feat(coding-agent): add release source archives (#6913)

This commit is contained in:
Christian Klotz
2026-07-21 18:18:05 +03:00
committed by GitHub
parent 959cc1897e
commit 4b91ec66fd
3 changed files with 160 additions and 3 deletions
+30 -3
View File
@@ -49,8 +49,27 @@ jobs:
node-version: '22'
registry-url: 'https://registry.npmjs.org'
- name: Build binaries
run: ./scripts/build-binaries.sh
- name: Create source archive
run: |
set -euo pipefail
VERSION="${RELEASE_TAG#v}"
mkdir -p release-assets
./scripts/create-source-archive.sh \
--version "${VERSION}" \
--ref HEAD \
--out "release-assets/pi-${VERSION}-source.tar.gz"
- name: Build binaries from source archive
run: |
set -euo pipefail
VERSION="${RELEASE_TAG#v}"
build_root="$(mktemp -d)"
trap 'rm -rf "${build_root}"' EXIT
tar -xzf "release-assets/pi-${VERSION}-source.tar.gz" -C "${build_root}"
"${build_root}/pi-${VERSION}/scripts/build-binaries.sh" \
--out "${GITHUB_WORKSPACE}/packages/coding-agent/binaries"
- name: Prepare GitHub release payload
run: |
@@ -83,7 +102,9 @@ jobs:
cp "${binary_assets[@]}" "${GITHUB_WORKSPACE}/release-assets/"
cd "${GITHUB_WORKSPACE}/release-assets"
source_asset="pi-${VERSION}-source.tar.gz"
release_assets=(
"${source_asset}"
pi-darwin-arm64.tar.gz
pi-darwin-x64.tar.gz
pi-linux-x64.tar.gz
@@ -125,7 +146,10 @@ jobs:
cd release-assets
VERSION="${RELEASE_TAG#v}"
source_asset="pi-${VERSION}-source.tar.gz"
expected_assets=(
"${source_asset}"
pi-darwin-arm64.tar.gz
pi-darwin-x64.tar.gz
pi-linux-x64.tar.gz
@@ -144,7 +168,7 @@ jobs:
sha256sum -c SHA256SUMS
- name: Create draft GitHub Release and upload binaries
- name: Create draft GitHub Release and upload assets
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
@@ -152,7 +176,10 @@ jobs:
cd release-assets
VERSION="${RELEASE_TAG#v}"
source_asset="pi-${VERSION}-source.tar.gz"
release_assets=(
"${source_asset}"
pi-darwin-arm64.tar.gz
pi-darwin-x64.tar.gz
pi-linux-x64.tar.gz
+13
View File
@@ -59,6 +59,19 @@ npm run check # Lint, format, and type check
./pi-test.sh # Run pi from sources (can be run from any directory)
```
## Building standalone binaries from release source
GitHub releases include a versioned source archive covered by the release's `SHA256SUMS` file. Extract it and run the same build script used for the official standalone binaries:
```bash
VERSION="<release-version>"
tar -xzf "pi-${VERSION}-source.tar.gz"
cd "pi-${VERSION}"
./scripts/build-binaries.sh --platform linux-x64 --out "$PWD/out"
```
The script installs dependencies, builds the monorepo, compiles the Bun executable, and stages its runtime assets. Package maintainers who provide dependencies separately can pass `--skip-install --skip-deps`.
## Supply-chain hardening
We treat npm dependency changes as reviewed code changes.
+117
View File
@@ -0,0 +1,117 @@
#!/usr/bin/env bash
# Create the deterministic source archive uploaded with GitHub releases.
#
# Usage:
# ./scripts/create-source-archive.sh --version <version> --ref <git-ref> --out <archive.tar.gz>
set -euo pipefail
version=""
source_ref="HEAD"
output=""
invocation_dir="$PWD"
usage() {
echo "Usage: $0 --version <version> [--ref <git-ref>] --out <archive.tar.gz>"
}
require_value() {
if [[ $# -lt 2 || -z "$2" ]]; then
echo "$1 requires a value" >&2
usage >&2
exit 1
fi
}
while [[ $# -gt 0 ]]; do
case "$1" in
--version)
require_value "$@"
version="$2"
shift 2
;;
--ref)
require_value "$@"
source_ref="$2"
shift 2
;;
--out)
require_value "$@"
output="$2"
shift 2
;;
--help)
usage
exit 0
;;
*)
echo "Unknown option: $1" >&2
exit 1
;;
esac
done
if [[ -z "$version" || -z "$output" ]]; then
usage >&2
exit 1
fi
if [[ ! "$version" =~ ^[0-9A-Za-z][0-9A-Za-z._-]*$ ]]; then
echo "Invalid version: $version" >&2
exit 1
fi
repo_root="$(cd "$(dirname "$0")/.." && pwd)"
cd "$repo_root"
commit="$(git rev-parse --verify --end-of-options "${source_ref}^{commit}")"
package_version="$(git show "${commit}:packages/coding-agent/package.json" | node -p 'JSON.parse(require("fs").readFileSync(0, "utf8")).version')"
if [[ "$package_version" != "$version" ]]; then
echo "Version ${version} does not match package version ${package_version} at ${source_ref}" >&2
exit 1
fi
if [[ "$output" != /* ]]; then
output="$invocation_dir/$output"
fi
mkdir -p "$(dirname "$output")"
output="$(cd "$(dirname "$output")" && pwd)/$(basename "$output")"
temporary_archive="$(mktemp "${output}.tmp.XXXXXX")"
manifest="$(mktemp "${output}.manifest.XXXXXX")"
trap 'rm -f "$temporary_archive" "$manifest"' EXIT
archive_root="pi-${version}"
git archive --format=tar --prefix="${archive_root}/" "$commit" | gzip -n -9 > "$temporary_archive"
tar -tzf "$temporary_archive" > "$manifest"
required_paths=(
"package.json"
"package-lock.json"
"scripts/build-binaries.sh"
"packages/coding-agent/package.json"
"packages/coding-agent/src/utils/image-resize-worker.ts"
"packages/coding-agent/src/core/export-html/template.css"
)
for path in "${required_paths[@]}"; do
if ! grep -Fxq "${archive_root}/${path}" "$manifest"; then
echo "Source archive is missing required path: $path" >&2
exit 1
fi
done
if ! awk -v prefix="${archive_root}/" 'index($0, prefix) != 1 { exit 1 }' "$manifest"; then
echo "Source archive contains a path outside ${archive_root}/" >&2
exit 1
fi
if grep -Eq '(^|/)node_modules/|(^|/)packages/coding-agent/binaries/' "$manifest"; then
echo "Source archive contains generated dependencies or binaries" >&2
exit 1
fi
mv "$temporary_archive" "$output"
trap 'rm -f "$manifest"' EXIT
printf '%s\n' "$output"