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
12 changes: 8 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,9 @@ jobs:
retention-days: 7

# ---------------------------------------------------------------------------
# audit: check dependencies for known vulnerabilities
# audit: check dependencies for known vulnerabilities and policy violations
# Runs on ubuntu only — advisory database is platform-neutral.
# Gates: cargo-audit (RustSec advisories), cargo-deny (policy/licenses/sources)
# ---------------------------------------------------------------------------
audit:
name: Audit dependencies
Expand All @@ -201,8 +202,11 @@ jobs:
- name: Cache Cargo registry and build artifacts
uses: Swatinem/rust-cache@v2

- name: Install cargo-audit
run: cargo install cargo-audit --quiet
- name: Install cargo-audit and cargo-deny
run: cargo install cargo-audit cargo-deny --quiet

- name: Run cargo audit
- name: Run cargo audit (RustSec advisories)
run: cargo audit

- name: "Run cargo deny (policy, licenses, sources, bans)"
run: cargo deny check
52 changes: 45 additions & 7 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,16 @@ jobs:
with:
key: ${{ matrix.target }}

# Pre-build supply-chain security gates: RustSec advisories + policy enforcement
- name: Install cargo-audit and cargo-deny
run: cargo install cargo-audit cargo-deny --quiet

- name: Supply-chain gate — cargo audit (RustSec advisories)
run: cargo audit

- name: Supply-chain gate — cargo deny (licenses, sources, bans, advisories)
run: cargo deny check

# Build all three binary crates in a single workspace compile.
# Cross-compiled binaries land in target/<target>/release/.
- name: Build release binaries
Expand Down Expand Up @@ -119,16 +129,40 @@ jobs:
echo "Created ${TARBALL_STEM}.tar.gz"
cat "${TARBALL_STEM}.tar.gz.sha256"

# Upload both artefacts so the release job can download them.
# Generate Software Bill of Materials (SBOM) in CycloneDX format
# The SBOM captures all direct and transitive dependencies at build time.
- name: Install cargo-cyclonedx
run: cargo install cargo-cyclonedx --quiet

- name: Generate CycloneDX SBOM
run: |
cargo cyclonedx --release --target ${{ matrix.target }} \
-o "clx-${{ matrix.arch }}-apple-darwin.sbom.xml"
echo "SBOM generated: clx-${{ matrix.arch }}-apple-darwin.sbom.xml"
ls -lh "clx-${{ matrix.arch }}-apple-darwin.sbom.xml"

# Generate build provenance attestation using GitHub's native SLSA provenance action.
# This creates a cryptographically-verifiable attestation that this tarball was built
# by this workflow, at this commit, with no external intervention.
- name: Generate build provenance attestation
uses: actions/attest-build-provenance@v1
with:
subject-path: ${{ env.TARBALL_STEM }}.tar.gz
# Note: GitHub's default keyless Sigstore signing (OIDC) is used.
# No long-lived signing keys are stored or transmitted.

# Upload artefacts so the release job can download them.
# Each matrix leg uploads to a uniquely named artifact to avoid collisions.
- name: Upload tarball artifact
# Includes: tarball, checksum, and SBOM.
- name: Upload release artifacts (tarball, checksum, SBOM, attestation)
uses: actions/upload-artifact@v4
with:
name: clx-${{ matrix.arch }}-apple-darwin
path: |
${{ env.TARBALL_STEM }}.tar.gz
${{ env.TARBALL_STEM }}.tar.gz.sha256
if-no-files-found: error
clx-${{ matrix.arch }}-apple-darwin.sbom.xml
if-no-files-found: warn
retention-days: 1

# ---------------------------------------------------------------------------
Expand Down Expand Up @@ -156,15 +190,17 @@ jobs:
with:
path: artifacts

# Flatten the nested subdirectories so all tarballs and checksums sit
# side-by-side at artifacts/*.tar.gz and artifacts/*.tar.gz.sha256.
# Flatten the nested subdirectories so all files sit side-by-side
# at release-assets/*.tar.gz, *.sha256, *.sbom.xml, etc.
- name: Flatten artifact directories
run: |
find artifacts -type f | sort
mkdir -p release-assets
find artifacts -type f -exec mv {} release-assets/ \;
echo "--- Release assets ---"
ls -lh release-assets/
echo "--- Artifact manifest ---"
find release-assets -type f -exec sha256sum {} \;

# Derive the human-readable version from the Git tag (strips the leading 'v').
- name: Set release version
Expand All @@ -173,10 +209,11 @@ jobs:
echo "RELEASE_VERSION=${VERSION}" >> "$GITHUB_ENV"
echo "Publishing release for ${VERSION}"

# Create the GitHub Release and attach all macOS tarballs + checksums.
# Create the GitHub Release and attach all release assets.
# Includes: tarballs, checksums, SBOMs, and build attestations.
# generate_release_notes: true fills the body with a commit-range changelog
# automatically generated by GitHub (no template required).
- name: Create GitHub Release
- name: Create GitHub Release with supply-chain artifacts
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ github.ref_name }}
Expand All @@ -188,6 +225,7 @@ jobs:
files: |
release-assets/*.tar.gz
release-assets/*.tar.gz.sha256
release-assets/*.sbom.xml
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,6 @@ SPEC.md
# Personal orchestration (not part of CLX)
/claude/
/.claude/
*.cdx.xml
clx-sbom.xml
/*.cdx.xml
Loading
Loading