Files
punktfunk/.gitea/workflows/sbom.yml
T
enricobuehlerandClaude Fable 5 5d018eea7c ci: the supply chain accounts for itself — per-release SBOM, full-tree audits, a real license gate
CRA Annex I Part II groundwork (see punktfunk-planning design/cra-readiness.md, Phase 1):

* sbom.yml + scripts/ci/gen-sbom.sh: every vX.Y.Z release gets a CycloneDX
  SBOM attached — syft over both Cargo.locks, all Bun/pnpm trees and the
  Swift Package.resolved (2,667 components), merged with
  compliance/sbom/manual-components.cdx.json for what no lockfile records
  (pyrowave/Granite/volk/Vulkan-Headers pins, libvpl, FFmpeg, SDL3,
  VB-CABLE, punktfunk-gamescope).
* audit.yml: bun audit now covers sdk + plugin-kit (not just web), decky's
  pnpm tree is scanned, and docs-site runs non-blocking until its known
  CMS-chain advisories are cleared. All shipping trees verified green today.
* license-gate: about.toml's allowlist claim is finally enforced —
  cargo-about 0.9.1 with --fail over BOTH workspaces. The old [crate.clarify]
  license-only syntax fails to deserialize under 0.9; migrated ring to a
  per-crate accepted extension and dropped the stale aws-lc-sys entry
  (workspace is ring-only). Both gates validated green locally.
* drivers/Cargo.lock: sync the pf-dualsense→pf-gamepad rename — the crate
  rename updated the manifest but the Windows-only lockfile was never
  regenerated; cargo-about's metadata pass caught it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-29 00:59:29 +02:00

61 lines
2.6 KiB
YAML

# Per-release SBOM (CRA Annex I Part II §1: identify and document the components in the product,
# in a commonly used machine-readable format — we emit CycloneDX JSON).
#
# Tag push → the SBOM is attached to the Gitea release, next to the artifacts it describes.
# Release assets are never pruned (security updates must stay available ≥10 years, CRA Art. 13),
# so the SBOM's retention rides on the release's.
# workflow_dispatch on a non-tag ref → generated and uploaded as a workflow artifact only
# (pipeline validation / an on-demand snapshot); no release is touched.
#
# What goes in: scripts/ci/gen-sbom.sh = syft over the checkout (every lockfile-pinned dep in
# both Rust workspaces + the JS trees + Swift Package.resolved) merged with
# compliance/sbom/manual-components.cdx.json (vendored C/C++, bundled DLLs, VB-CABLE, gamescope).
name: sbom
on:
push:
tags: ['v*']
workflow_dispatch:
jobs:
sbom:
runs-on: ubuntu-24.04
container:
image: git.unom.io/unom/punktfunk-rust-ci:latest
timeout-minutes: 20
steps:
# fetch-depth 0: the dispatch path derives the canary base from the tag history
# (scripts/ci/pf-version.sh), which a shallow clone cannot see.
- uses: actions/checkout@v4
with:
fetch-depth: 0
# Pinned syft (keep in sync with the version validated against this repo; bump deliberately).
- name: Install syft
run: |
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh \
| sh -s -- -b /usr/local/bin v1.49.0
- name: Generate SBOM
run: |
git config --global --add safe.directory "$PWD"
case "$GITHUB_REF" in
refs/tags/v*) VERSION="${GITHUB_REF_NAME#v}" ;;
*) eval "$(bash scripts/ci/pf-version.sh)"; VERSION="${PF_BASE}-snapshot" ;;
esac
sh scripts/ci/gen-sbom.sh "$VERSION" "punktfunk-${VERSION}.cdx.json"
echo "SBOM_FILE=punktfunk-${VERSION}.cdx.json" >> "$GITHUB_ENV"
- name: Attach to release
if: startsWith(github.ref, 'refs/tags/')
env:
GITEA_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
run: |
. scripts/ci/gitea-release.sh
RID=$(ensure_release "$GITHUB_REF_NAME" "$GITHUB_REF_NAME" auto)
upsert_asset "$RID" "$SBOM_FILE"
# v3, not v4: Gitea's artifact backend rejects upload-artifact@v4 (see release.yml).
- name: Upload artifact (non-tag runs)
if: "!startsWith(github.ref, 'refs/tags/')"
uses: actions/upload-artifact@v3
with:
name: sbom
path: punktfunk-*.cdx.json