From b4d86de3b67a7bf3a1829be74c50a23cf9d131b4 Mon Sep 17 00:00:00 2001 From: Juan Antonio Osorio Date: Tue, 21 Nov 2023 11:06:59 +0200 Subject: [PATCH 1/3] Add goreleaser configuration and release workflow This adds a configuration taken from the github.com/stacklok/minder repo and uses it to release the frizbee binary. --- .github/workflows/releaser.yml | 134 +++++++++++++++++++++++++++++++++ .goreleaser.yaml | 107 ++++++++++++++++++++++++++ 2 files changed, 241 insertions(+) create mode 100644 .github/workflows/releaser.yml create mode 100644 .goreleaser.yaml diff --git a/.github/workflows/releaser.yml b/.github/workflows/releaser.yml new file mode 100644 index 0000000..e883bb4 --- /dev/null +++ b/.github/workflows/releaser.yml @@ -0,0 +1,134 @@ +# +# Copyright 2023 Stacklok, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# This workflow compiles frizbee using a SLSA3 compliant +# build and then verifies the provenance of the built artifacts. +# It releases the following architectures: amd64, arm64, and armv7 on Linux, +# Windows, and macOS. +# The provenance file can be verified using https://github.com/slsa-framework/slsa-verifier. +# For more information about SLSA and how it improves the supply-chain, visit slsa.dev. + +name: Release +on: + push: + tags: + - '*' + +permissions: + contents: write + +jobs: + release: + name: Build and release + outputs: + hashes: ${{ steps.hash.outputs.hashes }} + permissions: + contents: write # To add assets to a release. + id-token: write # To do keyless signing with cosign + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Go + uses: actions/setup-go@v4 + with: + go-version-file: 'go.mod' + cache: true + + - name: Install Syft + uses: anchore/sbom-action/download-syft@78fc58e266e87a38d4194b2137a3d4e9bcaf7ca1 # v0.14.3 + + - name: Install Cosign + uses: sigstore/cosign-installer@v3.2.0 + + - name: Run GoReleaser + id: run-goreleaser + uses: goreleaser/goreleaser-action@v5 + with: + distribution: goreleaser + version: latest + args: release --clean + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }} + WINGET_GITHUB_TOKEN: ${{ secrets.WINGET_GITHUB_TOKEN }} + + - name: Generate subject + id: hash + env: + ARTIFACTS: "${{ steps.run-goreleaser.outputs.artifacts }}" + run: | + set -euo pipefail + hashes=$(echo $ARTIFACTS | jq --raw-output '.[] | {name, "digest": (.extra.Digest // .extra.Checksum)} | select(.digest) | {digest} + {name} | join(" ") | sub("^sha256:";"")' | base64 -w0) + if test "$hashes" = ""; then # goreleaser < v1.13.0 + checksum_file=$(echo "$ARTIFACTS" | jq -r '.[] | select (.type=="Checksum") | .path') + hashes=$(cat $checksum_file | base64 -w0) + fi + echo "hashes=$hashes" >> $GITHUB_OUTPUT + + provenance: + name: Generate provenance (SLSA3) + needs: + - release + permissions: + actions: read # To read the workflow path. + id-token: write # To sign the provenance. + contents: write # To add assets to a release. + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.9.0 + with: + base64-subjects: "${{ needs.release.outputs.hashes }}" + upload-assets: true # upload to a new release + verification: + name: Verify provenance of assets (SLSA3) + needs: + - release + - provenance + runs-on: ubuntu-latest + permissions: read-all + steps: + - name: Install the SLSA verifier + uses: slsa-framework/slsa-verifier/actions/installer@v2.4.1 + - name: Download assets + env: + GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" + CHECKSUMS: "${{ needs.release.outputs.hashes }}" + ATT_FILE_NAME: "${{ needs.provenance.outputs.provenance-name }}" + run: | + set -euo pipefail + checksums=$(echo "$CHECKSUMS" | base64 -d) + while read -r line; do + fn=$(echo $line | cut -d ' ' -f2) + echo "Downloading $fn" + gh -R "$GITHUB_REPOSITORY" release download "$GITHUB_REF_NAME" -p "$fn" + done <<<"$checksums" + gh -R "$GITHUB_REPOSITORY" release download "$GITHUB_REF_NAME" -p "$ATT_FILE_NAME" + - name: Verify assets + env: + CHECKSUMS: "${{ needs.release.outputs.hashes }}" + PROVENANCE: "${{ needs.provenance.outputs.provenance-name }}" + run: | + set -euo pipefail + checksums=$(echo "$CHECKSUMS" | base64 -d) + while read -r line; do + fn=$(echo $line | cut -d ' ' -f2) + echo "Verifying SLSA provenance for $fn" + slsa-verifier verify-artifact --provenance-path "$PROVENANCE" \ + --source-uri "github.com/$GITHUB_REPOSITORY" \ + --source-tag "$GITHUB_REF_NAME" \ + "$fn" + done <<<"$checksums" diff --git a/.goreleaser.yaml b/.goreleaser.yaml new file mode 100644 index 0000000..88983cd --- /dev/null +++ b/.goreleaser.yaml @@ -0,0 +1,107 @@ +# yaml-language-server: $schema=https://goreleaser.com/static/schema.json +# vim: set ts=2 sw=2 tw=0 fo=cnqoj +project_name: frizbee +# This section defines the build matrix. +builds: + - env: + - GO111MODULE=on + - CGO_ENABLED=0 + flags: + - -trimpath + - -tags=netgo + # TODO: Add ldflags + # ldflags: + # - "-X main.Version={{ .Env.VERSION }}" + # - "-X main.Commit={{ .Env.COMMIT }}" + # - "-X main.CommitDate={{ .Env.COMMIT_DATE }}" + # - "-X main.TreeState={{ .Env.TREE_STATE }}" + goos: + - linux + - windows + - darwin + goarch: + - amd64 + - arm64 + main: ./main.go +# This section defines the release format. +archives: + - format: tar.gz # we can use binary, but it seems there's an issue where goreleaser skips the sboms + name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}" + format_overrides: + - goos: windows + format: zip +# This section defines how to release to homebrew. +brews: + - homepage: 'https://github.com/stacklok/frizbee' + description: 'frizbee is a tool you may throw a tag at and it comes back with a checksum.' + folder: Formula + commit_author: + name: stacklokbot + email: info@stacklok.com + repository: + owner: stacklok + name: homebrew-tap + token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}" + test: | + system "#{bin}/frizbee --help" +# This section defines how to release to winget. +winget: + - name: frizbee + publisher: stacklok + license: Apache-2.0 + license_url: "https://github.com/stacklok/frizbee/blob/main/LICENSE" + copyright: Stacklok, Inc. + homepage: https://stacklok.com + short_description: 'frizbee is a tool you may throw a tag at and it comes back with a checksum.' + publisher_support_url: "https://github.com/stacklok/frizbee/issues/new/choose" + package_identifier: "stacklok.frizbee" + url_template: "https://github.com/stacklok/frizbee/releases/download/{{ .Tag }}/{{ .ArtifactName }}" + skip_upload: auto + release_notes: "{{.Changelog}}" + tags: + - golang + - cli + commit_author: + name: stacklokbot + email: info@stacklok.com + goamd64: v1 + repository: + owner: stacklok + name: winget-pkgs + branch: "frizbee-{{.Version}}" + token: "{{ .Env.WINGET_GITHUB_TOKEN }}" + pull_request: + enabled: true + draft: false + base: + owner: microsoft + name: winget-pkgs + branch: master +# This section defines whether we want to release the source code too. +source: + enabled: true +# This section defines how to generate the changelog +changelog: + sort: asc + use: github +# This section defines for which artifact types to generate SBOMs. +sboms: + - artifacts: archive +# This section defines the release policy. +release: + # If set to auto, will mark the release as not ready for production + # in case there is an indicator for this in the tag e.g. v1.0.0-rc1 + prerelease: auto + github: + owner: stacklok + name: frizbee +# This section defines how and which artifacts we want to sign for the release. +signs: + - cmd: cosign + args: + - "sign-blob" + - "--output-signature=${signature}" + - "${artifact}" + - "--yes" # needed on cosign 2.0.0+ + artifacts: archive + output: true From a87e3f266bcab98204d3dfc9dda0ddb84d01e87f Mon Sep 17 00:00:00 2001 From: Juan Antonio Osorio Date: Tue, 21 Nov 2023 11:16:01 +0200 Subject: [PATCH 2/3] Use frizbee to fix releaser job --- .github/workflows/releaser.yml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/releaser.yml b/.github/workflows/releaser.yml index e883bb4..50b1a05 100644 --- a/.github/workflows/releaser.yml +++ b/.github/workflows/releaser.yml @@ -40,12 +40,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 with: fetch-depth: 0 - name: Setup Go - uses: actions/setup-go@v4 + uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4 with: go-version-file: 'go.mod' cache: true @@ -54,11 +54,11 @@ jobs: uses: anchore/sbom-action/download-syft@78fc58e266e87a38d4194b2137a3d4e9bcaf7ca1 # v0.14.3 - name: Install Cosign - uses: sigstore/cosign-installer@v3.2.0 + uses: sigstore/cosign-installer@1fc5bd396d372bee37d608f955b336615edf79c8 # v3.2.0 - name: Run GoReleaser id: run-goreleaser - uses: goreleaser/goreleaser-action@v5 + uses: goreleaser/goreleaser-action@7ec5c2b0c6cdda6e8bbb49444bc797dd33d74dd8 # v5 with: distribution: goreleaser version: latest @@ -89,10 +89,11 @@ jobs: actions: read # To read the workflow path. id-token: write # To sign the provenance. contents: write # To add assets to a release. - uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.9.0 + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@07e64b653f10a80b6510f4568f685f8b7b9ea830 # v1.9.0 with: base64-subjects: "${{ needs.release.outputs.hashes }}" upload-assets: true # upload to a new release + verification: name: Verify provenance of assets (SLSA3) needs: @@ -102,7 +103,7 @@ jobs: permissions: read-all steps: - name: Install the SLSA verifier - uses: slsa-framework/slsa-verifier/actions/installer@v2.4.1 + uses: slsa-framework/slsa-verifier/actions/installer@7e1e47d7d793930ab0082c15c2b971fdb53a3c95 # v2.4.1 - name: Download assets env: GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" From a45854186274b824027542f1fb75e36a9deb7022 Mon Sep 17 00:00:00 2001 From: Juan Antonio Osorio Date: Tue, 21 Nov 2023 11:17:19 +0200 Subject: [PATCH 3/3] Remove prerelease flag from goreleaser --- .goreleaser.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 88983cd..62e1843 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -89,9 +89,6 @@ sboms: - artifacts: archive # This section defines the release policy. release: - # If set to auto, will mark the release as not ready for production - # in case there is an indicator for this in the tag e.g. v1.0.0-rc1 - prerelease: auto github: owner: stacklok name: frizbee