feat(ci): sign + SBOM + SLSA L3 provenance for images and tarballs #562
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build simple-container in branch | |
| # GitHub does not pass repository secrets to workflows triggered by fork | |
| # PRs (only same-repo branches), so the practical attack surface for the | |
| # rule below is limited to internal collaborators with push access. The | |
| # PR-validation job requires `secrets.SC_CONFIG` to decrypt the SC config | |
| # and run integration-style tests against shared infra. Splitting this | |
| # into a workflow_run-gated secret-using job is the proper fix and is | |
| # tracked separately; until then this is accepted defense-in-depth risk | |
| # for trusted contributors. | |
| # nosemgrep: gha-pull-request-uses-non-token-secret | |
| on: | |
| workflow_dispatch: | |
| pull_request: | |
| branches: | |
| - 'main' | |
| - 'staging' | |
| # Least-privilege root: every job inherits read-only unless it explicitly | |
| # grants more (CIS GHA 1.2). Only `finalize` actually needs `contents: write` | |
| # (sticky comment / notify), and it grants that itself further down. | |
| permissions: | |
| contents: read | |
| jobs: | |
| build-setup: | |
| name: Build Setup (clean, tools, schemas, lint, fmt) | |
| runs-on: blacksmith-8vcpu-ubuntu-2204 | |
| outputs: | |
| cicd-bot-telegram-token: ${{ steps.telegram-secrets.outputs.cicd-bot-telegram-token }} | |
| cicd-bot-telegram-chat-id: ${{ steps.telegram-secrets.outputs.cicd-bot-telegram-chat-id }} | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| persist-credentials: false | |
| - uses: fregante/setup-git-user@024bc0b8e177d7e77203b48dab6fb45666854b35 # v2.0.2 | |
| - name: Set up Go with Blacksmith caching | |
| uses: useblacksmith/setup-go@647ac649bd5b480f2a262e3e3e5f4d150ed452ad # v6.0.1 | |
| with: | |
| go-version: '1.25' | |
| - name: install sc tool | |
| uses: simple-container-com/actions/install-sc@main | |
| - name: install welder tool | |
| uses: simple-container-com/actions/install-welder@main | |
| - name: prepare secrets for build | |
| run: | | |
| cat << EOF > ./.sc/cfg.default.yaml | |
| ${{ secrets.SC_CONFIG }} | |
| EOF | |
| cat << EOF > ./.sc/cfg.test.yaml | |
| ${{ secrets.SC_CONFIG }} | |
| EOF | |
| sc secrets reveal | |
| - name: get openai key | |
| id: get-openai-key | |
| run: | | |
| echo "openai-key=$(sc stack secret-get -s dist openai-api-key 2>/dev/null || echo '')" >> $GITHUB_OUTPUT | |
| - name: prepare sc tool (rebuild) | |
| shell: bash | |
| env: | |
| OPENAI_API_KEY: ${{ steps.get-openai-key.outputs.openai-key }} | |
| SKIP_EMBEDDINGS: "true" | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: |- | |
| gh auth setup-git | |
| welder run rebuild | |
| - name: clean | |
| run: | | |
| mkdir -p dist | |
| rm -fR dist/* | |
| mkdir -p .sc/stacks/dist/bundle | |
| rm -fR .sc/stacks/dist/bundle/* | |
| mkdir -p docs/site | |
| rm -fR docs/site/* | |
| mkdir -p docs/schemas | |
| rm -fR docs/schemas/* | |
| - name: tools | |
| run: | | |
| cat tools.go | grep _ | awk -F'"' '{print $2}' | xargs -tI % go get % | |
| go mod download | |
| go generate -tags tools | |
| go mod tidy | |
| - name: generate-schemas | |
| run: | | |
| echo "Generating JSON Schema files for Simple Container resources..." | |
| go build -o bin/schema-gen ./cmd/schema-gen | |
| bin/schema-gen docs/schemas | |
| echo "Successfully generated JSON Schema files in docs/schemas/" | |
| - name: fmt | |
| run: | | |
| go mod tidy | |
| bin/gofumpt -l -w ./ | |
| bin/golangci-lint run --fix --timeout 3m -v | |
| - name: get telegram secrets | |
| id: telegram-secrets | |
| run: | | |
| echo "cicd-bot-telegram-token=$(./bin/sc stack secret-get -s dist cicd-bot-telegram-token)" >> $GITHUB_OUTPUT | |
| echo "cicd-bot-telegram-chat-id=$(./bin/sc stack secret-get -s dist cicd-bot-telegram-chat-id)" >> $GITHUB_OUTPUT | |
| - name: upload bin directory artifacts | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 | |
| with: | |
| name: bin-tools | |
| path: bin | |
| retention-days: 1 | |
| build-platforms: | |
| name: Build sc for ${{ matrix.os }}/${{ matrix.arch }} | |
| runs-on: blacksmith-8vcpu-ubuntu-2204 | |
| needs: build-setup | |
| strategy: | |
| matrix: | |
| include: | |
| - os: linux | |
| arch: amd64 | |
| - os: darwin | |
| arch: arm64 | |
| - os: darwin | |
| arch: amd64 | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| persist-credentials: false | |
| - name: Set up Go with Blacksmith caching | |
| uses: useblacksmith/setup-go@647ac649bd5b480f2a262e3e3e5f4d150ed452ad # v6.0.1 | |
| with: | |
| go-version: '1.25' | |
| - name: create build directories | |
| run: | | |
| mkdir -p dist | |
| mkdir -p .sc/stacks/dist/bundle | |
| - name: build sc for ${{ matrix.os }}/${{ matrix.arch }} | |
| env: | |
| GOOS: ${{ matrix.os }} | |
| GOARCH: ${{ matrix.arch }} | |
| CGO_ENABLED: "0" | |
| run: | | |
| echo "Building for ${GOOS}/${GOARCH}..." | |
| if [ "${GOOS}" = "windows" ]; then export EXT=".exe"; else export EXT=""; fi | |
| go build -ldflags "-s -w" -o dist/${GOOS}-${GOARCH}/sc${EXT} ./cmd/sc | |
| tar -czf .sc/stacks/dist/bundle/sc-${GOOS}-${GOARCH}.tar.gz -C dist/${GOOS}-${GOARCH} sc${EXT} | |
| - name: upload build artifacts | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 | |
| with: | |
| name: sc-${{ matrix.os }}-${{ matrix.arch }} | |
| path: .sc/stacks/dist/bundle/sc-${{ matrix.os }}-${{ matrix.arch }}.tar.gz | |
| retention-days: 1 | |
| build-binaries: | |
| name: Build ${{ matrix.target }} | |
| runs-on: blacksmith-8vcpu-ubuntu-2204 | |
| needs: build-setup | |
| strategy: | |
| matrix: | |
| include: | |
| - target: github-actions | |
| cmd: github-actions | |
| output: dist/github-actions | |
| - target: cloud-helpers | |
| cmd: cloud-helpers | |
| output: dist/cloud-helpers | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| persist-credentials: false | |
| - name: Set up Go with Blacksmith caching | |
| uses: useblacksmith/setup-go@647ac649bd5b480f2a262e3e3e5f4d150ed452ad # v6.0.1 | |
| with: | |
| go-version: '1.25' | |
| - name: create build directories | |
| run: | | |
| mkdir -p dist | |
| - name: build ${{ matrix.target }} | |
| env: | |
| CGO_ENABLED: "0" | |
| run: | | |
| go build -a -installsuffix cgo -ldflags "-s -w" -o ${{ matrix.output }} ./cmd/${{ matrix.cmd }} | |
| - name: upload ${{ matrix.target }} binary | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 | |
| with: | |
| name: ${{ matrix.target }}-binary | |
| path: ${{ matrix.output }} | |
| retention-days: 1 | |
| build-github-actions-staging: | |
| name: Build github-actions-staging | |
| runs-on: blacksmith-8vcpu-ubuntu-2204 | |
| needs: build-setup | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| persist-credentials: false | |
| - name: Set up Go with Blacksmith caching | |
| uses: useblacksmith/setup-go@647ac649bd5b480f2a262e3e3e5f4d150ed452ad # v6.0.1 | |
| with: | |
| go-version: '1.25' | |
| - name: build github-actions-staging | |
| run: | | |
| mkdir -p bin | |
| go build -ldflags "-s -w" -a -installsuffix cgo -o bin/github-actions ./cmd/github-actions | |
| - name: upload github-actions-staging binary | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 | |
| with: | |
| name: github-actions-staging-binary | |
| path: bin/github-actions | |
| retention-days: 1 | |
| test: | |
| name: Run tests | |
| runs-on: blacksmith-8vcpu-ubuntu-2204 | |
| needs: build-setup | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| persist-credentials: false | |
| - name: Set up Go with Blacksmith caching | |
| uses: useblacksmith/setup-go@647ac649bd5b480f2a262e3e3e5f4d150ed452ad # v6.0.1 | |
| with: | |
| go-version: '1.25' | |
| - name: test | |
| run: | | |
| go test ./... | |
| finalize: | |
| name: Finalize build in branch | |
| runs-on: ubuntu-latest | |
| if: ${{ always() }} | |
| permissions: | |
| contents: write | |
| needs: | |
| - build-setup | |
| - build-platforms | |
| - build-binaries | |
| - build-github-actions-staging | |
| - test | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| if: ${{ always() }} | |
| with: | |
| persist-credentials: false | |
| - name: Extract git reference | |
| id: extract_git_ref | |
| if: ${{ always() }} | |
| shell: bash | |
| env: | |
| COMMIT_MESSAGE: ${{ github.event.head_commit.message || github.event.workflow_run.head_commit.message }} | |
| run: |- | |
| message="$(printf '%s' "$COMMIT_MESSAGE" | tr -d '\n')" | |
| echo "branch=$GITHUB_REF_NAME" >> $GITHUB_OUTPUT | |
| echo "message=$message" >> $GITHUB_OUTPUT | |
| echo "author=$GITHUB_ACTOR" >> $GITHUB_OUTPUT | |
| echo "url=$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID" >> $GITHUB_OUTPUT | |
| - name: Notify Telegram (success) | |
| if: ${{ success() && !contains(needs.*.result, 'failure') }} | |
| continue-on-error: true | |
| uses: simple-container-com/actions/notify-telegram@main | |
| with: | |
| chat-id: ${{ needs.build-setup.outputs.cicd-bot-telegram-chat-id }} | |
| token: ${{ needs.build-setup.outputs.cicd-bot-telegram-token }} | |
| text: '✅ CI passed: ' | |
| link-url: ${{ github.event.pull_request.html_url || format('{0}/{1}/actions/runs/{2}', github.server_url, github.repository, github.run_id) }} | |
| link-text: "${{ github.event.pull_request.title && format('PR #{0}: {1}', github.event.pull_request.number, github.event.pull_request.title) || github.workflow }}" | |
| suffix: ' on ${{ github.head_ref || github.ref_name }} by ${{ steps.extract_git_ref.outputs.author }}' | |
| - name: Notify Telegram (failure) | |
| if: ${{ failure() || contains(needs.*.result, 'failure') }} | |
| continue-on-error: true | |
| uses: simple-container-com/actions/notify-telegram@main | |
| with: | |
| chat-id: ${{ needs.build-setup.outputs.cicd-bot-telegram-chat-id }} | |
| token: ${{ needs.build-setup.outputs.cicd-bot-telegram-token }} | |
| text: '❗ CI failed: ' | |
| link-url: ${{ github.event.pull_request.html_url || format('{0}/{1}/actions/runs/{2}', github.server_url, github.repository, github.run_id) }} | |
| link-text: "${{ github.event.pull_request.title && format('PR #{0}: {1}', github.event.pull_request.number, github.event.pull_request.title) || github.workflow }}" | |
| suffix: ' on ${{ github.head_ref || github.ref_name }} by ${{ steps.extract_git_ref.outputs.author }}' | |
| - name: Build failed due to previously failed steps | |
| id: fail_if_needed | |
| if: ${{ failure() || contains(needs.*.result, 'failure') }} | |
| shell: bash | |
| run: |- | |
| exit 1 |