mirror of
https://github.com/garrytan/gstack.git
synced 2026-09-21 12:20:48 +02:00
fix: make runtime release six-platform safe
Use an allowed local file URL for the browser smoke test, centralize keyless archive signing after native builds so Windows ARM64 does not require an unavailable Cosign binary, and advance the immutable bootstrap channel to RC2.
This commit is contained in:
@@ -53,8 +53,6 @@ jobs:
|
|||||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||||
with:
|
with:
|
||||||
node-version: 22.23.1
|
node-version: 22.23.1
|
||||||
- uses: sigstore/cosign-installer@d7543c93d881b35a8faa02e8e3605f69b7a1ce62 # v3.10.0
|
|
||||||
|
|
||||||
- name: Install frozen dependencies
|
- name: Install frozen dependencies
|
||||||
run: bun install --frozen-lockfile --ignore-scripts
|
run: bun install --frozen-lockfile --ignore-scripts
|
||||||
shell: bash
|
shell: bash
|
||||||
@@ -114,8 +112,9 @@ jobs:
|
|||||||
"$GSTACK_HOME/bin/browse" stop >/dev/null 2>&1 || true
|
"$GSTACK_HOME/bin/browse" stop >/dev/null 2>&1 || true
|
||||||
}
|
}
|
||||||
trap browser_cleanup EXIT
|
trap browser_cleanup EXIT
|
||||||
|
smoke_url=$(node -e 'const fs=require("fs"),p=require("path").join(process.env.RUNNER_TEMP,"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 \
|
PATH="$clean_path" GSTACK_NODE="$node_command" BROWSE_PARENT_PID=0 \
|
||||||
"$GSTACK_HOME/bin/browse" goto about:blank
|
"$GSTACK_HOME/bin/browse" goto "$smoke_url"
|
||||||
PATH="$clean_path" GSTACK_NODE="$node_command" BROWSE_PARENT_PID=0 \
|
PATH="$clean_path" GSTACK_NODE="$node_command" BROWSE_PARENT_PID=0 \
|
||||||
"$GSTACK_HOME/bin/browse" status
|
"$GSTACK_HOME/bin/browse" status
|
||||||
browser_cleanup
|
browser_cleanup
|
||||||
@@ -132,14 +131,6 @@ jobs:
|
|||||||
done
|
done
|
||||||
shell: bash
|
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
|
- name: Attest component archive provenance
|
||||||
uses: actions/attest-build-provenance@e8998f949152b193b063cb0ec769d69d929409be # v2
|
uses: actions/attest-build-provenance@e8998f949152b193b063cb0ec769d69d929409be # v2
|
||||||
with:
|
with:
|
||||||
@@ -171,6 +162,14 @@ jobs:
|
|||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
- uses: sigstore/cosign-installer@d7543c93d881b35a8faa02e8e3605f69b7a1ce62 # v3.10.0
|
- 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
|
- 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"
|
run: node .github/scripts/create-runtime-release-manifest.mjs release-output "$GITHUB_REPOSITORY" 2.0.0 "$GITHUB_REF_NAME"
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export const BOOTSTRAP_RUNTIME_VERSION = "2.0.0";
|
|||||||
// Keep the runtime compatibility version separate from the immutable release
|
// Keep the runtime compatibility version separate from the immutable release
|
||||||
// channel. Release candidates carry the 2.0.0 runtime contract while letting
|
// channel. Release candidates carry the 2.0.0 runtime contract while letting
|
||||||
// fresh-machine production journeys run before the stable v2.0.0 tag exists.
|
// fresh-machine production journeys run before the stable v2.0.0 tag exists.
|
||||||
export const BOOTSTRAP_RELEASE_TAG = "v2.0.0-rc.1";
|
export const BOOTSTRAP_RELEASE_TAG = "v2.0.0-rc.2";
|
||||||
export const OFFICIAL_MANIFEST_URL =
|
export const OFFICIAL_MANIFEST_URL =
|
||||||
`https://github.com/time-attack/gstack/releases/download/${BOOTSTRAP_RELEASE_TAG}/gstack-runtime-manifest.json`;
|
`https://github.com/time-attack/gstack/releases/download/${BOOTSTRAP_RELEASE_TAG}/gstack-runtime-manifest.json`;
|
||||||
const CAPABILITIES = new Set(["browser", "browser-visible", "design", "pdf", "diagram", "ios"]);
|
const CAPABILITIES = new Set(["browser", "browser-visible", "design", "pdf", "diagram", "ios"]);
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export const BOOTSTRAP_RUNTIME_VERSION = "2.0.0";
|
|||||||
// Keep the runtime compatibility version separate from the immutable release
|
// Keep the runtime compatibility version separate from the immutable release
|
||||||
// channel. Release candidates carry the 2.0.0 runtime contract while letting
|
// channel. Release candidates carry the 2.0.0 runtime contract while letting
|
||||||
// fresh-machine production journeys run before the stable v2.0.0 tag exists.
|
// fresh-machine production journeys run before the stable v2.0.0 tag exists.
|
||||||
export const BOOTSTRAP_RELEASE_TAG = "v2.0.0-rc.1";
|
export const BOOTSTRAP_RELEASE_TAG = "v2.0.0-rc.2";
|
||||||
export const OFFICIAL_MANIFEST_URL =
|
export const OFFICIAL_MANIFEST_URL =
|
||||||
`https://github.com/time-attack/gstack/releases/download/${BOOTSTRAP_RELEASE_TAG}/gstack-runtime-manifest.json`;
|
`https://github.com/time-attack/gstack/releases/download/${BOOTSTRAP_RELEASE_TAG}/gstack-runtime-manifest.json`;
|
||||||
const CAPABILITIES = new Set(["browser", "browser-visible", "design", "pdf", "diagram", "ios"]);
|
const CAPABILITIES = new Set(["browser", "browser-visible", "design", "pdf", "diagram", "ios"]);
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export const BOOTSTRAP_RUNTIME_VERSION = "2.0.0";
|
|||||||
// Keep the runtime compatibility version separate from the immutable release
|
// Keep the runtime compatibility version separate from the immutable release
|
||||||
// channel. Release candidates carry the 2.0.0 runtime contract while letting
|
// channel. Release candidates carry the 2.0.0 runtime contract while letting
|
||||||
// fresh-machine production journeys run before the stable v2.0.0 tag exists.
|
// fresh-machine production journeys run before the stable v2.0.0 tag exists.
|
||||||
export const BOOTSTRAP_RELEASE_TAG = "v2.0.0-rc.1";
|
export const BOOTSTRAP_RELEASE_TAG = "v2.0.0-rc.2";
|
||||||
export const OFFICIAL_MANIFEST_URL =
|
export const OFFICIAL_MANIFEST_URL =
|
||||||
`https://github.com/time-attack/gstack/releases/download/${BOOTSTRAP_RELEASE_TAG}/gstack-runtime-manifest.json`;
|
`https://github.com/time-attack/gstack/releases/download/${BOOTSTRAP_RELEASE_TAG}/gstack-runtime-manifest.json`;
|
||||||
const CAPABILITIES = new Set(["browser", "browser-visible", "design", "pdf", "diagram", "ios"]);
|
const CAPABILITIES = new Set(["browser", "browser-visible", "design", "pdf", "diagram", "ios"]);
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export const BOOTSTRAP_RUNTIME_VERSION = "2.0.0";
|
|||||||
// Keep the runtime compatibility version separate from the immutable release
|
// Keep the runtime compatibility version separate from the immutable release
|
||||||
// channel. Release candidates carry the 2.0.0 runtime contract while letting
|
// channel. Release candidates carry the 2.0.0 runtime contract while letting
|
||||||
// fresh-machine production journeys run before the stable v2.0.0 tag exists.
|
// fresh-machine production journeys run before the stable v2.0.0 tag exists.
|
||||||
export const BOOTSTRAP_RELEASE_TAG = "v2.0.0-rc.1";
|
export const BOOTSTRAP_RELEASE_TAG = "v2.0.0-rc.2";
|
||||||
export const OFFICIAL_MANIFEST_URL =
|
export const OFFICIAL_MANIFEST_URL =
|
||||||
`https://github.com/time-attack/gstack/releases/download/${BOOTSTRAP_RELEASE_TAG}/gstack-runtime-manifest.json`;
|
`https://github.com/time-attack/gstack/releases/download/${BOOTSTRAP_RELEASE_TAG}/gstack-runtime-manifest.json`;
|
||||||
const CAPABILITIES = new Set(["browser", "browser-visible", "design", "pdf", "diagram", "ios"]);
|
const CAPABILITIES = new Set(["browser", "browser-visible", "design", "pdf", "diagram", "ios"]);
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export const BOOTSTRAP_RUNTIME_VERSION = "2.0.0";
|
|||||||
// Keep the runtime compatibility version separate from the immutable release
|
// Keep the runtime compatibility version separate from the immutable release
|
||||||
// channel. Release candidates carry the 2.0.0 runtime contract while letting
|
// channel. Release candidates carry the 2.0.0 runtime contract while letting
|
||||||
// fresh-machine production journeys run before the stable v2.0.0 tag exists.
|
// fresh-machine production journeys run before the stable v2.0.0 tag exists.
|
||||||
export const BOOTSTRAP_RELEASE_TAG = "v2.0.0-rc.1";
|
export const BOOTSTRAP_RELEASE_TAG = "v2.0.0-rc.2";
|
||||||
export const OFFICIAL_MANIFEST_URL =
|
export const OFFICIAL_MANIFEST_URL =
|
||||||
`https://github.com/time-attack/gstack/releases/download/${BOOTSTRAP_RELEASE_TAG}/gstack-runtime-manifest.json`;
|
`https://github.com/time-attack/gstack/releases/download/${BOOTSTRAP_RELEASE_TAG}/gstack-runtime-manifest.json`;
|
||||||
const CAPABILITIES = new Set(["browser", "browser-visible", "design", "pdf", "diagram", "ios"]);
|
const CAPABILITIES = new Set(["browser", "browser-visible", "design", "pdf", "diagram", "ios"]);
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export const BOOTSTRAP_RUNTIME_VERSION = "2.0.0";
|
|||||||
// Keep the runtime compatibility version separate from the immutable release
|
// Keep the runtime compatibility version separate from the immutable release
|
||||||
// channel. Release candidates carry the 2.0.0 runtime contract while letting
|
// channel. Release candidates carry the 2.0.0 runtime contract while letting
|
||||||
// fresh-machine production journeys run before the stable v2.0.0 tag exists.
|
// fresh-machine production journeys run before the stable v2.0.0 tag exists.
|
||||||
export const BOOTSTRAP_RELEASE_TAG = "v2.0.0-rc.1";
|
export const BOOTSTRAP_RELEASE_TAG = "v2.0.0-rc.2";
|
||||||
export const OFFICIAL_MANIFEST_URL =
|
export const OFFICIAL_MANIFEST_URL =
|
||||||
`https://github.com/time-attack/gstack/releases/download/${BOOTSTRAP_RELEASE_TAG}/gstack-runtime-manifest.json`;
|
`https://github.com/time-attack/gstack/releases/download/${BOOTSTRAP_RELEASE_TAG}/gstack-runtime-manifest.json`;
|
||||||
const CAPABILITIES = new Set(["browser", "browser-visible", "design", "pdf", "diagram", "ios"]);
|
const CAPABILITIES = new Set(["browser", "browser-visible", "design", "pdf", "diagram", "ios"]);
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export const BOOTSTRAP_RUNTIME_VERSION = "2.0.0";
|
|||||||
// Keep the runtime compatibility version separate from the immutable release
|
// Keep the runtime compatibility version separate from the immutable release
|
||||||
// channel. Release candidates carry the 2.0.0 runtime contract while letting
|
// channel. Release candidates carry the 2.0.0 runtime contract while letting
|
||||||
// fresh-machine production journeys run before the stable v2.0.0 tag exists.
|
// fresh-machine production journeys run before the stable v2.0.0 tag exists.
|
||||||
export const BOOTSTRAP_RELEASE_TAG = "v2.0.0-rc.1";
|
export const BOOTSTRAP_RELEASE_TAG = "v2.0.0-rc.2";
|
||||||
export const OFFICIAL_MANIFEST_URL =
|
export const OFFICIAL_MANIFEST_URL =
|
||||||
`https://github.com/time-attack/gstack/releases/download/${BOOTSTRAP_RELEASE_TAG}/gstack-runtime-manifest.json`;
|
`https://github.com/time-attack/gstack/releases/download/${BOOTSTRAP_RELEASE_TAG}/gstack-runtime-manifest.json`;
|
||||||
const CAPABILITIES = new Set(["browser", "browser-visible", "design", "pdf", "diagram", "ios"]);
|
const CAPABILITIES = new Set(["browser", "browser-visible", "design", "pdf", "diagram", "ios"]);
|
||||||
|
|||||||
@@ -57,10 +57,18 @@ describe("GStack runtime release channel", () => {
|
|||||||
|
|
||||||
test("release workflow publishes both RC and stable tags through the same signed manifest path", async () => {
|
test("release workflow publishes both RC and stable tags through the same signed manifest path", async () => {
|
||||||
const workflow = await fs.readFile(WORKFLOW, "utf8");
|
const workflow = await fs.readFile(WORKFLOW, "utf8");
|
||||||
|
const buildSection = workflow.slice(workflow.indexOf(" build:"), workflow.indexOf("\n manifest:"));
|
||||||
|
const manifestSection = workflow.slice(workflow.indexOf("\n manifest:"));
|
||||||
expect(workflow).toContain("v2.0.0-rc.*");
|
expect(workflow).toContain("v2.0.0-rc.*");
|
||||||
expect(workflow).toContain('2.0.0 "$GITHUB_REF_NAME"');
|
expect(workflow).toContain('2.0.0 "$GITHUB_REF_NAME"');
|
||||||
expect(workflow).toContain("PRERELEASE_FLAG:");
|
expect(workflow).toContain("PRERELEASE_FLAG:");
|
||||||
expect(workflow).toContain("--prerelease");
|
expect(workflow).toContain("--prerelease");
|
||||||
expect(workflow).toContain('gh release create "$GITHUB_REF_NAME"');
|
expect(workflow).toContain('gh release create "$GITHUB_REF_NAME"');
|
||||||
|
expect(workflow).toContain("pathToFileURL(p).href");
|
||||||
|
expect(workflow).not.toContain("goto about:blank");
|
||||||
|
expect(buildSection).not.toContain("sigstore/cosign-installer");
|
||||||
|
expect(manifestSection).toContain("sigstore/cosign-installer");
|
||||||
|
expect(manifestSection.indexOf("Keyless-sign component archives"))
|
||||||
|
.toBeLessThan(manifestSection.indexOf("Create strict six-target manifest"));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -53,14 +53,20 @@ describe("release and CI hardening", () => {
|
|||||||
expect(workflow).toContain("versions/current.json");
|
expect(workflow).toContain("versions/current.json");
|
||||||
expect(workflow).not.toContain('active="$GSTACK_HOME/versions/2.0.0"');
|
expect(workflow).not.toContain('active="$GSTACK_HOME/versions/2.0.0"');
|
||||||
expect(workflow).toContain(".gstack-runtime-browsers");
|
expect(workflow).toContain(".gstack-runtime-browsers");
|
||||||
expect(workflow).toContain('chromium.launch({ headless: true, channel: "chromium" })');
|
// Exercise both the bundled browser and the explicit Chromium channel. Keep
|
||||||
|
// this semantic: the workflow intentionally loops over launch options so a
|
||||||
|
// harmless refactor does not invalidate release hardening.
|
||||||
|
expect(workflow).toMatch(/for \(const options of \[\{ headless: true \}, \{ headless: true, channel: ["']chromium["'] \}\]\)/);
|
||||||
|
expect(workflow).toContain("chromium.launch(options)");
|
||||||
|
expect(workflow).toContain("await browser.close()");
|
||||||
expect(workflow).not.toContain("--with-deps");
|
expect(workflow).not.toContain("--with-deps");
|
||||||
expect(workflow).toContain(".gstack-runtime-tools/bun");
|
expect(workflow).toContain(".gstack-runtime-tools/bun");
|
||||||
expect(workflow).toContain('"$GSTACK_HOME/bin/bun" --version');
|
expect(workflow).toContain('"$GSTACK_HOME/bin/bun" --version');
|
||||||
expect(workflow).toContain("BUN-LICENSE-1.3.14.md");
|
expect(workflow).toContain("BUN-LICENSE-1.3.14.md");
|
||||||
expect(workflow).toContain("command -v bun");
|
expect(workflow).toContain("command -v bun");
|
||||||
expect(workflow).toContain("GSTACK_NODE=\"$node_command\"");
|
expect(workflow).toContain("GSTACK_NODE=\"$node_command\"");
|
||||||
expect(workflow).toContain("goto about:blank");
|
expect(workflow).toContain("pathToFileURL(p).href");
|
||||||
|
expect(workflow).not.toContain("goto about:blank");
|
||||||
const manifest = read(".github/scripts/create-runtime-release-manifest.mjs");
|
const manifest = read(".github/scripts/create-runtime-release-manifest.mjs");
|
||||||
expect(manifest).toContain("bytes: stat.size");
|
expect(manifest).toContain("bytes: stat.size");
|
||||||
expect(manifest).toContain('certificateOidcIssuer: "https://token.actions.githubusercontent.com"');
|
expect(manifest).toContain('certificateOidcIssuer: "https://token.actions.githubusercontent.com"');
|
||||||
@@ -80,7 +86,8 @@ describe("release and CI hardening", () => {
|
|||||||
expect(installer).toContain('entry(managedBunRelativePath(), "managed-bun", true)');
|
expect(installer).toContain('entry(managedBunRelativePath(), "managed-bun", true)');
|
||||||
const browser = read("browse/src/cli.ts");
|
const browser = read("browse/src/cli.ts");
|
||||||
expect(browser).toContain("Every installed/compiled client must use the adjacent Node-compatible daemon");
|
expect(browser).toContain("Every installed/compiled client must use the adjacent Node-compatible daemon");
|
||||||
expect(browser).toContain("if (IS_COMPILED && !NODE_SERVER_SCRIPT)");
|
expect(browser).toContain("export function resolveServerLaunchTarget(");
|
||||||
|
expect(browser).toContain("server-node.mjs not found. Rebuild the managed browser runtime");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Windows setup lane installs, doctors, and uninstalls rather than only building", () => {
|
test("Windows setup lane installs, doctors, and uninstalls rather than only building", () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user