Diff
1diff --git a/http.go b/http.go
2index 8f71ca0fbc38ace2dca02c41dc64bb47f072b4b3..312a62e71fc1c99b2985757856980895d6df97eb 100644
3--- a/http.go
4+++ b/http.go
5@@ -19,11 +19,15 @@ const (
6 maxStatusRepositories = 100
7 )
8
9-var commitSHA = regexp.MustCompile(`^[0-9a-f]{40}([0-9a-f]{24})?$`)
10+var (
11+ commitSHA = regexp.MustCompile(`^[0-9a-f]{40}([0-9a-f]{24})?$`)
12+ dockerTag = regexp.MustCompile(`^[A-Za-z0-9_][A-Za-z0-9_.-]{0,127}$`)
13+)
14
15 type buildRequest struct {
16 Repository string `json:"repository"`
17 SHA string `json:"sha"`
18+ Ref string `json:"ref"`
19 }
20
21 type buildStatus struct {
22@@ -122,6 +126,11 @@ func buildHandler(jobs chan<- buildJob, statuses *buildStatuses) http.HandlerFun
23 http.Error(writer, "invalid build request", http.StatusBadRequest)
24 return
25 }
26+ if !isBuildRef(buildRequest.Ref) {
27+ slog.Info("build ignored", "repository", buildRequest.Repository, "sha", buildRequest.SHA, "ref", buildRequest.Ref)
28+ writer.WriteHeader(http.StatusNoContent)
29+ return
30+ }
31
32 job, err := newBuildJob(buildRequest)
33 if err != nil {
34@@ -172,7 +181,18 @@ func buildStatusHandler(statuses *buildStatuses) http.HandlerFunc {
35 }
36
37 func validBuildRequest(request buildRequest) bool {
38- return validRepository(request.Repository) && commitSHA.MatchString(request.SHA)
39+ return validRepository(request.Repository) && commitSHA.MatchString(request.SHA) && validBuildRef(request.Ref)
40+}
41+
42+func validBuildRef(ref string) bool {
43+ if strings.HasPrefix(ref, "refs/heads/") {
44+ return strings.TrimPrefix(ref, "refs/heads/") != ""
45+ }
46+ return strings.HasPrefix(ref, "refs/tags/") && dockerTag.MatchString(strings.TrimPrefix(ref, "refs/tags/"))
47+}
48+
49+func isBuildRef(ref string) bool {
50+ return ref == "refs/heads/main" || strings.HasPrefix(ref, "refs/tags/")
51 }
52
53 func validBuildStatusRequest(request buildStatusRequest) bool {
54diff --git a/worker.go b/worker.go
55index 776bc588c04eec87bc5c0a7521a1dc2ebfb4ccab..9b69771baf6e0f342862863cf46e77353776008a 100644
56--- a/worker.go
57+++ b/worker.go
58@@ -74,7 +74,7 @@ func build(ctx context.Context, config config, request buildRequest) error {
59 }
60
61 image := imageName(config.registry, request.Repository)
62- output := fmt.Sprintf("type=image,\"name=%s:%s,%s:main\",push=true", image, request.SHA, image)
63+ output := fmt.Sprintf("type=image,\"name=%s\",push=true", strings.Join(imageTags(image, request), ","))
64 if err := run(
65 ctx,
66 "buildctl", "--addr", config.buildkitAddress,
67@@ -118,6 +118,14 @@ func imageName(registry, repository string) string {
68 return registry + "/" + filepath.Base(repository)
69 }
70
71+func imageTags(image string, request buildRequest) []string {
72+ tags := []string{image + ":" + request.SHA}
73+ if request.Ref == "refs/heads/main" {
74+ return append(tags, image+":main")
75+ }
76+ return append(tags, image+":"+strings.TrimPrefix(request.Ref, "refs/tags/"))
77+}
78+
79 func run(ctx context.Context, name string, arguments ...string) error {
80 output, err := exec.CommandContext(ctx, name, arguments...).CombinedOutput()
81 if err == nil {