Skip to content

Commit 27a30c5

Browse files
authored
Harden provider UX and test git-smoke paths (#127)
* Centralize provider status copy and setup guidance - Extract shared provider status presentation helpers - Reuse headings, descriptions, and setup phase labels across chat UI - Add tests for phase classification and auth-specific copy * Pin Effect smol deps and fix custom theme parsing - Add the shared Effect catalog override - Merge theme vars directly when parsing Tweakcn JSON - Remove an unused theme dialog import * Disable Git signing in tests and harden theme root access - Force `commit.gpgsign=false` in Git test helpers and fixtures - Make theme application tolerate missing DOM root targets * Resolve Electron binary in desktop smoke test - Load Electron via `require("electron")` instead of a fixed `node_modules` path - Fail fast with a clear error if the smoke test cannot launch Electron * Add desktop release smoke test script - Add a `release-smoke` script for the desktop app - Expose a root `test:desktop-release-smoke` turbo command - Register the new task in desktop turbo config * Add marketing Turbo config and remove probe scripts - Add a Turbo config for the marketing app's persistent preview task - Drop obsolete Claude probe scripts from `scripts/package.json` * Require signed desktop release artifacts - Fail macOS release builds closed unless signing is enabled - Add `--require-signed` to desktop artifact builder and document release behavior
1 parent f917cfd commit 27a30c5

8 files changed

Lines changed: 52 additions & 9 deletions

File tree

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ jobs:
208208
printf '%s' "$APPLE_API_KEY" > "$key_path"
209209
export APPLE_API_KEY="$key_path"
210210
echo "macOS signing + notarization enabled."
211-
args+=(--signed)
211+
args+=(--signed --require-signed)
212212
elif [[ "${{ matrix.platform }}" == "win" ]]; then
213213
if has_all \
214214
"$AZURE_TENANT_ID" \

apps/desktop/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
"start": "bun run scripts/start-electron.mjs",
1212
"typecheck": "tsc --noEmit",
1313
"test": "vitest run --passWithNoTests",
14-
"smoke-test": "node scripts/smoke-test.mjs"
14+
"smoke-test": "node scripts/smoke-test.mjs",
15+
"release-smoke": "node ../../scripts/release-smoke.ts"
1516
},
1617
"dependencies": {
1718
"effect": "catalog:",

apps/desktop/turbo.jsonc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,9 @@
2020
"cache": false,
2121
"outputs": [],
2222
},
23+
"release-smoke": {
24+
"cache": false,
25+
"outputs": [],
26+
},
2327
},
2428
}

apps/marketing/turbo.jsonc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"$schema": "https://turbo.build/schema.json",
3+
"extends": ["//"],
4+
"tasks": {
5+
"preview": {
6+
"dependsOn": ["build"],
7+
"cache": false,
8+
"persistent": true,
9+
},
10+
},
11+
}

docs/release.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Canonical release process documentation for the OK Code project.
44

5-
**Last updated:** 2026-03-27
5+
**Last updated:** 2026-03-31
66

77
---
88

@@ -32,7 +32,7 @@ A release of OK Code produces:
3232

3333
The **`okcodes` CLI npm package** is **not** published by CI; publish it manually when needed (see [npm publishing (CLI, manual)](#npm-publishing-cli-manual)).
3434

35-
Releases follow Semantic Versioning and are triggered either by pushing a version tag (`v*.*.*`) or by manual workflow dispatch. Code signing is automatic when the required secrets are configured and is gracefully skipped otherwise.
35+
Releases follow Semantic Versioning and are triggered either by pushing a version tag (`v*.*.*`) or by manual workflow dispatch. macOS release builds fail closed unless signing and notarization are enabled. Windows signing is used when Azure Trusted Signing secrets are configured, and Linux AppImage builds remain unsigned.
3636

3737
---
3838

@@ -272,7 +272,7 @@ To validate the release pipeline without shipping a real version:
272272
1. Create a test prerelease tag: `git tag v0.0.0-test.1`
273273
2. Push it: `git push origin v0.0.0-test.1`
274274
3. Wait for the workflow to complete.
275-
4. Verify the GitHub prerelease contains all platform artifacts.
275+
4. Verify the GitHub prerelease contains all expected platform artifacts.
276276
5. Delete the prerelease and tag when done.
277277

278278
---
@@ -309,9 +309,9 @@ The release workflow (`.github/workflows/release.yml`) runs five jobs:
309309
- Runs in parallel across platforms with `fail-fast: false` (one platform failing does not cancel others).
310310
- Aligns all workspace `package.json` versions to the release version via `scripts/update-release-package-versions.ts`.
311311
- Invokes `bun run dist:desktop:artifact` with `--platform`, `--target`, `--arch`, and `--build-version` flags.
312-
- Detects signing secrets per platform and passes `--signed` when all required secrets are present:
312+
- Requires signing only for macOS release artifacts and fails the job if the Apple signing secrets are incomplete:
313313
- **macOS:** Writes `APPLE_API_KEY` to a temporary `.p8` file at `$RUNNER_TEMP`.
314-
- **Windows:** Uses Azure Trusted Signing via environment variables.
314+
- **Windows:** Uses Azure Trusted Signing via environment variables when configured.
315315
- **Linux:** No code signing.
316316
- Collects release assets (`.dmg`, `.zip`, `.AppImage`, `.exe`, `.blockmap`, `latest*.yml`) into `release-publish/`.
317317
- Renames `latest-mac.yml` to `latest-mac-x64.yml` for the non-arm64 macOS build (prevents collision before merging).

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
"lint": "oxlint --report-unused-disable-directives",
4040
"test": "turbo run test",
4141
"test:desktop-smoke": "turbo run smoke-test --filter=@okcode/desktop",
42+
"test:desktop-release-smoke": "turbo run release-smoke --filter=@okcode/desktop",
4243
"fmt": "oxfmt",
4344
"fmt:check": "oxfmt --check",
4445
"build:contracts": "turbo run build --filter=@okcode/contracts",

scripts/build-desktop-artifact.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ interface BuildCliInput {
7373
readonly skipBuild: Option.Option<boolean>;
7474
readonly keepStage: Option.Option<boolean>;
7575
readonly signed: Option.Option<boolean>;
76+
readonly requireSigned: Option.Option<boolean>;
7677
readonly verbose: Option.Option<boolean>;
7778
}
7879

@@ -161,6 +162,7 @@ interface ResolvedBuildOptions {
161162
readonly skipBuild: boolean;
162163
readonly keepStage: boolean;
163164
readonly signed: boolean;
165+
readonly requireSigned: boolean;
164166
readonly verbose: boolean;
165167
}
166168

@@ -203,9 +205,14 @@ const BuildEnvConfig = Config.all({
203205
skipBuild: Config.boolean("OKCODE_DESKTOP_SKIP_BUILD").pipe(Config.withDefault(false)),
204206
keepStage: Config.boolean("OKCODE_DESKTOP_KEEP_STAGE").pipe(Config.withDefault(false)),
205207
signed: Config.boolean("OKCODE_DESKTOP_SIGNED").pipe(Config.withDefault(false)),
208+
requireSigned: Config.boolean("OKCODE_DESKTOP_REQUIRE_SIGNED").pipe(Config.withDefault(false)),
206209
verbose: Config.boolean("OKCODE_DESKTOP_VERBOSE").pipe(Config.withDefault(false)),
207210
});
208211

212+
function supportsReleaseSigning(platform: typeof BuildPlatform.Type): boolean {
213+
return platform === "mac" || platform === "win";
214+
}
215+
209216
const resolveBooleanFlag = (flag: Option.Option<boolean>, envValue: boolean) =>
210217
Option.getOrElse(Option.filter(flag, Boolean), () => envValue);
211218
const mergeOptions = <A>(a: Option.Option<A>, b: Option.Option<A>, defaultValue: A) =>
@@ -236,8 +243,22 @@ const resolveBuildOptions = Effect.fn("resolveBuildOptions")(function* (input: B
236243
const skipBuild = resolveBooleanFlag(input.skipBuild, env.skipBuild);
237244
const keepStage = resolveBooleanFlag(input.keepStage, env.keepStage);
238245
const signed = resolveBooleanFlag(input.signed, env.signed);
246+
const requireSigned = resolveBooleanFlag(input.requireSigned, env.requireSigned);
239247
const verbose = resolveBooleanFlag(input.verbose, env.verbose);
240248

249+
if (requireSigned && !supportsReleaseSigning(platform)) {
250+
return yield* new BuildScriptError({
251+
message: `Signed desktop releases are not supported for platform '${platform}'.`,
252+
});
253+
}
254+
255+
if (requireSigned && !signed) {
256+
return yield* new BuildScriptError({
257+
message:
258+
"This desktop artifact requires signing. Re-run with --signed after configuring the required signing secrets.",
259+
});
260+
}
261+
241262
return {
242263
platform,
243264
target,
@@ -247,6 +268,7 @@ const resolveBuildOptions = Effect.fn("resolveBuildOptions")(function* (input: B
247268
skipBuild,
248269
keepStage,
249270
signed,
271+
requireSigned,
250272
verbose,
251273
} satisfies ResolvedBuildOptions;
252274
});
@@ -851,6 +873,12 @@ const buildDesktopArtifactCli = Command.make("build-desktop-artifact", {
851873
),
852874
Flag.optional,
853875
),
876+
requireSigned: Flag.boolean("require-signed").pipe(
877+
Flag.withDescription(
878+
"Fail closed unless the artifact is signed; supported for release macOS and Windows builds (env: OKCODE_DESKTOP_REQUIRE_SIGNED).",
879+
),
880+
Flag.optional,
881+
),
854882
verbose: Flag.boolean("verbose").pipe(
855883
Flag.withDescription("Stream subprocess stdout (env: OKCODE_DESKTOP_VERBOSE)."),
856884
Flag.optional,

scripts/package.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
"type": "module",
55
"scripts": {
66
"prepare": "node -e \"process.exit(process.env.CI ? 0 : 1)\" || node ./patch-effect-language-service.ts",
7-
"claude-fast-mode-probe": "bun run claude-fast-mode-probe.ts",
8-
"claude-haiku-thinking-probe": "bun run claude-haiku-thinking-probe.ts",
97
"typecheck": "tsc --noEmit",
108
"test": "vitest run"
119
},

0 commit comments

Comments
 (0)