Repository navigation
ci(release): add release gates, smoke tests, post-publish verification - #76
Conversation
…h verification PR CI does not cover release-specific risks. Adds four safeguards: - release-gate job: the tag must point at the default branch HEAD and its version must match Cargo.toml (both failure modes were hit while cutting v0.7.0) - per-platform smoke tests: run each freshly built binary and expect the startup banner plus exit 1 (missing GITHUB_TOKEN) — catches cross-compiled builds that link but do not run - verify-release job: re-downloads every published asset and checks the SHA-256 checksums, then smoke-tests the published linux-amd64 binary - concurrency group to serialize runs of the same tag
| run: | | ||
| DEFAULT_BRANCH="${{ github.event.repository.default_branch }}" | ||
| TAG_SHA=$(git rev-parse "${{ github.ref_name }}^{commit}") | ||
| HEAD_SHA=$(git rev-parse "origin/${DEFAULT_BRANCH}") | ||
| if [ "$TAG_SHA" != "$HEAD_SHA" ]; then | ||
| echo "::error::Tag ${{ github.ref_name }} ($TAG_SHA) does not point at ${DEFAULT_BRANCH} HEAD ($HEAD_SHA)." | ||
| exit 1 | ||
| fi | ||
|
|
There was a problem hiding this comment.
Template Injection in GitHub Workflows Action - high severity
A GitHub Actions workflow step contains a template expression referencing potentially untrusted GitHub context fields. This may allow malicious input to be injected into shell commands, leading to a potential supply chain attack as tokens of the CI/CD pipeline could be exfiltrated.
Show fix
| run: | | |
| DEFAULT_BRANCH="${{ github.event.repository.default_branch }}" | |
| TAG_SHA=$(git rev-parse "${{ github.ref_name }}^{commit}") | |
| HEAD_SHA=$(git rev-parse "origin/${DEFAULT_BRANCH}") | |
| if [ "$TAG_SHA" != "$HEAD_SHA" ]; then | |
| echo "::error::Tag ${{ github.ref_name }} ($TAG_SHA) does not point at ${DEFAULT_BRANCH} HEAD ($HEAD_SHA)." | |
| exit 1 | |
| fi | |
| env: | |
| DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} | |
| REF_NAME: ${{ github.ref_name }} | |
| run: | | |
| TAG_SHA=$(git rev-parse "${REF_NAME}^{commit}") | |
| HEAD_SHA=$(git rev-parse "origin/${DEFAULT_BRANCH}") | |
| if [ "$TAG_SHA" != "$HEAD_SHA" ]; then | |
| echo "::error::Tag ${REF_NAME} ($TAG_SHA) does not point at ${DEFAULT_BRANCH} HEAD ($HEAD_SHA)." | |
| exit 1 | |
| fi | |
Reply @AikidoSec ignore: [REASON] to ignore this issue.
More info
| run: | | ||
| set -euo pipefail | ||
| TAG="${{ github.ref_name }}" | ||
| REPO="${{ github.repository }}" | ||
| DIR=$(mktemp -d) | ||
| cd "$DIR" | ||
| curl -fsSL -o code-review-cli-linux-amd64 "https://github.com/${REPO}/releases/download/${TAG}/code-review-cli-linux-amd64" | ||
| chmod +x code-review-cli-linux-amd64 | ||
| set +e | ||
| out=$(./code-review-cli-linux-amd64 2>&1) | ||
| rc=$? | ||
| set -e | ||
| echo "$out" | ||
| if [ "$rc" -ne 1 ] || ! echo "$out" | grep -q "AI Code Reviewer"; then | ||
| echo "::error::Published linux-amd64 binary does not run" | ||
| exit 1 | ||
| fi |
There was a problem hiding this comment.
Binary, code or archive is pulled from a remote source without integrity verification - medium severity
A GitHub Actions Workflow was built using an artifact from a remote source without any integrity verification. If the remote artifact were silently replaced with a malicious version (for example, through a supply chain attack), the integrity and confidentiality of the environment in which the container is deployed could be compromised.
Show fix
Remediation: Validate the artifact against a trusted SHA-512 checksum in the CI/CD pipeline using sha512sum in check mode. Store the expected checksum in a file (e.g., artifact.sha512), then verify it with: sha512sum -c artifact.sha512. Enable strict error handling (for example, set -e in shell scripts) so the pipeline fails if verification fails or outputs errors.
Reply @AikidoSec ignore: [REASON] to ignore this issue.
More info
Context
While cutting v0.7.0 we hit two release-only failure modes that PR CI cannot catch: a tag pointing at a diverged commit (run rejected by GitHub after the ref moved), and the risk of forgetting the
Cargo.tomlversion bump. Neither the cross-compiled binaries' ability to actually run, nor the integrity of uploaded assets was ever verified.Changes to
release.ymlrelease-gatejob (runs first, fails fast)crates/code-review-cli/Cargo.toml— prevents "b tagged, binary says 0.(b-1)"GITHUB_TOKEN): catches cross-compiled builds that link but do not run (wrong arch, missing shared libs, glibc too new)verify-releasejob (runs last) — re-downloads all 10 published assets and runssha256sum -c, then smoke-tests the published linux-amd64 binaryconcurrency: release-<tag>— serializes runs of the same tag, no duplicate release racesVerification
yaml.safe_load)