Skip to content

Release CodeTruss CLI v0.2.50 #16

Release CodeTruss CLI v0.2.50

Release CodeTruss CLI v0.2.50 #16

Workflow file for this run

name: Release
on:
push:
tags: ['v*']
permissions: {}
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false
jobs:
release:
name: Build, attest, and release
runs-on: ubuntu-latest
timeout-minutes: 25
permissions:
contents: write
id-token: write
attestations: write
artifact-metadata: write
steps:
- name: Check out the tagged source
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Set up Node
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: '24'
package-manager-cache: false
- name: Activate pinned pnpm
run: |
corepack enable
corepack prepare pnpm@10.28.2 --activate
- name: Install locked dependencies
run: pnpm install --frozen-lockfile
- name: Require tag and package version parity
run: |
node - <<'NODE'
const pkg = require('./packages/cli/package.json')
const expected = `v${pkg.version}`
if (process.env.GITHUB_REF_NAME !== expected) {
throw new Error(`tag ${process.env.GITHUB_REF_NAME} does not match ${expected}`)
}
NODE
- name: Test and build exact release artifacts
run: |
pnpm typecheck
pnpm test
pnpm release:artifact
pnpm release:verify
pnpm test:install
- name: Resolve artifact paths
id: artifact
run: |
VERSION="$(node -p "require('./packages/cli/package.json').version")"
echo "archive=public/downloads/codetruss-cli-${VERSION}.tgz" >> "$GITHUB_OUTPUT"
echo "checksum=public/downloads/codetruss-cli-${VERSION}.tgz.sha256" >> "$GITHUB_OUTPUT"
echo "sbom=public/downloads/codetruss-cli-${VERSION}.sbom.cdx.json" >> "$GITHUB_OUTPUT"
- name: Attest package build provenance
uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4.2.2
with:
subject-path: ${{ steps.artifact.outputs.archive }}
- name: Attest package SBOM
uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4.2.2
with:
subject-path: ${{ steps.artifact.outputs.archive }}
sbom-path: ${{ steps.artifact.outputs.sbom }}
- name: Create, populate, and publish immutable GitHub release
env:
GH_TOKEN: ${{ github.token }}
ARCHIVE: ${{ steps.artifact.outputs.archive }}
CHECKSUM: ${{ steps.artifact.outputs.checksum }}
SBOM: ${{ steps.artifact.outputs.sbom }}
run: |
VERSION="${GITHUB_REF_NAME#v}"
DIGEST="$(cut -d' ' -f1 "$CHECKSUM")"
# Release notes are the changelog entry for this version, not a list of
# commit subjects. `--generate-notes` on a repo whose only commit per
# release is "Release CodeTruss CLI vX" produces a note that says
# nothing a reader did not already know from the title.
awk -v ver="## $VERSION " '
index($0, ver) == 1 { found = 1; next }
found && /^## / { exit }
found { print }
' CHANGELOG.md > changelog-entry.md
# Guard the EXTRACTED ENTRY, not the composed file. The install section
# below is written unconditionally, so a check after composition can
# never fail, and a version missing its changelog entry would publish a
# release note containing nothing but install steps.
if [ ! -s changelog-entry.md ]; then
echo "No changelog entry found for $VERSION; refusing to publish an empty release note." >&2
exit 1
fi
{
cat changelog-entry.md
cat <<NOTES
## Install
\`\`\`bash
curl -fsSL https://codetruss.com/install.sh | sh
\`\`\`
Windows (PowerShell):
\`\`\`powershell
irm https://codetruss.com/install.ps1 | iex
\`\`\`
## Verify what you installed
\`\`\`
sha256 $DIGEST
\`\`\`
\`\`\`bash
gh attestation verify codetruss-cli-$VERSION.tgz --repo $GITHUB_REPOSITORY
\`\`\`
The archive ships with a CycloneDX SBOM and SLSA build provenance. You
should not have to take our word for what is in it.
NOTES
} > release-notes.md
gh release create "$GITHUB_REF_NAME" \
--draft \
--verify-tag \
--notes-file release-notes.md \
--title "CodeTruss CLI $GITHUB_REF_NAME"
gh release upload "$GITHUB_REF_NAME" \
"$ARCHIVE" \
"$CHECKSUM" \
"$SBOM"
gh release edit "$GITHUB_REF_NAME" --draft=false