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