forked from garrytan/gstack
-
Notifications
You must be signed in to change notification settings - Fork 0
205 lines (192 loc) · 9.14 KB
/
Copy pathrelease-artifacts.yml
File metadata and controls
205 lines (192 loc) · 9.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
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
- 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 \
--browser managed \
--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
smoke_url=$(node -e 'const fs=require("fs"),p=require("path").join(process.env.GITHUB_WORKSPACE,".gstack-runtime-smoke.html");fs.writeFileSync(p,"<!doctype html><title>GStack runtime smoke</title>\n");process.stdout.write(require("url").pathToFileURL(p).href)')
PATH="$clean_path" GSTACK_NODE="$node_command" BROWSE_PARENT_PID=0 \
"$GSTACK_HOME/bin/browse" goto "$smoke_url"
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"
# GNU tar treats a Windows drive colon in an archive path as a
# remote-host separator. Keep archive output in Git Bash's POSIX view.
release_dir="$(pwd -P)/release-output"
mkdir -p "$stage" "$release_dir"
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="$release_dir/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: 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: 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: 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. This release adds an explicit managed-versus-installed Chromium consent gate before browser preview or installation." \
release-output/*
shell: bash