diff --git a/.github/workflows/releaser.yml b/.github/workflows/releaser.yml index f37db65..74da5b7 100644 --- a/.github/workflows/releaser.yml +++ b/.github/workflows/releaser.yml @@ -26,6 +26,10 @@ jobs: with: go-version-file: go.mod cache: false + - name: Install Syft for archive SBOMs + uses: anchore/sbom-action/download-syft@3ad7283483fc7af8ff2b4ea19663c2d5ca935e26 # v0.24.2 + with: + syft-version: v1.44.0 - name: Publish with this repository's workflow token uses: goreleaser/goreleaser-action@f06c13b6b1a9625abc9e6e439d9c05a8f2190e94 # v7.2.3 with: diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 4436ab3..fff82c9 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -1,5 +1,12 @@ version: 2 +sboms: + - id: archives + artifacts: archive + documents: + - "${artifact}.sbom.json" + disable: false + release: github: owner: codefly-dev diff --git a/agent.codefly.yaml b/agent.codefly.yaml index de310c7..5f6d85d 100644 --- a/agent.codefly.yaml +++ b/agent.codefly.yaml @@ -2,3 +2,6 @@ publisher: codefly.dev kind: codefly:service name: mssql version: 0.0.18 +release: + owner: workflow + workflow: releaser.yml diff --git a/go.mod b/go.mod index 1488da3..e0f4f8c 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/microsoft/go-mssqldb v1.10.0 github.com/stretchr/testify v1.12.1 google.golang.org/grpc v1.83.2 + gopkg.in/yaml.v3 v3.0.1 ) require ( @@ -116,7 +117,6 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20260825221802-da73d73af1c5 // indirect google.golang.org/protobuf v1.36.12 // indirect gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/kube-openapi v0.0.0-20260721132016-d427ff9ee9ad // indirect sigs.k8s.io/kustomize/api v0.21.1 // indirect sigs.k8s.io/kustomize/kyaml v0.21.1 // indirect diff --git a/release_test.go b/release_test.go new file mode 100644 index 0000000..d15f99c --- /dev/null +++ b/release_test.go @@ -0,0 +1,39 @@ +package main + +import ( + "os" + "testing" + + "gopkg.in/yaml.v3" +) + +func TestReleaseDeclaresOnePublisherAndArchiveSBOMs(t *testing.T) { + read := func(path string, target any) { + t.Helper() + payload, err := os.ReadFile(path) + if err != nil { + t.Fatal(err) + } + if err := yaml.Unmarshal(payload, target); err != nil { + t.Fatal(err) + } + } + var manifest struct { + Release struct{ Owner, Workflow string } + } + read("agent.codefly.yaml", &manifest) + if manifest.Release.Owner != "workflow" || manifest.Release.Workflow != "releaser.yml" { + t.Fatal("the tag workflow must be the sole artifact publisher") + } + var config struct { + SBOMs []struct { + Artifacts string + Documents []string + Disable bool + } `yaml:"sboms"` + } + read(".goreleaser.yaml", &config) + if len(config.SBOMs) != 1 || config.SBOMs[0].Artifacts != "archive" || config.SBOMs[0].Disable || len(config.SBOMs[0].Documents) != 1 || config.SBOMs[0].Documents[0] != "${artifact}.sbom.json" { + t.Fatal("each published archive must carry its canonical SBOM") + } +}