Skip to content

badges

badges #9

Workflow file for this run

# Build the app with ko and push image incl. provenance, sbom, everything signed
name: Release workflow
on:
push:
tags:
- "*"
env:
KO_DOCKER_REPO: "ghcr.io/${{ github.repository}}"
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
outputs:
image: ${{ steps.build.outputs.image }}
digest: ${{ steps.build.outputs.digest }}
steps:
- name: checkout repo
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 #v3.5.3
- uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 #v4.0.1
with:
go-version: '1.19'
# setup-ko could do KO_DOCKER_REPO and login for us, but I prefer to show it explicitly
- uses: ko-build/setup-ko@ace48d793556083a76f1e3e6068850c1f4a369aa #v0.6
with:
version: 'v0.14.1'
- name: Build and push with ko
id: build
if: startsWith(github.ref, 'refs/tags/') # just to be safe, don't push if it's not a tag
run: |
tag=$(echo ${{ github.ref }} | cut -d'/' -f3)
echo "${{ github.token }}" | ko login ghcr.io --username ${{ github.actor }} --password-stdin
# fetch go deps to local and generate ent files
go generate ./...
go mod tidy
# build the SPA UI so it can be embedded into the binary when `ko` builds
make fe-build
# Build & push the image. Save the image name.
# NOTICE the '--bare' flag, this uses the value of KO_DOCKER_REPO
# directly without adding anything to the end, which ko likes to do
# don't let ko upload the SBOM, we want to do it differently
image_and_digest=$(ko build --tags="${tag}" --bare --sbom=none .)
# Output the image name and digest so we can generate provenance.
digest=$(echo "${image_and_digest}" | cut -d'@' -f2)
echo "digest=$digest" >> "$GITHUB_OUTPUT"
# image is defined fully by the KO_DOCKER_REPO, so just use that
echo "image=$KO_DOCKER_REPO" >> "$GITHUB_OUTPUT"
sign-image:
runs-on: ubuntu-latest
needs: [build]
permissions:
packages: write
id-token: write
env:
image: ${{ needs.build.outputs.image }}
digest: ${{ needs.build.outputs.digest }}
steps:
- name: Install cosign
uses: sigstore/cosign-installer@6e04d228eb30da1757ee4e1dd75a0ec73a653e06 #v3.1.1
with:
cosign-release: v2.1.1
- name: Login to ghcr.io
uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc #v2.2.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Sign image
run: |
cosign sign "${image}@${digest}" --yes
sbom:
runs-on: ubuntu-latest
needs: [build]
permissions:
packages: write
id-token: write
env:
image: ${{ needs.build.outputs.image }}
digest: ${{ needs.build.outputs.digest }}
steps:
- name: checkout repo (verinotes)
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 #v3.5.3
- name: checkout repo of sbom-merge, compile during build
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 #v3.5.3
with:
repository: verifa/sbom-merge
path: sbom-merge
ref: e279f901130689f7576ff33ad65e34cb9767150b # v0.0.1
- name: Install cosign
uses: sigstore/cosign-installer@6e04d228eb30da1757ee4e1dd75a0ec73a653e06 #v3.1.1
with:
cosign-release: v2.1.1
- name: Install Syft
uses: anchore/sbom-action/download-syft@78fc58e266e87a38d4194b2137a3d4e9bcaf7ca1 #v0.14.3
- uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 #v4.0.1
with:
go-version: '1.19'
- name: Login to ghcr.io
uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc #v2.2.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Attach SBOM to image
run: |
# syft pull the image and analyses the contents to generate an SBOM
syft "${image}@${digest}" --output spdx-json --file sbom.spdx.json
# ui SBOM is generated explicitly since syft cannot find it inside Go binary
# this is an example why SBOM is good to create at build time, not afterwards
syft --output spdx-json file:./ui/package-lock.json --file sbom-ui.spdx.json
# use the experimental sbom-merge tool to merge the ui and container(+go backend) SBOMs
cd sbom-merge && go mod tidy && go build -o ../sbom-merge-tool && cd ..
ls -l
./sbom-merge-tool sbom.spdx.json sbom-ui.spdx.json > sbom-final.spdx.json
# attach merged sbom as attestation (signed)
cosign attest --predicate sbom-final.spdx.json --type spdxjson "${image}@${digest}" --yes
# slsa-github-generator creates and pushes the provenance attestation
provenance:
needs: [build]
permissions:
actions: read
id-token: write
# contents: read
packages: write
if: startsWith(github.ref, 'refs/tags/') # just to be safe, don't push if it's not a tag
uses: slsa-framework/slsa-github-generator/.github/workflows/[email protected]
with:
image: ${{ needs.build.outputs.image }}
digest: ${{ needs.build.outputs.digest }}
registry-username: ${{ github.actor }}
compile-generator: true
secrets:
registry-password: ${{ secrets.GITHUB_TOKEN }}