Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions .github/workflows/release-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: Supply Chain Check

on:
pull_request:
paths:
- ".github/workflows/release.yml"
- ".github/workflows/release-check.yml"
- "composer.json"

permissions:
contents: read

jobs:
verify-release-artifacts:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v7

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: "8.4"
extensions: simplexml, zip
coverage: none

- name: Install runtime dependencies
run: composer install --no-dev --prefer-dist --no-progress --no-interaction

- name: Create test package
run: composer archive --format=zip --file=elp-parser-test

- name: Generate test CycloneDX SBOM
uses: anchore/sbom-action@v0.24.2
with:
path: .
format: cyclonedx-json
output-file: elp-parser-test.cdx.json
upload-artifact: false
upload-release-assets: false

- name: Generate and verify checksums
run: |
sha256sum elp-parser-test.zip elp-parser-test.cdx.json > SHA256SUMS
sha256sum --check SHA256SUMS

- name: Validate CycloneDX document
run: |
jq -e '.bomFormat == "CycloneDX"' elp-parser-test.cdx.json
jq -e '.specVersion != null' elp-parser-test.cdx.json
jq -e '.metadata.component != null' elp-parser-test.cdx.json
49 changes: 43 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,68 @@ jobs:
build:
runs-on: ubuntu-latest
permissions:
actions: read
attestations: write
contents: write
id-token: write

steps:
- uses: actions/checkout@v7

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.0'
php-version: "8.4"
extensions: simplexml, zip
coverage: none

- name: Install dependencies
run: composer install --no-dev --prefer-dist --no-progress
- name: Install runtime dependencies
run: composer install --no-dev --prefer-dist --no-progress --no-interaction

- name: Get tag
id: tag
run: echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
run: echo "tag=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT"

- name: Create package
run: composer archive --format=zip --file="elp-parser-${{ steps.tag.outputs.tag }}"
run: |
composer archive \
--format=zip \
--file="elp-parser-${{ steps.tag.outputs.tag }}"

- name: Generate CycloneDX SBOM
uses: anchore/sbom-action@v0.24.2
with:
path: .
format: cyclonedx-json
output-file: elp-parser-${{ steps.tag.outputs.tag }}.cdx.json
upload-artifact: false
upload-release-assets: false

- name: Generate checksums
run: |
sha256sum \
"elp-parser-${{ steps.tag.outputs.tag }}.zip" \
"elp-parser-${{ steps.tag.outputs.tag }}.cdx.json" \
> SHA256SUMS

- name: Attest build provenance
uses: actions/attest-build-provenance@v4.2.2
with:
subject-path: elp-parser-${{ steps.tag.outputs.tag }}.zip

- name: Attest SBOM
uses: actions/attest-sbom@v4.1.0
with:
subject-path: elp-parser-${{ steps.tag.outputs.tag }}.zip
sbom-path: elp-parser-${{ steps.tag.outputs.tag }}.cdx.json

- name: Create Release
uses: softprops/action-gh-release@v3
with:
files: elp-parser-${{ steps.tag.outputs.tag }}.zip
files: |
elp-parser-${{ steps.tag.outputs.tag }}.zip
elp-parser-${{ steps.tag.outputs.tag }}.cdx.json
SHA256SUMS
draft: false
prerelease: false
generate_release_notes: true
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,10 @@ php tests/upstream-compat.php /path/to/exelearning/test/fixtures
- [Security policy](SECURITY.md)
- [Changelog](CHANGELOG.md)

## Release integrity

Tagged releases publish a CycloneDX SBOM, SHA-256 checksums and GitHub artifact attestations for build provenance and the SBOM. See [Release supply chain](docs/supply-chain.md).

## License

The project is distributed under the MIT License. See [LICENSE.md](LICENSE.md).
28 changes: 28 additions & 0 deletions docs/supply-chain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Release supply chain

Tagged releases publish more than the Composer archive.

Each release contains:

- `elp-parser-<tag>.zip` — distributable package archive;
- `elp-parser-<tag>.cdx.json` — CycloneDX JSON software bill of materials;
- `SHA256SUMS` — SHA-256 checksums for the archive and SBOM.

GitHub Artifact Attestations are also created for:

- build provenance of the ZIP artifact;
- the CycloneDX SBOM bound to that ZIP artifact.

The attestation actions use GitHub OIDC and repository-scoped workflow permissions; no additional signing key or long-lived secret is stored in the repository.

## Verify checksums

```bash
sha256sum --check SHA256SUMS
```

## Verify GitHub attestations

Consumers with the GitHub CLI can verify release artifact attestations using GitHub's artifact-attestation commands against the repository identity.

A dedicated pull-request workflow builds a test archive, generates the SBOM and validates checksums/CycloneDX structure so release packaging changes are checked before a tag is created.
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ nav:
- Guides:
- Validation: validation.md
- Security: security.md
- Release Supply Chain: supply-chain.md
- iDevices: idevices.md
- Assets and Package Entries: assets.md
- Performance: performance.md
Expand Down
Loading