Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/git/vole.git

Write over SSH with a registered key:

git clone ssh://git@0.0.0.0:2222/vole.git

A free and open-source forge that lives in your Git repo.

Let a job start service containers beside it

c1929d2fceb5e9e65204d5eef907d0781b9a5391 · Keenan Nemetz · 5d ago · parent 1d06b008

ci/workflow_test.go +71

@@ -767,3 +767,74 @@ func TestSecretNamesAreEnvironmentVariableNames(t *testing.T) {
767 767 t.Fatal("the runner's own variables are not distinguished")
768 768 }
769 769 }
770
771 func TestServicesParseInNameOrder(t *testing.T) {
772 t.Parallel()
773 wf, problems := Parse(".vole/workflows/x.yaml", `version: 1
774 jobs:
775 test:
776 image: golang:1.27-bookworm
777 network: bridge
778 services:
779 cache:
780 image: redis:8
781 db:
782 image: postgres:17
783 env:
784 POSTGRES_PASSWORD: test
785 PGDATA: /tmp/pgdata
786 steps:
787 - run: go test ./...
788 `)
789 if len(problems) > 0 {
790 t.Fatalf("rejected: %v", problems)
791 }
792 svcs := wf.Jobs[0].Services
793 if len(svcs) != 2 || svcs[0].ID != "cache" || svcs[1].ID != "db" {
794 t.Fatalf("services = %+v, want cache then db", svcs)
795 }
796 if svcs[1].Image != "postgres:17" || svcs[1].Env["PGDATA"] != "/tmp/pgdata" {
797 t.Fatalf("db = %+v", svcs[1])
798 }
799 }
800
801 func TestServiceProblemsAreRefused(t *testing.T) {
802 t.Parallel()
803 base := `version: 1
804 jobs:
805 test:
806 image: golang:1.27-bookworm
807 network: bridge
808 services:
809 db:
810 image: postgres:17
811 steps:
812 - run: echo hi
813 `
814 cases := []struct {
815 name string
816 src string
817 want string
818 }{
819 {"no network", strings.Replace(base, " network: bridge\n", "", 1), "need network: bridge"},
820 {"network none", strings.Replace(base, "network: bridge", "network: none", 1), "need network: bridge"},
821 {"no image", strings.Replace(base, " image: postgres:17\n", "", 1), "image is required"},
822 {"image file", strings.Replace(base, "image: postgres:17", "image: file:db", 1), "reserved for image-file"},
823 {"bad name", strings.Replace(base, " db:", " DB:", 1), "service name is"},
824 {"bad env name", strings.Replace(base, " steps:", " env:\n BAD NAME: x\n steps:", 1), "not a variable name"},
825 {"multiline env", strings.Replace(base, " steps:", " env:\n X: \"one\\ntwo\"\n steps:", 1), "one line"},
826 {"unknown key", strings.Replace(base, " image: postgres:17", " image: postgres:17\n ports: [5432]", 1), "not a known key"},
827 }
828 for _, tc := range cases {
829 t.Run(tc.name, func(t *testing.T) {
830 _, problems := Parse(".vole/workflows/x.yaml", tc.src)
831 if len(problems) == 0 {
832 t.Fatalf("accepted invalid services:\n%s", tc.src)
833 }
834 joined := strings.Join(problems, "\n")
835 if !strings.Contains(joined, tc.want) {
836 t.Fatalf("problems do not mention %q:\n%s", tc.want, joined)
837 }
838 })
839 }
840 }