summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGusted <gusted@noreply.codeberg.org>2025-01-03 01:22:33 +0100
committerGusted <gusted@noreply.codeberg.org>2025-01-03 01:22:33 +0100
commitcfb18e2b6cfbe92995bf890e1c368928f4078514 (patch)
tree407990d192f39e7a18e35fa9f3e77ba156bd6f1e
parentMerge pull request 'chore: bump renovate to v39.90.0' (#6453) from viceice/ch... (diff)
parentadd release notes (diff)
downloadforgejo-cfb18e2b6cfbe92995bf890e1c368928f4078514.tar.xz
forgejo-cfb18e2b6cfbe92995bf890e1c368928f4078514.zip
Merge pull request 'feat(webhook): sourcehut: submit SSH URL for private repository (or when pre-filled)' (#6445) from oliverpool/forgejo:sourcehut-refactor into forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6445 Reviewed-by: Gusted <gusted@noreply.codeberg.org>
-rw-r--r--release-notes/6445.md1
-rw-r--r--services/webhook/sourcehut/builds.go26
-rw-r--r--services/webhook/sourcehut/builds_test.go132
3 files changed, 151 insertions, 8 deletions
diff --git a/release-notes/6445.md b/release-notes/6445.md
new file mode 100644
index 0000000000..d3755701b2
--- /dev/null
+++ b/release-notes/6445.md
@@ -0,0 +1 @@
+feat: webhook: sourcehut: submit SSH URL for private repository or when pre-filled
diff --git a/services/webhook/sourcehut/builds.go b/services/webhook/sourcehut/builds.go
index 5a34503a7d..346ccd3c0b 100644
--- a/services/webhook/sourcehut/builds.go
+++ b/services/webhook/sourcehut/builds.go
@@ -8,6 +8,7 @@ import (
"context"
"fmt"
"html/template"
+ "io"
"io/fs"
"net/http"
"strings"
@@ -189,11 +190,11 @@ func (pc sourcehutConvertor) Package(_ *api.PackagePayload) (graphqlPayload[buil
return graphqlPayload[buildsVariables]{}, shared.ErrPayloadTypeNotSupported
}
-// mustBuildManifest adjusts the manifest to submit to the builds service
+// newPayload opens and adjusts the manifest to submit to the builds service
//
// in case of an error the Error field will be set, to be visible by the end-user under recent deliveries
func (pc sourcehutConvertor) newPayload(repo *api.Repository, commitID, ref, note string, trusted bool) (graphqlPayload[buildsVariables], error) {
- manifest, err := pc.buildManifest(repo, commitID, ref)
+ manifest, err := pc.constructManifest(repo, commitID, ref)
if err != nil {
if len(manifest) == 0 {
return graphqlPayload[buildsVariables]{}, err
@@ -238,9 +239,9 @@ func (pc sourcehutConvertor) newPayload(repo *api.Repository, commitID, ref, not
}, nil
}
-// buildManifest adjusts the manifest to submit to the builds service
+// constructManifest opens and adjusts the manifest to submit to the builds service
// in case of an error the []byte might contain an error that can be displayed to the user
-func (pc sourcehutConvertor) buildManifest(repo *api.Repository, commitID, gitRef string) ([]byte, error) {
+func (pc sourcehutConvertor) constructManifest(repo *api.Repository, commitID, gitRef string) ([]byte, error) {
gitRepo, err := gitrepo.OpenRepository(pc.ctx, repo)
if err != nil {
msg := "could not open repository"
@@ -265,6 +266,10 @@ func (pc sourcehutConvertor) buildManifest(repo *api.Repository, commitID, gitRe
}
defer r.Close()
+ return adjustManifest(repo, commitID, gitRef, r, pc.meta.ManifestPath)
+}
+
+func adjustManifest(repo *api.Repository, commitID, gitRef string, r io.Reader, path string) ([]byte, error) {
// reference: https://man.sr.ht/builds.sr.ht/manifest.md
var manifest struct {
Sources []string `yaml:"sources"`
@@ -273,7 +278,7 @@ func (pc sourcehutConvertor) buildManifest(repo *api.Repository, commitID, gitRe
Rest map[string]yaml.Node `yaml:",inline"`
}
if err := yaml.NewDecoder(r).Decode(&manifest); err != nil {
- msg := fmt.Sprintf("could not decode manifest %q", pc.meta.ManifestPath)
+ msg := fmt.Sprintf("could not decode manifest %q", path)
return []byte(msg), fmt.Errorf(msg+": %w", err)
}
@@ -284,16 +289,21 @@ func (pc sourcehutConvertor) buildManifest(repo *api.Repository, commitID, gitRe
manifest.Environment["BUILD_SUBMITTER_URL"] = setting.AppURL
manifest.Environment["GIT_REF"] = gitRef
- source := repo.CloneURL + "#" + commitID
found := false
for i, s := range manifest.Sources {
- if s == repo.CloneURL {
- manifest.Sources[i] = source
+ if s == repo.CloneURL || s == repo.SSHURL {
+ manifest.Sources[i] = s + "#" + commitID
found = true
break
}
}
if !found {
+ source := repo.CloneURL
+ if repo.Private || setting.Repository.DisableHTTPGit {
+ // default to ssh for private repos or when git clone is disabled over http
+ source = repo.SSHURL
+ }
+ source += "#" + commitID
manifest.Sources = append(manifest.Sources, source)
}
diff --git a/services/webhook/sourcehut/builds_test.go b/services/webhook/sourcehut/builds_test.go
index 1a37279c99..5b16f08c09 100644
--- a/services/webhook/sourcehut/builds_test.go
+++ b/services/webhook/sourcehut/builds_test.go
@@ -5,6 +5,7 @@ package sourcehut
import (
"context"
+ "strings"
"testing"
webhook_model "code.gitea.io/gitea/models/webhook"
@@ -384,3 +385,134 @@ func TestSourcehutJSONPayload(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, "json test", body.Variables.Note)
}
+
+func TestSourcehutAdjustManifest(t *testing.T) {
+ defer test.MockVariableValue(&setting.AppURL, "https://example.forgejo.org/")()
+ t.Run("without sources", func(t *testing.T) {
+ repo := &api.Repository{
+ CloneURL: "http://localhost:3000/testdata/repo.git",
+ }
+
+ manifest, err := adjustManifest(repo, "58771003157b81abc6bf41df0c5db4147a3e3c83", "refs/heads/main", strings.NewReader(`image: alpine/edge
+tasks:
+ - say-hello: |
+ echo hello
+ - say-world: echo world`), ".build.yml")
+
+ require.NoError(t, err)
+ assert.Equal(t, `sources:
+ - http://localhost:3000/testdata/repo.git#58771003157b81abc6bf41df0c5db4147a3e3c83
+environment:
+ BUILD_SUBMITTER: forgejo
+ BUILD_SUBMITTER_URL: https://example.forgejo.org/
+ GIT_REF: refs/heads/main
+image: alpine/edge
+tasks:
+ - say-hello: |
+ echo hello
+ - say-world: echo world
+`, string(manifest))
+ })
+
+ t.Run("with other sources", func(t *testing.T) {
+ repo := &api.Repository{
+ CloneURL: "http://localhost:3000/testdata/repo.git",
+ }
+
+ manifest, err := adjustManifest(repo, "58771003157b81abc6bf41df0c5db4147a3e3c83", "refs/heads/main", strings.NewReader(`image: alpine/edge
+sources:
+- http://other.example.conm/repo.git
+tasks:
+ - hello: echo world`), ".build.yml")
+
+ require.NoError(t, err)
+ assert.Equal(t, `sources:
+ - http://other.example.conm/repo.git
+ - http://localhost:3000/testdata/repo.git#58771003157b81abc6bf41df0c5db4147a3e3c83
+environment:
+ BUILD_SUBMITTER: forgejo
+ BUILD_SUBMITTER_URL: https://example.forgejo.org/
+ GIT_REF: refs/heads/main
+image: alpine/edge
+tasks:
+ - hello: echo world
+`, string(manifest))
+ })
+
+ t.Run("with same source", func(t *testing.T) {
+ repo := &api.Repository{
+ CloneURL: "http://localhost:3000/testdata/repo.git",
+ }
+
+ manifest, err := adjustManifest(repo, "58771003157b81abc6bf41df0c5db4147a3e3c83", "refs/heads/main", strings.NewReader(`image: alpine/edge
+sources:
+- http://localhost:3000/testdata/repo.git
+- http://other.example.conm/repo.git
+tasks:
+ - hello: echo world`), ".build.yml")
+
+ require.NoError(t, err)
+ assert.Equal(t, `sources:
+ - http://localhost:3000/testdata/repo.git#58771003157b81abc6bf41df0c5db4147a3e3c83
+ - http://other.example.conm/repo.git
+environment:
+ BUILD_SUBMITTER: forgejo
+ BUILD_SUBMITTER_URL: https://example.forgejo.org/
+ GIT_REF: refs/heads/main
+image: alpine/edge
+tasks:
+ - hello: echo world
+`, string(manifest))
+ })
+
+ t.Run("with ssh source", func(t *testing.T) {
+ repo := &api.Repository{
+ CloneURL: "http://localhost:3000/testdata/repo.git",
+ SSHURL: "git@localhost:testdata/repo.git",
+ }
+
+ manifest, err := adjustManifest(repo, "58771003157b81abc6bf41df0c5db4147a3e3c83", "refs/heads/main", strings.NewReader(`image: alpine/edge
+sources:
+- git@localhost:testdata/repo.git
+- http://other.example.conm/repo.git
+tasks:
+ - hello: echo world`), ".build.yml")
+
+ require.NoError(t, err)
+ assert.Equal(t, `sources:
+ - git@localhost:testdata/repo.git#58771003157b81abc6bf41df0c5db4147a3e3c83
+ - http://other.example.conm/repo.git
+environment:
+ BUILD_SUBMITTER: forgejo
+ BUILD_SUBMITTER_URL: https://example.forgejo.org/
+ GIT_REF: refs/heads/main
+image: alpine/edge
+tasks:
+ - hello: echo world
+`, string(manifest))
+ })
+
+ t.Run("private without source", func(t *testing.T) {
+ repo := &api.Repository{
+ CloneURL: "http://localhost:3000/testdata/repo.git",
+ SSHURL: "git@localhost:testdata/repo.git",
+ Private: true,
+ }
+
+ manifest, err := adjustManifest(repo, "58771003157b81abc6bf41df0c5db4147a3e3c83", "refs/heads/main", strings.NewReader(`image: alpine/edge
+tasks:
+ - hello: echo world`), ".build.yml")
+
+ require.NoError(t, err)
+ assert.Equal(t, `sources:
+ - git@localhost:testdata/repo.git#58771003157b81abc6bf41df0c5db4147a3e3c83
+environment:
+ BUILD_SUBMITTER: forgejo
+ BUILD_SUBMITTER_URL: https://example.forgejo.org/
+ GIT_REF: refs/heads/main
+image: alpine/edge
+tasks:
+ - hello: echo world
+`, string(manifest))
+ })
+}