e2e/cipaths_test.go
120 lines · 5313 bytes
1package e2e
2
3import (
4 "os"
5 "path/filepath"
6 "strings"
7 "testing"
8)
9
10// A job with paths only builds when the push touched something it names.
11// A doc-only push queues nothing; a push touching the named path queues
12// the job, same as before path filters existed.
13func TestCIPaths(t *testing.T) {
14 inst := startInstance(t)
15 aliceKey := inst.newKey(t, "alice")
16 inst.admin(t, "admin", "user", "create", "alice", "--key", aliceKey+".pub")
17
18 if _, errOut, code := inst.ssh(t, aliceKey, "", "repo", "create", "alice/app"); code != 0 {
19 t.Fatalf("repo create: %s", errOut)
20 }
21 work := t.TempDir()
22 env := inst.gitEnv(aliceKey)
23 mustGit(t, work, env, "clone", inst.sshURL("alice/app"), "w")
24 dir := filepath.Join(work, "w")
25 os.MkdirAll(filepath.Join(dir, ".gitbay"), 0o755)
26 os.MkdirAll(filepath.Join(dir, "src"), 0o755)
27 os.MkdirAll(filepath.Join(dir, "docs"), 0o755)
28 os.WriteFile(filepath.Join(dir, ".gitbay", "ci.yml"), []byte(
29 "jobs:\n unit:\n paths:\n - src/**\n steps:\n - echo fine\n"), 0o644)
30 os.WriteFile(filepath.Join(dir, "src", "x.go"), []byte("package x\n"), 0o644)
31 os.WriteFile(filepath.Join(dir, "docs", "x.md"), []byte("# x\n"), 0o644)
32 mustGit(t, dir, env, "checkout", "-q", "-b", "main")
33 mustGit(t, dir, env, "add", ".")
34 mustGit(t, dir, env, "commit", "-q", "-m", "base")
35 mustGit(t, dir, env, "push", "-q", "origin", "main")
36 // A new branch has no diff base, so the filter fails open: the base
37 // push above already queued build 1.
38 before := strings.Count(inst.buildList(t, aliceKey), "\n")
39 if before != 1 {
40 t.Fatalf("base push did not queue exactly one build:\n%s", inst.buildList(t, aliceKey))
41 }
42
43 // A push touching only docs does not match src/**: no build queued.
44 os.WriteFile(filepath.Join(dir, "docs", "x.md"), []byte("# x changed\n"), 0o644)
45 mustGit(t, dir, env, "add", ".")
46 mustGit(t, dir, env, "commit", "-q", "-m", "docs only")
47 mustGit(t, dir, env, "push", "-q", "origin", "main")
48 if out := inst.buildList(t, aliceKey); strings.Count(out, "\n") != before {
49 t.Fatalf("doc-only push queued a build:\n%s", out)
50 }
51
52 // A push touching src matches: a build is queued.
53 os.WriteFile(filepath.Join(dir, "src", "x.go"), []byte("package x\n\nvar y int\n"), 0o644)
54 mustGit(t, dir, env, "add", ".")
55 mustGit(t, dir, env, "commit", "-q", "-m", "src change")
56 mustGit(t, dir, env, "push", "-q", "origin", "main")
57 out := inst.buildList(t, aliceKey)
58 if strings.Count(out, "\n") != before+1 {
59 t.Fatalf("src push did not queue a build:\n%s", out)
60 }
61 if !strings.Contains(out, "unit\tpending") {
62 t.Fatalf("src push did not queue the unit job:\n%s", out)
63 }
64}
65
66// A branch's first push has no old sha, but path filters must still
67// apply: the normal workflow here is branch, commit, open an MR, and
68// that first push is always a new branch. Without a merge-base fallback,
69// a docs-only branch queues the full suite anyway (#171).
70func TestCIPathsNewBranch(t *testing.T) {
71 inst := startInstance(t)
72 aliceKey := inst.newKey(t, "alice")
73 inst.admin(t, "admin", "user", "create", "alice", "--key", aliceKey+".pub")
74
75 if _, errOut, code := inst.ssh(t, aliceKey, "", "repo", "create", "alice/app"); code != 0 {
76 t.Fatalf("repo create: %s", errOut)
77 }
78 work := t.TempDir()
79 env := inst.gitEnv(aliceKey)
80 mustGit(t, work, env, "clone", inst.sshURL("alice/app"), "w")
81 dir := filepath.Join(work, "w")
82 os.MkdirAll(filepath.Join(dir, ".gitbay"), 0o755)
83 os.MkdirAll(filepath.Join(dir, "src"), 0o755)
84 os.MkdirAll(filepath.Join(dir, "docs"), 0o755)
85 os.WriteFile(filepath.Join(dir, ".gitbay", "ci.yml"), []byte(
86 "jobs:\n unit:\n paths-ignore:\n - docs/**\n steps:\n - echo fine\n"), 0o644)
87 os.WriteFile(filepath.Join(dir, "src", "x.go"), []byte("package x\n"), 0o644)
88 os.WriteFile(filepath.Join(dir, "docs", "x.md"), []byte("# x\n"), 0o644)
89 mustGit(t, dir, env, "checkout", "-q", "-b", "main")
90 mustGit(t, dir, env, "add", ".")
91 mustGit(t, dir, env, "commit", "-q", "-m", "base")
92 mustGit(t, dir, env, "push", "-q", "origin", "main")
93 before := strings.Count(inst.buildList(t, aliceKey), "\n")
94
95 // A brand-new branch whose only commit touches an ignored path: the
96 // filter must apply on this, its first push, not just on later ones.
97 mustGit(t, dir, env, "checkout", "-q", "-b", "docs-branch")
98 os.WriteFile(filepath.Join(dir, "docs", "x.md"), []byte("# x changed\n"), 0o644)
99 mustGit(t, dir, env, "add", ".")
100 mustGit(t, dir, env, "commit", "-q", "-m", "docs only")
101 mustGit(t, dir, env, "push", "-q", "origin", "docs-branch")
102 if out := inst.buildList(t, aliceKey); strings.Count(out, "\n") != before {
103 t.Fatalf("new branch's docs-only push queued a build:\n%s", out)
104 }
105
106 // A brand-new branch touching a matched path still queues, on its
107 // first push.
108 mustGit(t, dir, env, "checkout", "-q", "-b", "src-branch")
109 os.WriteFile(filepath.Join(dir, "src", "x.go"), []byte("package x\n\nvar y int\n"), 0o644)
110 mustGit(t, dir, env, "add", ".")
111 mustGit(t, dir, env, "commit", "-q", "-m", "src change")
112 mustGit(t, dir, env, "push", "-q", "origin", "src-branch")
113 out := inst.buildList(t, aliceKey)
114 if strings.Count(out, "\n") != before+1 {
115 t.Fatalf("new branch's src push did not queue a build:\n%s", out)
116 }
117 if !strings.Contains(out, "unit\tpending") {
118 t.Fatalf("new branch's src push did not queue the unit job:\n%s", out)
119 }
120}