name: Release
on:
push:
tags:
- 'v*'
permissions:
actions: read
attestations: write
contents: write
id-token: write
packages: write
jobs:
build:
name: Build ${{ matrix.target }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- target: x86_64-unknown-linux-gnu
os: ubuntu-latest
asset_name: codexctl-x86_64-unknown-linux-gnu.tar.gz
- target: aarch64-unknown-linux-gnu
os: ubuntu-latest
asset_name: codexctl-aarch64-unknown-linux-gnu.tar.gz
- target: x86_64-apple-darwin
os: macos-latest
asset_name: codexctl-x86_64-apple-darwin.tar.gz
- target: aarch64-apple-darwin
os: macos-latest
asset_name: codexctl-aarch64-apple-darwin.tar.gz
- target: x86_64-pc-windows-msvc
os: windows-latest
asset_name: codexctl-x86_64-pc-windows-msvc.zip
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- uses: Swatinem/rust-cache@v2
with:
key: ${{ matrix.target }}
- name: Install cross-compilation tools
if: matrix.target == 'aarch64-unknown-linux-gnu'
run: |
sudo apt-get update
sudo apt-get install -y gcc-aarch64-linux-gnu
echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc" >> $GITHUB_ENV
- name: Build
run: cargo build --release --locked --target ${{ matrix.target }}
- name: Package (Unix)
if: matrix.os != 'windows-latest'
run: |
cd target/${{ matrix.target }}/release
ln -sf codexctl cdx
tar czvf ../../../${{ matrix.asset_name }} codexctl cdx
cd ../../..
- name: Package (Windows)
if: matrix.os == 'windows-latest'
run: |
cd target/${{ matrix.target }}/release
copy codexctl.exe cdx.exe
7z a ../../../${{ matrix.asset_name }} codexctl.exe cdx.exe
cd ../../..
- name: Upload artifact
uses: actions/upload-artifact@v7
with:
name: ${{ matrix.asset_name }}
path: ${{ matrix.asset_name }}
release:
name: Sign, Attest, and Release
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Download all artifacts
uses: actions/download-artifact@v8
with:
path: artifacts
merge-multiple: true
- name: List artifacts
run: ls -la artifacts/
- name: Generate checksums
run: |
cd artifacts
find . -maxdepth 1 -type f \( -name "codexctl-*.tar.gz" -o -name "codexctl-*.zip" \) -print0 \
| sort -z \
| xargs -0 sha256sum > SHA256SUMS
cat SHA256SUMS
- name: Install Syft
uses: anchore/sbom-action/download-syft@v0
id: install-syft
- name: Generate SBOM (SPDX JSON)
run: |
"${{ steps.install-syft.outputs.cmd }}" dir:. \
-o "spdx-json=artifacts/codexctl-${GITHUB_REF_NAME}.spdx.json"
ls -la "artifacts/codexctl-${GITHUB_REF_NAME}.spdx.json"
- name: Install Cosign
uses: sigstore/cosign-installer@v4.1.1
- name: Sign release artifacts
run: |
files=(
artifacts/codexctl-*.tar.gz
artifacts/codexctl-*.zip
artifacts/SHA256SUMS
"artifacts/codexctl-${GITHUB_REF_NAME}.spdx.json"
)
for file in "${files[@]}"; do
if [ ! -f "${file}" ]; then
continue
fi
cosign sign-blob --yes \
--bundle "${file}.bundle" \
--output-signature "${file}.sig" \
--output-certificate "${file}.pem" \
"${file}"
done
- name: Attest build provenance
uses: actions/attest-build-provenance@v4.1.0
with:
subject-checksums: artifacts/SHA256SUMS
- name: Attest SBOM
uses: actions/attest-sbom@v4.1.0
with:
subject-checksums: artifacts/SHA256SUMS
sbom-path: artifacts/codexctl-${{ github.ref_name }}.spdx.json
- name: Create Release
uses: softprops/action-gh-release@v2
with:
files: artifacts/*
generate_release_notes: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
publish-cargo:
name: Publish to crates.io
needs: release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Publish
run: cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }}
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}