mirror of
https://github.com/mwisnowski/mtg_python_deckbuilder.git
synced 2026-04-04 20:27:16 +02:00
feat: add SBOM generation and build provenance attestation to release workflows (#69)
* feat: add SBOM generation and build provenance attestation to release workflows * docs: update release notes template with SBOM unreleased entry
This commit is contained in:
parent
6d1d5a1822
commit
75184a5967
5 changed files with 90 additions and 5 deletions
41
.github/workflows/dockerhub-publish.yml
vendored
41
.github/workflows/dockerhub-publish.yml
vendored
|
|
@ -119,6 +119,7 @@ jobs:
|
||||||
platforms: linux/amd64
|
platforms: linux/amd64
|
||||||
tags: ${{ steps.arch_tag.outputs.tag }}
|
tags: ${{ steps.arch_tag.outputs.tag }}
|
||||||
labels: ${{ needs.prepare.outputs.labels }}
|
labels: ${{ needs.prepare.outputs.labels }}
|
||||||
|
provenance: mode=max
|
||||||
build-args: |
|
build-args: |
|
||||||
APP_VERSION=${{ needs.prepare.outputs.version }}
|
APP_VERSION=${{ needs.prepare.outputs.version }}
|
||||||
|
|
||||||
|
|
@ -171,6 +172,7 @@ jobs:
|
||||||
platforms: linux/arm64
|
platforms: linux/arm64
|
||||||
tags: ${{ steps.arch_tag.outputs.tag }}
|
tags: ${{ steps.arch_tag.outputs.tag }}
|
||||||
labels: ${{ needs.prepare.outputs.labels }}
|
labels: ${{ needs.prepare.outputs.labels }}
|
||||||
|
provenance: mode=max
|
||||||
build-args: |
|
build-args: |
|
||||||
APP_VERSION=${{ needs.prepare.outputs.version }}
|
APP_VERSION=${{ needs.prepare.outputs.version }}
|
||||||
|
|
||||||
|
|
@ -178,6 +180,10 @@ jobs:
|
||||||
name: Create latest multi-arch manifest
|
name: Create latest multi-arch manifest
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [prepare, build_amd64, build_arm64]
|
needs: [prepare, build_amd64, build_arm64]
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
id-token: write
|
||||||
|
attestations: write
|
||||||
steps:
|
steps:
|
||||||
- name: Docker Hub login
|
- name: Docker Hub login
|
||||||
uses: docker/login-action@v3.5.0
|
uses: docker/login-action@v3.5.0
|
||||||
|
|
@ -197,3 +203,38 @@ jobs:
|
||||||
echo "Inspecting latest"
|
echo "Inspecting latest"
|
||||||
docker buildx imagetools inspect mwisnowski/mtg-python-deckbuilder:latest
|
docker buildx imagetools inspect mwisnowski/mtg-python-deckbuilder:latest
|
||||||
|
|
||||||
|
- name: Extract manifest digest
|
||||||
|
id: inspect
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
DIGEST=$(docker buildx imagetools inspect mwisnowski/mtg-python-deckbuilder:latest \
|
||||||
|
| grep -E '^Digest:' | awk '{print $2}' | head -1)
|
||||||
|
echo "Manifest digest: $DIGEST"
|
||||||
|
echo "digest=$DIGEST" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Attest image build provenance
|
||||||
|
uses: actions/attest-build-provenance@v2.2.3
|
||||||
|
with:
|
||||||
|
subject-name: index.docker.io/mwisnowski/mtg-python-deckbuilder
|
||||||
|
subject-digest: ${{ steps.inspect.outputs.digest }}
|
||||||
|
push-to-registry: false
|
||||||
|
|
||||||
|
- name: Generate image SBOM (CycloneDX)
|
||||||
|
uses: anchore/sbom-action@v0.24.0
|
||||||
|
with:
|
||||||
|
image: mwisnowski/mtg-python-deckbuilder:latest
|
||||||
|
format: cyclonedx-json
|
||||||
|
output-file: sbom-image-${{ needs.prepare.outputs.version }}.cyclonedx.json
|
||||||
|
upload-artifact: false
|
||||||
|
upload-release-assets: false
|
||||||
|
|
||||||
|
- name: Upload image SBOM to GitHub Release
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
gh release upload ${{ needs.prepare.outputs.version }} \
|
||||||
|
sbom-image-${{ needs.prepare.outputs.version }}.cyclonedx.json \
|
||||||
|
--repo ${{ github.repository }} \
|
||||||
|
--clobber
|
||||||
|
|
||||||
|
|
|
||||||
21
.github/workflows/github-release.yml
vendored
21
.github/workflows/github-release.yml
vendored
|
|
@ -56,6 +56,24 @@ jobs:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v5.0.0
|
uses: actions/checkout@v5.0.0
|
||||||
|
|
||||||
|
- name: Generate source SBOM (SPDX)
|
||||||
|
uses: anchore/sbom-action@v0.24.0
|
||||||
|
with:
|
||||||
|
path: .
|
||||||
|
format: spdx-json
|
||||||
|
output-file: sbom-source.spdx.json
|
||||||
|
upload-artifact: false
|
||||||
|
upload-release-assets: false
|
||||||
|
|
||||||
|
- name: Generate source SBOM (CycloneDX)
|
||||||
|
uses: anchore/sbom-action@v0.24.0
|
||||||
|
with:
|
||||||
|
path: .
|
||||||
|
format: cyclonedx-json
|
||||||
|
output-file: sbom-source.cyclonedx.json
|
||||||
|
upload-artifact: false
|
||||||
|
upload-release-assets: false
|
||||||
|
|
||||||
- name: Prepare release notes
|
- name: Prepare release notes
|
||||||
id: notes
|
id: notes
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
@ -84,5 +102,8 @@ jobs:
|
||||||
tag_name: ${{ steps.notes.outputs.version }}
|
tag_name: ${{ steps.notes.outputs.version }}
|
||||||
name: ${{ steps.notes.outputs.version }}
|
name: ${{ steps.notes.outputs.version }}
|
||||||
body_path: ${{ steps.notes.outputs.notes_file }}
|
body_path: ${{ steps.notes.outputs.notes_file }}
|
||||||
|
files: |
|
||||||
|
sbom-source.spdx.json
|
||||||
|
sbom-source.cyclonedx.json
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,8 @@ This format follows Keep a Changelog principles and aims for Semantic Versioning
|
||||||
- Link PRs/issues inline when helpful, e.g., (#123) or [#123]. Reference-style links at the bottom are encouraged for readability.
|
- Link PRs/issues inline when helpful, e.g., (#123) or [#123]. Reference-style links at the bottom are encouraged for readability.
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
_No unreleased changes yet._
|
### Added
|
||||||
|
- **SBOM & supply chain provenance**: Every tagged release now attaches source SBOMs (SPDX + CycloneDX JSON) for Python dependencies and a CycloneDX container image SBOM to the GitHub Release assets. Build provenance attestations (SLSA-style) are published for the multi-arch Docker image via the GitHub Attestations API. `provenance: mode=max` is enabled on all arch builds.
|
||||||
|
|
||||||
## [4.5.2] - 2026-04-01
|
## [4.5.2] - 2026-04-01
|
||||||
### Added
|
### Added
|
||||||
|
|
|
||||||
25
README.md
25
README.md
|
|
@ -34,6 +34,7 @@ A web-first Commander/EDH deckbuilder with a shared core for CLI, headless, and
|
||||||
- [Development setup](#development-setup)
|
- [Development setup](#development-setup)
|
||||||
- [Troubleshooting](#troubleshooting)
|
- [Troubleshooting](#troubleshooting)
|
||||||
- [Contributing](#contributing)
|
- [Contributing](#contributing)
|
||||||
|
- [Supply chain security](#supply-chain-security)
|
||||||
- [License & attribution](#license--attribution)
|
- [License & attribution](#license--attribution)
|
||||||
- [Further reading](#further-reading)
|
- [Further reading](#further-reading)
|
||||||
|
|
||||||
|
|
@ -446,6 +447,30 @@ Pull requests are welcome—follow the conventional commit style, keep diffs foc
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Supply chain security
|
||||||
|
Every tagged release includes SBOM (Software Bill of Materials) files attached to the GitHub Release assets:
|
||||||
|
|
||||||
|
| File | Format | Contents |
|
||||||
|
|------|--------|----------|
|
||||||
|
| `sbom-source.spdx.json` | SPDX 2.x JSON | Python dependency tree from source |
|
||||||
|
| `sbom-source.cyclonedx.json` | CycloneDX JSON | Python dependency tree from source |
|
||||||
|
| `sbom-image-vX.Y.Z.cyclonedx.json` | CycloneDX JSON | Full container image (OS + app) |
|
||||||
|
|
||||||
|
Build provenance attestations are published to the GitHub Attestations API for the multi-arch container image. To verify:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gh attestation verify oci://docker.io/mwisnowski/mtg-python-deckbuilder:latest \
|
||||||
|
--repo mwisnowski/mtg_python_deckbuilder
|
||||||
|
```
|
||||||
|
|
||||||
|
To inspect an SBOM locally (requires [Syft](https://github.com/anchore/syft)):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
syft convert sbom-source.cyclonedx.json -o table
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## License & attribution
|
## License & attribution
|
||||||
Licensed under the [MIT License](LICENSE). Card data and imagery are provided by [Scryfall](https://scryfall.com); please respect their [API terms](https://scryfall.com/docs/api).
|
Licensed under the [MIT License](LICENSE). Card data and imagery are provided by [Scryfall](https://scryfall.com); please respect their [API terms](https://scryfall.com/docs/api).
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,6 @@
|
||||||
# MTG Python Deckbuilder
|
# MTG Python Deckbuilder
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
_No unreleased changes yet._
|
|
||||||
|
|
||||||
## [4.5.2] - 2026-04-01
|
|
||||||
### Added
|
### Added
|
||||||
- Hover-intent prefetch (`WEB_PREFETCH=1`): hovering the Open button on the Finished Decks page prefetches the deck view after 100 ms, making it load near-instantly. Off by default; Data Saver / slow connections are respected automatically.
|
- **SBOM & supply chain provenance**: Every tagged release now attaches source SBOMs (SPDX + CycloneDX JSON) for Python dependencies and a CycloneDX container image SBOM to the GitHub Release assets. Build provenance attestations (SLSA-style) are published for the multi-arch Docker image via the GitHub Attestations API. `provenance: mode=max` is enabled on all arch builds.
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue