Skip to content

Commit b88fdce

Browse files
committed
fix(desktop): harden bundle update safety and release gates
Make bundle activation fail closed across migration, rollback, and cohort transitions. Bind health and activity gates to the exact sidecar runtime. Harden full and hot releases against replay and partial publication.
1 parent e1c6975 commit b88fdce

44 files changed

Lines changed: 5134 additions & 1086 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
name: Bundle Hot Update Checks
2+
3+
on:
4+
pull_request:
5+
paths:
6+
- ".github/workflows/bundle-hot-*.yml"
7+
- ".github/workflows/electron-release.yml"
8+
- "apps/workspace/bundle-update.json"
9+
- "apps/workspace/electron/**"
10+
- "apps/workspace/scripts/**"
11+
- "apps/workspace/src/**"
12+
- "apps/workspace/package.json"
13+
- "pnpm-lock.yaml"
14+
- "Taskfile.yml"
15+
- "scripts/build-server-target.mjs"
16+
- "scripts/sync-workspace-dist.mjs"
17+
- "docs/hot-update-architecture.md"
18+
- "packages/vendor/**"
19+
- "services/server/**"
20+
push:
21+
branches:
22+
- dev
23+
paths:
24+
- ".github/workflows/bundle-hot-*.yml"
25+
- ".github/workflows/electron-release.yml"
26+
- "apps/workspace/bundle-update.json"
27+
- "apps/workspace/electron/**"
28+
- "apps/workspace/scripts/**"
29+
- "apps/workspace/src/**"
30+
- "apps/workspace/package.json"
31+
- "pnpm-lock.yaml"
32+
- "Taskfile.yml"
33+
- "scripts/build-server-target.mjs"
34+
- "scripts/sync-workspace-dist.mjs"
35+
- "docs/hot-update-architecture.md"
36+
- "packages/vendor/**"
37+
- "services/server/**"
38+
39+
permissions:
40+
contents: read
41+
42+
env:
43+
HUSKY: "0"
44+
NODE_VERSION: "24"
45+
PNPM_VERSION: "11.9.0"
46+
47+
jobs:
48+
checks:
49+
name: Bundle safety and reproducibility
50+
runs-on: ubuntu-latest
51+
steps:
52+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
53+
with:
54+
fetch-depth: 0
55+
56+
- uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6
57+
with:
58+
version: ${{ env.PNPM_VERSION }}
59+
60+
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
61+
with:
62+
node-version: ${{ env.NODE_VERSION }}
63+
cache: pnpm
64+
cache-dependency-path: pnpm-lock.yaml
65+
66+
- uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6
67+
with:
68+
go-version-file: go.work
69+
cache-dependency-path: |
70+
go.work.sum
71+
**/go.sum
72+
73+
- name: Install dependencies
74+
run: pnpm install --frozen-lockfile
75+
76+
- name: Format and lint hot-update sources
77+
working-directory: apps/workspace
78+
run: |
79+
pnpm exec oxfmt --check electron/src scripts/package-bundle-update.ts scripts/hot-update-local-test.ts scripts/stage-electron-app.ts scripts/check-bundle-version-bumps.mjs
80+
pnpm exec oxlint electron/src scripts/package-bundle-update.ts scripts/hot-update-local-test.ts scripts/stage-electron-app.ts scripts/check-bundle-version-bumps.mjs
81+
82+
- name: Require schema and workspace-layout version bumps
83+
env:
84+
BASE_SHA: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event.before }}
85+
run: node apps/workspace/scripts/check-bundle-version-bumps.mjs "$BASE_SHA"
86+
87+
- name: Compile Electron and run state-machine tests
88+
run: |
89+
pnpm --dir apps/workspace electron:compile
90+
pnpm --dir apps/workspace exec vitest run electron/src
91+
92+
- name: Build renderer
93+
env:
94+
VITE_ELECTRON_BUILD: "1"
95+
VITE_MEDIAGO_EDITION: community
96+
VITE_MEDIAGO_SERVER_PORT: "48273"
97+
run: pnpm --dir apps/workspace build
98+
99+
- name: Package determinism smoke test
100+
shell: bash
101+
run: |
102+
set -euo pipefail
103+
private_key="$(node -e 'const {generateKeyPairSync}=require("node:crypto"); const {privateKey}=generateKeyPairSync("ed25519"); process.stdout.write(privateKey.export({format:"der",type:"pkcs8"}).toString("base64"))')"
104+
export RENDERER_UPDATE_PRIVATE_KEY="$private_key"
105+
export RENDERER_UPDATE_EXPECTED_PUBLIC_KEY="$(PRIVATE_KEY="$private_key" node -e 'const {createPrivateKey,createPublicKey}=require("node:crypto"); const key=createPrivateKey({key:Buffer.from(process.env.PRIVATE_KEY,"base64"),format:"der",type:"pkcs8"}); process.stdout.write(createPublicKey(key).export({format:"der",type:"spki"}).toString("base64"))')"
106+
export RENDERER_UPDATE_CHANNEL="beta"
107+
export RENDERER_UPDATE_EDITION="community"
108+
export MEDIAGO_BUNDLE_SCHEMA_VERSION="$(node -p 'JSON.parse(require("node:fs").readFileSync("apps/workspace/bundle-update.json", "utf8")).schemaVersion')"
109+
export MEDIAGO_BUNDLE_WORKSPACE_LAYOUT_VERSION="$(node -p 'JSON.parse(require("node:fs").readFileSync("apps/workspace/bundle-update.json", "utf8")).workspaceLayoutVersion')"
110+
export MEDIAGO_SERVER_BINARY_DARWIN_ARM64="/bin/true"
111+
export MEDIAGO_SERVER_BINARY_WINDOWS_X64="/bin/true"
112+
113+
node apps/workspace/scripts/package-bundle-update.ts
114+
find apps/workspace/release/bundle -type f -print0 | sort -z | xargs -0 sha256sum > "$RUNNER_TEMP/first.sha256"
115+
node apps/workspace/scripts/package-bundle-update.ts
116+
find apps/workspace/release/bundle -type f -print0 | sort -z | xargs -0 sha256sum > "$RUNNER_TEMP/second.sha256"
117+
diff -u "$RUNNER_TEMP/first.sha256" "$RUNNER_TEMP/second.sha256"
118+
119+
- name: Go server race tests
120+
working-directory: services/server
121+
run: go test -race ./...

0 commit comments

Comments
 (0)