mirror of
https://github.com/garrytan/gstack.git
synced 2026-09-21 04:10:47 +02:00
Publish signed prerelease artifacts from v2.0.0-rc.* tags, bind bootstrap trust to the immutable RC tag, make missing-release errors actionable, and install the six public skills from the canonical subpath.
203 lines
8.7 KiB
YAML
203 lines
8.7 KiB
YAML
name: Release runtime artifacts
|
|
|
|
on:
|
|
push:
|
|
tags:
|
|
- v2.0.0
|
|
- v2.0.0-rc.*
|
|
workflow_dispatch:
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
concurrency:
|
|
group: runtime-release-${{ github.ref }}
|
|
cancel-in-progress: false
|
|
|
|
jobs:
|
|
build:
|
|
name: Build ${{ matrix.target }}
|
|
permissions:
|
|
contents: read
|
|
id-token: write
|
|
attestations: write
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- os: macos-15
|
|
target: darwin-arm64
|
|
capabilities: browser,browser-visible,design,pdf,diagram,ios
|
|
- os: macos-15-intel
|
|
target: darwin-x64
|
|
capabilities: browser,browser-visible,design,pdf,diagram,ios
|
|
- os: ubuntu-24.04-arm
|
|
target: linux-arm64
|
|
capabilities: browser,browser-visible,design,pdf,diagram
|
|
- os: ubuntu-24.04
|
|
target: linux-x64
|
|
capabilities: browser,browser-visible,design,pdf,diagram
|
|
- os: windows-11-arm
|
|
target: windows-arm64
|
|
capabilities: browser,browser-visible,design,pdf,diagram
|
|
- os: windows-2025
|
|
target: windows-x64
|
|
capabilities: browser,browser-visible,design,pdf,diagram
|
|
runs-on: ${{ matrix.os }}
|
|
timeout-minutes: 35
|
|
steps:
|
|
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
|
|
with:
|
|
bun-version: 1.3.14
|
|
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
|
with:
|
|
node-version: 22.23.1
|
|
- uses: sigstore/cosign-installer@d7543c93d881b35a8faa02e8e3605f69b7a1ce62 # v3.10.0
|
|
|
|
- name: Install frozen dependencies
|
|
run: bun install --frozen-lockfile --ignore-scripts
|
|
shell: bash
|
|
|
|
- name: Build and stage the complete managed runtime
|
|
env:
|
|
GSTACK_HOME: ${{ runner.temp }}/gstack-release-home
|
|
TARGET: ${{ matrix.target }}
|
|
CAPABILITIES: ${{ matrix.capabilities }}
|
|
run: |
|
|
set -euo pipefail
|
|
node runtime/install.js \
|
|
--source "$GITHUB_WORKSPACE" \
|
|
--home "$GSTACK_HOME" \
|
|
--version 2.0.0 \
|
|
--install-now \
|
|
--yes \
|
|
--capabilities "$CAPABILITIES"
|
|
active_slot=$(node -e 'const fs=require("fs"),p=process.argv[1];const v=JSON.parse(fs.readFileSync(p,"utf8")).current;if(typeof v!=="string"||!/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/.test(v))process.exit(1);process.stdout.write(v)' "$GSTACK_HOME/versions/current.json")
|
|
active="$GSTACK_HOME/versions/$active_slot"
|
|
test -f "$active/.gstack-bundle.json"
|
|
case "$TARGET" in
|
|
windows-*) managed_bun_rel=".gstack-runtime-tools/bun.exe" ;;
|
|
*) managed_bun_rel=".gstack-runtime-tools/bun" ;;
|
|
esac
|
|
managed_bun="$active/$managed_bun_rel"
|
|
test -f "$managed_bun"
|
|
test "$("$managed_bun" --version)" = "1.3.14"
|
|
test -f "$active/runtime/licenses/BUN-LICENSE-1.3.14.md"
|
|
test -f "$active/runtime/licenses/BUN-SOURCE.md"
|
|
node -e 'const fs=require("fs"),c=require("crypto"),root=process.argv[1],rel=process.argv[2];const m=JSON.parse(fs.readFileSync(root+"/.gstack-bundle.json","utf8"));if(m.tools?.bun?.path!==rel||m.tools?.bun?.version!=="1.3.14")process.exit(1);const license=fs.readFileSync(root+"/runtime/licenses/BUN-LICENSE-1.3.14.md");if(c.createHash("sha256").update(license).digest("hex")!=="2cb858b2db8fc793bca2093489c5bc8eee615d002cc4924254904044c27a0afa")process.exit(1)' "$active" "$managed_bun_rel"
|
|
test -d "$active/.gstack-runtime-browsers"
|
|
(
|
|
cd "$active"
|
|
PLAYWRIGHT_BROWSERS_PATH="$active/.gstack-runtime-browsers" \
|
|
node --input-type=module --eval \
|
|
'const { chromium } = await import("./node_modules/playwright/index.mjs"); for (const options of [{ headless: true }, { headless: true, channel: "chromium" }]) { const browser = await chromium.launch(options); await browser.close(); }'
|
|
)
|
|
node_command=$(node -p 'process.execPath')
|
|
host_bun=$(command -v bun)
|
|
host_bun_dir=$(cd "$(dirname "$host_bun")" && pwd -P)
|
|
clean_path=""
|
|
IFS=: read -r -a path_parts <<< "$PATH"
|
|
for part in "${path_parts[@]}"; do
|
|
physical=$(cd "$part" 2>/dev/null && pwd -P || printf '%s' "$part")
|
|
if [ "$physical" != "$host_bun_dir" ]; then
|
|
clean_path="${clean_path:+$clean_path:}$part"
|
|
fi
|
|
done
|
|
if (PATH="$clean_path"; command -v bun >/dev/null 2>&1); then
|
|
echo "Host-global Bun remained available after removing setup-bun from PATH" >&2
|
|
exit 1
|
|
fi
|
|
test "$(PATH="$clean_path" GSTACK_NODE="$node_command" "$GSTACK_HOME/bin/bun" --version)" = "1.3.14"
|
|
browser_cleanup() {
|
|
PATH="$clean_path" GSTACK_NODE="$node_command" BROWSE_PARENT_PID=0 \
|
|
"$GSTACK_HOME/bin/browse" stop >/dev/null 2>&1 || true
|
|
}
|
|
trap browser_cleanup EXIT
|
|
PATH="$clean_path" GSTACK_NODE="$node_command" BROWSE_PARENT_PID=0 \
|
|
"$GSTACK_HOME/bin/browse" goto about:blank
|
|
PATH="$clean_path" GSTACK_NODE="$node_command" BROWSE_PARENT_PID=0 \
|
|
"$GSTACK_HOME/bin/browse" status
|
|
browser_cleanup
|
|
trap - EXIT
|
|
stage="$RUNNER_TEMP/runtime-components"
|
|
mkdir -p "$stage" "$GITHUB_WORKSPACE/release-output"
|
|
node .github/scripts/stage-runtime-components.mjs "$active" "$stage"
|
|
for component_dir in "$stage"/*; do
|
|
test -d "$component_dir" || continue
|
|
component=$(basename "$component_dir")
|
|
archive="$GITHUB_WORKSPACE/release-output/gstack-runtime-2.0.0-$TARGET-$component.tar.gz"
|
|
tar -czf "$archive" -C "$component_dir" gstack
|
|
node -e 'const fs=require("fs"),c=require("crypto"),p=process.argv[1];const b=fs.readFileSync(p);fs.writeFileSync(p+".sha256",c.createHash("sha256").update(b).digest("hex")+" "+require("path").basename(p)+"\n")' "$archive"
|
|
done
|
|
shell: bash
|
|
|
|
- name: Keyless-sign component archives
|
|
run: |
|
|
set -euo pipefail
|
|
for archive in release-output/*.tar.gz; do
|
|
cosign sign-blob --yes --bundle "$archive.sigstore.json" "$archive"
|
|
done
|
|
shell: bash
|
|
|
|
- name: Attest component archive provenance
|
|
uses: actions/attest-build-provenance@e8998f949152b193b063cb0ec769d69d929409be # v2
|
|
with:
|
|
subject-path: release-output/*.tar.gz
|
|
|
|
- name: Upload signed archive
|
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
|
with:
|
|
name: runtime-${{ matrix.target }}
|
|
path: release-output/*
|
|
if-no-files-found: error
|
|
retention-days: 14
|
|
|
|
manifest:
|
|
name: Assemble manifest and GitHub Release
|
|
needs: build
|
|
runs-on: ubuntu-24.04
|
|
if: startsWith(github.ref, 'refs/tags/v')
|
|
permissions:
|
|
contents: write
|
|
id-token: write
|
|
attestations: write
|
|
steps:
|
|
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
|
with:
|
|
pattern: runtime-*
|
|
path: release-output
|
|
merge-multiple: true
|
|
- uses: sigstore/cosign-installer@d7543c93d881b35a8faa02e8e3605f69b7a1ce62 # v3.10.0
|
|
|
|
- name: Create strict six-target manifest
|
|
run: node .github/scripts/create-runtime-release-manifest.mjs release-output "$GITHUB_REPOSITORY" 2.0.0 "$GITHUB_REF_NAME"
|
|
|
|
- name: Checksum and keyless-sign manifest
|
|
run: |
|
|
set -euo pipefail
|
|
cd release-output
|
|
sha256sum gstack-runtime-manifest.json > gstack-runtime-manifest.json.sha256
|
|
cosign sign-blob --yes --bundle gstack-runtime-manifest.json.sigstore.json gstack-runtime-manifest.json
|
|
shell: bash
|
|
|
|
- name: Attest manifest provenance
|
|
uses: actions/attest-build-provenance@e8998f949152b193b063cb0ec769d69d929409be # v2
|
|
with:
|
|
subject-path: release-output/gstack-runtime-manifest.json
|
|
|
|
- name: Publish immutable release assets
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
PRERELEASE_FLAG: ${{ contains(github.ref_name, '-rc.') && '--prerelease' || '' }}
|
|
run: |
|
|
set -euo pipefail
|
|
gh release create "$GITHUB_REF_NAME" \
|
|
--verify-tag \
|
|
$PRERELEASE_FLAG \
|
|
--title "GStack runtime $GITHUB_REF_NAME" \
|
|
--notes "Signed optional runtime artifacts for the six portable GStack skills." \
|
|
release-output/*
|
|
shell: bash
|