diff --git a/docs/releases/v0.16.0/assets.md b/docs/releases/v0.16.0/assets.md index 923805f62..0a06dbbf1 100644 --- a/docs/releases/v0.16.0/assets.md +++ b/docs/releases/v0.16.0/assets.md @@ -47,10 +47,10 @@ The iOS build is uploaded directly to App Store Connect / TestFlight by the [Rel ## Rollout documentation -| Document | Purpose | -| -------- | ------- | +| Document | Purpose | +| -------------------------------------------- | --------------------------------------------------------------- | | [rollout-checklist.md](rollout-checklist.md) | Step-by-step release playbook (pre-flight through post-release) | -| [soak-test-plan.md](soak-test-plan.md) | Structured 48-hour RC soak test cases | +| [soak-test-plan.md](soak-test-plan.md) | Structured 48-hour RC soak test cases | ## Checksums diff --git a/docs/releases/v0.16.0/rollout-checklist.md b/docs/releases/v0.16.0/rollout-checklist.md index 87ad6dcf5..76cf568ca 100644 --- a/docs/releases/v0.16.0/rollout-checklist.md +++ b/docs/releases/v0.16.0/rollout-checklist.md @@ -81,8 +81,8 @@ All seven gates must pass with zero warnings: ## Phase 2: RC Soak (48 hours) -Start: ____-__-__T__:__Z -End: ____-__-__T__:__Z +Start: \_**\_-**-**T**:**Z +End: \_\_**-**-**T**:**Z ### Soak exit criteria @@ -108,8 +108,8 @@ These checks validate the high-risk surface area introduced in this release: Run on two devices: one current-generation and one older-generation supported device. -Device 1: ______________ (iOS __.__) -Device 2: ______________ (iOS __.__) +Device 1: **\*\***\_\_**\*\*** (iOS **.**) +Device 2: **\*\***\_\_**\*\*** (iOS **.**) - [ ] Pair the mobile companion with a desktop/server instance. - [ ] Restore a previously saved pairing. @@ -121,6 +121,7 @@ Device 2: ______________ (iOS __.__) ### If soak fails If any blocker is found during the soak period: + 1. Fix the issue on `main`. 2. Cut `v0.16.0-rc.2` with the fix included. 3. Restart the 48-hour soak from the beginning. @@ -166,12 +167,12 @@ Only after the 48-hour soak completes with all exit criteria met. ## Timeline -| Phase | Duration | Starts after | -| ----- | -------- | ------------ | -| Pre-flight | ~30 min | Decision to release | -| Cut RC | ~45 min | Pre-flight passes | -| RC Soak | 48 hours | All RC artifacts verified | -| Promote to stable | ~45 min | Soak exit criteria met | +| Phase | Duration | Starts after | +| ----------------------- | -------- | ------------------------- | +| Pre-flight | ~30 min | Decision to release | +| Cut RC | ~45 min | Pre-flight passes | +| RC Soak | 48 hours | All RC artifacts verified | +| Promote to stable | ~45 min | Soak exit criteria met | | Post-release monitoring | 24 hours | Stable artifacts verified | Total time from decision to stable: ~3 days minimum. diff --git a/docs/releases/v0.16.0/soak-test-plan.md b/docs/releases/v0.16.0/soak-test-plan.md index 4441f0d17..661bdf09c 100644 --- a/docs/releases/v0.16.0/soak-test-plan.md +++ b/docs/releases/v0.16.0/soak-test-plan.md @@ -4,214 +4,214 @@ Structured test plan for the 48-hour RC soak period. Each test case must be exec ## Test environments -| Role | Platform | Version | -| ---- | -------- | ------- | -| Primary desktop | macOS arm64 | Sonoma or later | -| Secondary desktop | Windows x64 | Windows 11 | -| Tertiary desktop | Linux x64 | Ubuntu 24.04 | -| Primary mobile | iPhone (current gen) | iOS 17+ | -| Secondary mobile | iPhone (older gen) | iOS 16+ | -| CLI | Any | Node 22.16+ | +| Role | Platform | Version | +| ----------------- | -------------------- | --------------- | +| Primary desktop | macOS arm64 | Sonoma or later | +| Secondary desktop | Windows x64 | Windows 11 | +| Tertiary desktop | Linux x64 | Ubuntu 24.04 | +| Primary mobile | iPhone (current gen) | iOS 17+ | +| Secondary mobile | iPhone (older gen) | iOS 16+ | +| CLI | Any | Node 22.16+ | ## 1. Installation and launch ### 1.1 Fresh install (all desktop platforms) -| Step | Expected | Pass | -| ---- | -------- | ---- | -| Download the RC DMG/AppImage/installer from GitHub Releases | Download completes, correct file size | [ ] | -| Install the application | Installs without errors | [ ] | -| Launch the application for the first time | App window opens, no crash | [ ] | -| Verify build metadata in the UI | Shows v0.16.0-rc.1, correct commit hash | [ ] | +| Step | Expected | Pass | +| ----------------------------------------------------------- | --------------------------------------- | ---- | +| Download the RC DMG/AppImage/installer from GitHub Releases | Download completes, correct file size | [ ] | +| Install the application | Installs without errors | [ ] | +| Launch the application for the first time | App window opens, no crash | [ ] | +| Verify build metadata in the UI | Shows v0.16.0-rc.1, correct commit hash | [ ] | ### 1.2 Upgrade from v0.15.0 (macOS, Windows) -| Step | Expected | Pass | -| ---- | -------- | ---- | -| Install v0.15.0 from the previous stable release | Installs and launches | [ ] | -| Allow the auto-updater to detect the RC | Updater notification appears | [ ] | -| Apply the update | App restarts on v0.16.0-rc.1 | [ ] | -| Verify existing sessions/settings survived the upgrade | Data is intact | [ ] | +| Step | Expected | Pass | +| ------------------------------------------------------ | ---------------------------- | ---- | +| Install v0.15.0 from the previous stable release | Installs and launches | [ ] | +| Allow the auto-updater to detect the RC | Updater notification appears | [ ] | +| Apply the update | App restarts on v0.16.0-rc.1 | [ ] | +| Verify existing sessions/settings survived the upgrade | Data is intact | [ ] | ### 1.3 CLI install -| Step | Expected | Pass | -| ---- | -------- | ---- | -| `npx okcodes@0.16.0-rc.1 --version` | Prints `0.16.0-rc.1` | [ ] | -| `npx okcodes@0.16.0-rc.1 --help` | Renders help text without errors | [ ] | -| `npx okcodes@0.16.0-rc.1 doctor --help` | Renders doctor subcommand help | [ ] | +| Step | Expected | Pass | +| --------------------------------------- | -------------------------------- | ---- | +| `npx okcodes@0.16.0-rc.1 --version` | Prints `0.16.0-rc.1` | [ ] | +| `npx okcodes@0.16.0-rc.1 --help` | Renders help text without errors | [ ] | +| `npx okcodes@0.16.0-rc.1 doctor --help` | Renders doctor subcommand help | [ ] | ## 2. Core session lifecycle ### 2.1 Start a new session -| Step | Expected | Pass | -| ---- | -------- | ---- | -| Open the app, start a new thread | Thread initializes, provider session starts | [ ] | -| Send a message | Response streams in real-time | [ ] | -| Send a follow-up message | Context carries over, response is coherent | [ ] | -| Wait 60 seconds idle, then send another message | Session resumes without reconnect error | [ ] | +| Step | Expected | Pass | +| ----------------------------------------------- | ------------------------------------------- | ---- | +| Open the app, start a new thread | Thread initializes, provider session starts | [ ] | +| Send a message | Response streams in real-time | [ ] | +| Send a follow-up message | Context carries over, response is coherent | [ ] | +| Wait 60 seconds idle, then send another message | Session resumes without reconnect error | [ ] | ### 2.2 Long-running session -| Step | Expected | Pass | -| ---- | -------- | ---- | -| Run a multi-turn session (10+ messages) over 30 minutes | No memory leaks, no UI lag | [ ] | -| Switch between threads during the session | State preserved per-thread | [ ] | -| Close and reopen the app mid-session | Session state recovers | [ ] | +| Step | Expected | Pass | +| ------------------------------------------------------- | -------------------------- | ---- | +| Run a multi-turn session (10+ messages) over 30 minutes | No memory leaks, no UI lag | [ ] | +| Switch between threads during the session | State preserved per-thread | [ ] | +| Close and reopen the app mid-session | Session state recovers | [ ] | ## 3. New feature tests (v0.16.0 specific) ### 3.1 Right-panel diff viewer -| Step | Expected | Pass | -| ---- | -------- | ---- | -| Trigger a file change in a thread | Diff entry appears in work log | [ ] | -| Click the diff entry | Right panel opens with diff view | [ ] | -| Navigate between multiple changed files | Panel updates, no stale content | [ ] | -| Close the diff panel | Panel closes cleanly | [ ] | -| Reopen the diff panel | Previous diff state restored | [ ] | +| Step | Expected | Pass | +| --------------------------------------- | -------------------------------- | ---- | +| Trigger a file change in a thread | Diff entry appears in work log | [ ] | +| Click the diff entry | Right panel opens with diff view | [ ] | +| Navigate between multiple changed files | Panel updates, no stale content | [ ] | +| Close the diff panel | Panel closes cleanly | [ ] | +| Reopen the diff panel | Previous diff state restored | [ ] | ### 3.2 Editable code preview with autosave -| Step | Expected | Pass | -| ---- | -------- | ---- | -| Open a code preview | Preview renders correctly | [ ] | -| Make edits in the preview | Changes appear immediately | [ ] | -| Wait 5 seconds (autosave interval) | No save indicator or error | [ ] | -| Navigate away from the preview, then return | Edits are preserved | [ ] | -| Close and reopen the app | Edits survive the restart | [ ] | +| Step | Expected | Pass | +| ------------------------------------------- | -------------------------- | ---- | +| Open a code preview | Preview renders correctly | [ ] | +| Make edits in the preview | Changes appear immediately | [ ] | +| Wait 5 seconds (autosave interval) | No save indicator or error | [ ] | +| Navigate away from the preview, then return | Edits are preserved | [ ] | +| Close and reopen the app | Edits survive the restart | [ ] | ### 3.3 Rebase-before-commit flow -| Step | Expected | Pass | -| ---- | -------- | ---- | -| Create a branch that has diverged from main (both have new commits) | Branch exists | [ ] | -| Trigger commit with rebase-before-commit enabled | Rebase starts | [ ] | -| (Clean rebase) Verify the commit lands on rebased history | Commit appears with linear history | [ ] | -| (Conflict rebase) Create a branch with deliberate conflicts | Branch exists | [ ] | -| Trigger commit with rebase-before-commit | Conflict is detected and surfaced to the user | [ ] | -| Resolve conflict and retry | Commit succeeds after resolution | [ ] | +| Step | Expected | Pass | +| ------------------------------------------------------------------- | --------------------------------------------- | ---- | +| Create a branch that has diverged from main (both have new commits) | Branch exists | [ ] | +| Trigger commit with rebase-before-commit enabled | Rebase starts | [ ] | +| (Clean rebase) Verify the commit lands on rebased history | Commit appears with linear history | [ ] | +| (Conflict rebase) Create a branch with deliberate conflicts | Branch exists | [ ] | +| Trigger commit with rebase-before-commit | Conflict is detected and surfaced to the user | [ ] | +| Resolve conflict and retry | Commit succeeds after resolution | [ ] | ### 3.4 GitHub repo cloning -| Step | Expected | Pass | -| ---- | -------- | ---- | -| Use the clone entry point with a public repo URL | Repo clones, thread opens in the cloned project | [ ] | -| Use the clone entry point with a private repo URL | Auth flow triggers, repo clones after auth | [ ] | -| Clone a large repo (1GB+) | Progress indicator shows, clone completes | [ ] | -| Cancel a clone in progress | Clone stops cleanly, no partial state left | [ ] | +| Step | Expected | Pass | +| ------------------------------------------------- | ----------------------------------------------- | ---- | +| Use the clone entry point with a public repo URL | Repo clones, thread opens in the cloned project | [ ] | +| Use the clone entry point with a private repo URL | Auth flow triggers, repo clones after auth | [ ] | +| Clone a large repo (1GB+) | Progress indicator shows, clone completes | [ ] | +| Cancel a clone in progress | Clone stops cleanly, no partial state left | [ ] | ### 3.5 Provider session restart on CWD change -| Step | Expected | Pass | -| ---- | -------- | ---- | -| Start a session in worktree A | Session runs normally | [ ] | -| Switch active worktree to B | Provider session restarts automatically | [ ] | -| Send a message after the switch | Response uses worktree B context | [ ] | -| Switch back to worktree A | Session restarts again, context is correct | [ ] | +| Step | Expected | Pass | +| ------------------------------- | ------------------------------------------ | ---- | +| Start a session in worktree A | Session runs normally | [ ] | +| Switch active worktree to B | Provider session restarts automatically | [ ] | +| Send a message after the switch | Response uses worktree B context | [ ] | +| Switch back to worktree A | Session restarts again, context is correct | [ ] | ### 3.6 Shell env sanitization -| Step | Expected | Pass | -| ---- | -------- | ---- | -| Set `NODE_OPTIONS=--max-old-space-size=100` in shell env | Env is set | [ ] | -| Launch an agent session | Session starts without inheriting the restrictive NODE_OPTIONS | [ ] | -| Set `PATH` to include unusual directories | Env is set | [ ] | -| Launch an agent session | Session uses sanitized PATH | [ ] | +| Step | Expected | Pass | +| -------------------------------------------------------- | -------------------------------------------------------------- | ---- | +| Set `NODE_OPTIONS=--max-old-space-size=100` in shell env | Env is set | [ ] | +| Launch an agent session | Session starts without inheriting the restrictive NODE_OPTIONS | [ ] | +| Set `PATH` to include unusual directories | Env is set | [ ] | +| Launch an agent session | Session uses sanitized PATH | [ ] | ### 3.7 Build metadata visibility -| Step | Expected | Pass | -| ---- | -------- | ---- | -| Check version display in the web UI | Shows 0.16.0-rc.1 | [ ] | -| Check commit hash in the web UI | Matches the tagged commit | [ ] | -| Check server metadata endpoint/logs | Reports matching version and commit | [ ] | +| Step | Expected | Pass | +| ----------------------------------- | ----------------------------------- | ---- | +| Check version display in the web UI | Shows 0.16.0-rc.1 | [ ] | +| Check commit hash in the web UI | Matches the tagged commit | [ ] | +| Check server metadata endpoint/logs | Reports matching version and commit | [ ] | ## 4. Viewport presets and orientation -| Step | Expected | Pass | -| ---- | -------- | ---- | -| Open viewport preset selector | Presets are listed | [ ] | -| Switch to a mobile preset | Preview resizes to mobile dimensions | [ ] | -| Toggle orientation (portrait/landscape) | Preview rotates | [ ] | -| Switch to a tablet preset | Preview resizes correctly | [ ] | -| Return to default viewport | Preview returns to normal | [ ] | +| Step | Expected | Pass | +| --------------------------------------- | ------------------------------------ | ---- | +| Open viewport preset selector | Presets are listed | [ ] | +| Switch to a mobile preset | Preview resizes to mobile dimensions | [ ] | +| Toggle orientation (portrait/landscape) | Preview rotates | [ ] | +| Switch to a tablet preset | Preview resizes correctly | [ ] | +| Return to default viewport | Preview returns to normal | [ ] | ## 5. iOS TestFlight testing -### 5.1 Device 1: ______________ (iOS __.__) - -| Step | Expected | Pass | -| ---- | -------- | ---- | -| Install from TestFlight | App installs and launches | [ ] | -| Pair with desktop/server | Pairing completes | [ ] | -| Restore a saved pairing | Connection re-establishes | [ ] | -| Open a thread and send a message | Message sends, response streams | [ ] | -| Approve an action | Action executes | [ ] | -| Answer a user-input request | Input is delivered to the agent | [ ] | -| Background the app for 30 seconds | App suspends | [ ] | -| Foreground the app | App resumes without reconnect error | [ ] | -| Tap a notification | App opens to the correct thread | [ ] | - -### 5.2 Device 2: ______________ (iOS __.__) - -| Step | Expected | Pass | -| ---- | -------- | ---- | -| Install from TestFlight | App installs and launches | [ ] | -| Pair with desktop/server | Pairing completes | [ ] | -| Restore a saved pairing | Connection re-establishes | [ ] | -| Open a thread and send a message | Message sends, response streams | [ ] | -| Approve an action | Action executes | [ ] | -| Answer a user-input request | Input is delivered to the agent | [ ] | -| Background the app for 30 seconds | App suspends | [ ] | -| Foreground the app | App resumes without reconnect error | [ ] | -| Tap a notification | App opens to the correct thread | [ ] | +### 5.1 Device 1: **\*\***\_\_**\*\*** (iOS **.**) + +| Step | Expected | Pass | +| --------------------------------- | ----------------------------------- | ---- | +| Install from TestFlight | App installs and launches | [ ] | +| Pair with desktop/server | Pairing completes | [ ] | +| Restore a saved pairing | Connection re-establishes | [ ] | +| Open a thread and send a message | Message sends, response streams | [ ] | +| Approve an action | Action executes | [ ] | +| Answer a user-input request | Input is delivered to the agent | [ ] | +| Background the app for 30 seconds | App suspends | [ ] | +| Foreground the app | App resumes without reconnect error | [ ] | +| Tap a notification | App opens to the correct thread | [ ] | + +### 5.2 Device 2: **\*\***\_\_**\*\*** (iOS **.**) + +| Step | Expected | Pass | +| --------------------------------- | ----------------------------------- | ---- | +| Install from TestFlight | App installs and launches | [ ] | +| Pair with desktop/server | Pairing completes | [ ] | +| Restore a saved pairing | Connection re-establishes | [ ] | +| Open a thread and send a message | Message sends, response streams | [ ] | +| Approve an action | Action executes | [ ] | +| Answer a user-input request | Input is delivered to the agent | [ ] | +| Background the app for 30 seconds | App suspends | [ ] | +| Foreground the app | App resumes without reconnect error | [ ] | +| Tap a notification | App opens to the correct thread | [ ] | ## 6. Regression tests ### 6.1 Sidebar and navigation -| Step | Expected | Pass | -| ---- | -------- | ---- | -| Open sidebar, verify thread list loads | Threads render with wide names | [ ] | -| Create a new thread | Thread appears in sidebar | [ ] | -| Switch between threads | Content updates without flash | [ ] | +| Step | Expected | Pass | +| -------------------------------------- | ------------------------------ | ---- | +| Open sidebar, verify thread list loads | Threads render with wide names | [ ] | +| Create a new thread | Thread appears in sidebar | [ ] | +| Switch between threads | Content updates without flash | [ ] | ### 6.2 Prompt enhancement -| Step | Expected | Pass | -| ---- | -------- | ---- | -| Open the prompt enhancement menu | Menu appears | [ ] | -| Select an enhancement | Enhancement applies to the composer | [ ] | -| Send the message with enhancement | Enhancement is preserved in the sent message | [ ] | +| Step | Expected | Pass | +| --------------------------------- | -------------------------------------------- | ---- | +| Open the prompt enhancement menu | Menu appears | [ ] | +| Select an enhancement | Enhancement applies to the composer | [ ] | +| Send the message with enhancement | Enhancement is preserved in the sent message | [ ] | ### 6.3 PR status display -| Step | Expected | Pass | -| ---- | -------- | ---- | -| Open a thread linked to a branch with a PR | PR status badge appears | [ ] | -| Verify PR status matches GitHub | Status is correct (open/merged/closed) | [ ] | +| Step | Expected | Pass | +| ------------------------------------------ | -------------------------------------- | ---- | +| Open a thread linked to a branch with a PR | PR status badge appears | [ ] | +| Verify PR status matches GitHub | Status is correct (open/merged/closed) | [ ] | ## 7. Stability monitoring Track throughout the 48-hour soak: -| Metric | Threshold | Status | -| ------ | --------- | ------ | -| Crash-on-launch | 0 across all desktop platforms | [ ] | -| Unhandled exceptions in console | 0 critical | [ ] | -| Memory usage after 1 hour | < 500 MB RSS | [ ] | -| WebSocket reconnect failures | 0 permanent failures | [ ] | -| Sev-1 issues filed | 0 | [ ] | -| Sev-2 issues filed | 0 | [ ] | +| Metric | Threshold | Status | +| ------------------------------- | ------------------------------ | ------ | +| Crash-on-launch | 0 across all desktop platforms | [ ] | +| Unhandled exceptions in console | 0 critical | [ ] | +| Memory usage after 1 hour | < 500 MB RSS | [ ] | +| WebSocket reconnect failures | 0 permanent failures | [ ] | +| Sev-1 issues filed | 0 | [ ] | +| Sev-2 issues filed | 0 | [ ] | ## Soak sign-off -| Role | Name | Date | Approved | -| ---- | ---- | ---- | -------- | -| Release lead | | | [ ] | -| QA reviewer | | | [ ] | -| iOS tester | | | [ ] | +| Role | Name | Date | Approved | +| ------------ | ---- | ---- | -------- | +| Release lead | | | [ ] | +| QA reviewer | | | [ ] | +| iOS tester | | | [ ] | When all checks pass and sign-off is complete, proceed to Phase 3 (Promote to Stable) in the [rollout checklist](rollout-checklist.md). diff --git a/scripts/pre-release-validate.ts b/scripts/pre-release-validate.ts index ef5a96045..43dd78f9d 100644 --- a/scripts/pre-release-validate.ts +++ b/scripts/pre-release-validate.ts @@ -63,7 +63,11 @@ const RELEASE_PACKAGES = [ // Helpers // --------------------------------------------------------------------------- -function run(cmd: string, args: string[], opts?: { cwd?: string }): { ok: boolean; stdout: string } { +function run( + cmd: string, + args: string[], + opts?: { cwd?: string }, +): { ok: boolean; stdout: string } { try { const stdout = execFileSync(cmd, args, { cwd: opts?.cwd, @@ -109,7 +113,11 @@ function checkVersionAlignment(rootDir: string, version: string): CheckResult { } if (mismatched.length === 0) { - return { name: "Package version alignment", passed: true, detail: `All packages at ${version}` }; + return { + name: "Package version alignment", + passed: true, + detail: `All packages at ${version}`, + }; } return { name: "Package version alignment", @@ -160,7 +168,11 @@ function checkAssetManifest(rootDir: string, version: string): CheckResult { function checkReleasesReadmeEntry(rootDir: string, version: string): CheckResult { const readmePath = resolve(rootDir, "docs/releases/README.md"); if (!existsSync(readmePath)) { - return { name: "Releases index entry", passed: false, detail: "docs/releases/README.md missing" }; + return { + name: "Releases index entry", + passed: false, + detail: "docs/releases/README.md missing", + }; } const content = readFileSync(readmePath, "utf8"); @@ -203,16 +215,15 @@ function checkOnMain(rootDir: string): CheckResult { return { name: "On main branch", passed: isMain, - detail: isMain ? "Currently on main" : `Currently on "${stdout}" — release tags should be cut from main`, + detail: isMain + ? "Currently on main" + : `Currently on "${stdout}" — release tags should be cut from main`, }; } function checkReleaseReadyDocs(rootDir: string, version: string): CheckResult { // Validate the same conditions the release-ready.yml workflow checks - const requiredFiles = [ - `docs/releases/v${version}.md`, - `docs/releases/v${version}/assets.md`, - ]; + const requiredFiles = [`docs/releases/v${version}.md`, `docs/releases/v${version}/assets.md`]; const missing = requiredFiles.filter((f) => !existsSync(resolve(rootDir, f))); if (missing.length === 0) { @@ -241,7 +252,8 @@ function checkReleaseNotesContent(rootDir: string, version: string): CheckResult if (!content.includes(`v${version}`)) issues.push("version not mentioned in body"); if (!content.includes("## Summary")) issues.push("missing Summary section"); if (!content.includes("## Highlights")) issues.push("missing Highlights section"); - if (!content.includes("## Upgrade and install")) issues.push("missing Upgrade and install section"); + if (!content.includes("## Upgrade and install")) + issues.push("missing Upgrade and install section"); if (issues.length === 0) { return { name: "Release notes content", passed: true, detail: "All expected sections present" }; @@ -263,13 +275,18 @@ function checkAssetManifestContent(rootDir: string, version: string): CheckResul const issues: string[] = []; if (!content.includes("Desktop installers")) issues.push("missing Desktop installers section"); - if (!content.includes("Electron updater metadata")) issues.push("missing updater metadata section"); + if (!content.includes("Electron updater metadata")) + issues.push("missing updater metadata section"); if (!content.includes("iOS (TestFlight)")) issues.push("missing iOS section"); if (!content.includes("Checksums")) issues.push("missing Checksums section"); if (!content.includes(version)) issues.push("version not mentioned in body"); if (issues.length === 0) { - return { name: "Asset manifest content", passed: true, detail: "All expected sections present" }; + return { + name: "Asset manifest content", + passed: true, + detail: "All expected sections present", + }; } return { name: "Asset manifest content", @@ -285,7 +302,9 @@ function checkIosProjectVersion(rootDir: string, version: string): CheckResult { } const content = readFileSync(pbxprojPath, "utf8"); - const versionPattern = new RegExp(`MARKETING_VERSION\\s*=\\s*${version.replace(/\./g, "\\.")}\\s*;`); + const versionPattern = new RegExp( + `MARKETING_VERSION\\s*=\\s*${version.replace(/\./g, "\\.")}\\s*;`, + ); const matches = content.match(versionPattern); if (matches) { @@ -480,7 +499,9 @@ function main(): void { } console.log(""); - console.log(` ${passed.length} passed, ${failed.length} failed out of ${allChecks.length} checks.`); + console.log( + ` ${passed.length} passed, ${failed.length} failed out of ${allChecks.length} checks.`, + ); if (failed.length > 0) { console.log(""); @@ -507,7 +528,9 @@ function main(): void { console.log(` node scripts/prepare-release.ts ${version} --full-matrix`); } else { console.log(" Next steps:"); - console.log(` 1. Cut RC first: node scripts/prepare-release.ts ${version}-rc.1 --full-matrix`); + console.log( + ` 1. Cut RC first: node scripts/prepare-release.ts ${version}-rc.1 --full-matrix`, + ); console.log(" 2. Soak RC for 48 hours."); console.log(` 3. Promote: node scripts/prepare-release.ts ${version} --full-matrix`); }