feat(coding-agent): add release source archives (#6913)
This commit is contained in:
@@ -49,8 +49,27 @@ jobs:
|
|||||||
node-version: '22'
|
node-version: '22'
|
||||||
registry-url: 'https://registry.npmjs.org'
|
registry-url: 'https://registry.npmjs.org'
|
||||||
|
|
||||||
- name: Build binaries
|
- name: Create source archive
|
||||||
run: ./scripts/build-binaries.sh
|
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
|
- name: Prepare GitHub release payload
|
||||||
run: |
|
run: |
|
||||||
@@ -83,7 +102,9 @@ jobs:
|
|||||||
cp "${binary_assets[@]}" "${GITHUB_WORKSPACE}/release-assets/"
|
cp "${binary_assets[@]}" "${GITHUB_WORKSPACE}/release-assets/"
|
||||||
|
|
||||||
cd "${GITHUB_WORKSPACE}/release-assets"
|
cd "${GITHUB_WORKSPACE}/release-assets"
|
||||||
|
source_asset="pi-${VERSION}-source.tar.gz"
|
||||||
release_assets=(
|
release_assets=(
|
||||||
|
"${source_asset}"
|
||||||
pi-darwin-arm64.tar.gz
|
pi-darwin-arm64.tar.gz
|
||||||
pi-darwin-x64.tar.gz
|
pi-darwin-x64.tar.gz
|
||||||
pi-linux-x64.tar.gz
|
pi-linux-x64.tar.gz
|
||||||
@@ -125,7 +146,10 @@ jobs:
|
|||||||
|
|
||||||
cd release-assets
|
cd release-assets
|
||||||
|
|
||||||
|
VERSION="${RELEASE_TAG#v}"
|
||||||
|
source_asset="pi-${VERSION}-source.tar.gz"
|
||||||
expected_assets=(
|
expected_assets=(
|
||||||
|
"${source_asset}"
|
||||||
pi-darwin-arm64.tar.gz
|
pi-darwin-arm64.tar.gz
|
||||||
pi-darwin-x64.tar.gz
|
pi-darwin-x64.tar.gz
|
||||||
pi-linux-x64.tar.gz
|
pi-linux-x64.tar.gz
|
||||||
@@ -144,7 +168,7 @@ jobs:
|
|||||||
|
|
||||||
sha256sum -c SHA256SUMS
|
sha256sum -c SHA256SUMS
|
||||||
|
|
||||||
- name: Create draft GitHub Release and upload binaries
|
- name: Create draft GitHub Release and upload assets
|
||||||
env:
|
env:
|
||||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
run: |
|
run: |
|
||||||
@@ -152,7 +176,10 @@ jobs:
|
|||||||
|
|
||||||
cd release-assets
|
cd release-assets
|
||||||
|
|
||||||
|
VERSION="${RELEASE_TAG#v}"
|
||||||
|
source_asset="pi-${VERSION}-source.tar.gz"
|
||||||
release_assets=(
|
release_assets=(
|
||||||
|
"${source_asset}"
|
||||||
pi-darwin-arm64.tar.gz
|
pi-darwin-arm64.tar.gz
|
||||||
pi-darwin-x64.tar.gz
|
pi-darwin-x64.tar.gz
|
||||||
pi-linux-x64.tar.gz
|
pi-linux-x64.tar.gz
|
||||||
|
|||||||
@@ -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)
|
./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
|
## Supply-chain hardening
|
||||||
|
|
||||||
We treat npm dependency changes as reviewed code changes.
|
We treat npm dependency changes as reviewed code changes.
|
||||||
|
|||||||
Executable
+117
@@ -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"
|
||||||
Reference in New Issue
Block a user