Skip to content

Commit db292ee

Browse files
authored
Merge pull request #1 from ccofallen/feat/cross-platform-desktop-release
Release cross-platform Codex Pet Pause desktop apps
2 parents 901d0f9 + 7af6164 commit db292ee

70 files changed

Lines changed: 10699 additions & 222 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
name: Build Desktop
2+
3+
on:
4+
push:
5+
branches: [main]
6+
tags: ["v*"]
7+
pull_request:
8+
workflow_dispatch:
9+
10+
permissions:
11+
contents: write
12+
13+
jobs:
14+
validate:
15+
runs-on: ubuntu-latest
16+
steps:
17+
- uses: actions/checkout@v4
18+
- uses: actions/setup-node@v4
19+
with:
20+
node-version: 22
21+
cache: npm
22+
- run: npm ci
23+
- run: npx playwright install --with-deps chromium
24+
- run: npm run test:desktop-release-config
25+
- run: npm run test:brand-assets
26+
- run: npm run test:desktop-workflow
27+
- run: npm run test:electron
28+
- run: npm run test:release-artifacts
29+
- run: npm run test:release-tag
30+
- run: npm run test:packaged-resources
31+
- run: npm run test:packaged-app
32+
- run: npm run check:desktop-release-config
33+
- run: npm run test:run
34+
- run: npm run build
35+
- run: npm run test:e2e
36+
- name: Validate workflow syntax with actionlint
37+
run: docker run --rm -v "$GITHUB_WORKSPACE:/workspace" -w /workspace rhysd/actionlint:1.7.12 .github/workflows/build-desktop.yml
38+
39+
package:
40+
needs: validate
41+
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
42+
strategy:
43+
fail-fast: false
44+
matrix:
45+
include:
46+
- id: mac-arm64
47+
target: mac-arm64
48+
os: macos-latest
49+
command: npm run desktop:pack:mac -- --arm64
50+
artifact: release/*-mac-arm64.dmg
51+
- id: mac-x64
52+
target: mac-x64
53+
os: macos-latest
54+
command: npm run desktop:pack:mac -- --x64
55+
artifact: release/*-mac-x64.dmg
56+
- id: windows-x64
57+
target: windows-x64
58+
os: windows-latest
59+
command: npm run desktop:pack:win -- --x64
60+
artifact: release/*-windows-x64.exe
61+
- id: linux-x64
62+
target: linux-x64
63+
os: ubuntu-latest
64+
command: npm run desktop:pack:linux -- --x64
65+
artifact: |
66+
release/*-linux-x64.AppImage
67+
release/*-linux-x64.deb
68+
runs-on: ${{ matrix.os }}
69+
steps:
70+
- uses: actions/checkout@v4
71+
- uses: actions/setup-node@v4
72+
with:
73+
node-version: 22
74+
cache: npm
75+
- run: npm ci
76+
- run: node scripts/verify-release-tag.mjs "${{ github.ref_name }}"
77+
- run: ${{ matrix.command }}
78+
- run: npm run desktop:smoke:packaged-app
79+
- run: node scripts/verify-release-artifacts.mjs release --target ${{ matrix.target }}
80+
- uses: actions/upload-artifact@v4
81+
with:
82+
name: ${{ matrix.id }}
83+
path: ${{ matrix.artifact }}
84+
if-no-files-found: error
85+
86+
release:
87+
needs: package
88+
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
89+
runs-on: ubuntu-latest
90+
steps:
91+
- uses: actions/checkout@v4
92+
- uses: actions/setup-node@v4
93+
with:
94+
node-version: 22
95+
- run: node scripts/verify-release-tag.mjs "${{ github.ref_name }}"
96+
- uses: actions/download-artifact@v4
97+
with:
98+
path: release-assets
99+
merge-multiple: true
100+
- run: node scripts/verify-release-artifacts.mjs release-assets
101+
- name: Publish release assets
102+
env:
103+
GH_TOKEN: ${{ github.token }}
104+
run: |
105+
if gh release view "$GITHUB_REF_NAME"; then
106+
gh release view "$GITHUB_REF_NAME" --json assets --jq '.assets[].name' | while IFS= read -r asset; do
107+
gh release delete-asset "$GITHUB_REF_NAME" "$asset" --yes
108+
done
109+
gh release upload "$GITHUB_REF_NAME" release-assets/*
110+
else
111+
gh release create "$GITHUB_REF_NAME" release-assets/* --generate-notes --title "Codex Pet Pause $GITHUB_REF_NAME"
112+
fi
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
# Task 1 Report: Establish the Release Contract
2+
3+
## Result
4+
5+
Implemented the desktop release-config validator, its behavioral tests, and the two requested npm scripts. The final package matrix was not added; that remains owned by Task 3.
6+
7+
## TDD evidence
8+
9+
### RED
10+
11+
Command:
12+
13+
```bash
14+
node --test scripts/verify-desktop-release-config.test.mjs
15+
```
16+
17+
Output:
18+
19+
```text
20+
TAP version 13
21+
# Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/Users/cc/Documents/Codex/codex-pet-pause-desktop/.worktrees/cross-platform-release/scripts/verify-desktop-release-config.mjs' imported from /Users/cc/Documents/Codex/codex-pet-pause-desktop/.worktrees/cross-platform-release/scripts/verify-desktop-release-config.test.mjs
22+
# Subtest: scripts/verify-desktop-release-config.test.mjs
23+
not ok 1 - scripts/verify-desktop-release-config.test.mjs
24+
1..1
25+
# tests 1
26+
# pass 0
27+
# fail 1
28+
```
29+
30+
The test failed because the contract module did not exist, as required for the RED step.
31+
32+
### GREEN
33+
34+
Command:
35+
36+
```bash
37+
npm run test:desktop-release-config
38+
```
39+
40+
Output:
41+
42+
```text
43+
> codex-pet-pause@0.2.0 test:desktop-release-config
44+
> node --test scripts/verify-desktop-release-config.test.mjs
45+
46+
TAP version 13
47+
# Subtest: accepts the approved desktop release contract
48+
ok 1 - accepts the approved desktop release contract
49+
# Subtest: rejects an identity, target, or icon regression
50+
ok 2 - rejects an identity, target, or icon regression
51+
1..2
52+
# tests 2
53+
# pass 2
54+
# fail 0
55+
```
56+
57+
## Files
58+
59+
- `scripts/verify-desktop-release-config.mjs`: Exports `verifyDesktopReleaseConfig(packageJson, fileExists)`, validates the approved identity, platform targets, and icon existence, and provides the standalone `check:desktop-release-config` entry point.
60+
- `scripts/verify-desktop-release-config.test.mjs`: Covers acceptance of the approved contract and rejection of identity, target, and icon regressions.
61+
- `package.json`: Adds `test:desktop-release-config` and `check:desktop-release-config`.
62+
63+
## Self-review
64+
65+
- The implementation follows the exact validator shape and values from the task brief.
66+
- The injected `fileExists` function keeps the validator deterministic and directly testable.
67+
- Missing target entries and missing architecture entries produce human-readable failures rather than throwing.
68+
- No final Electron Builder package matrix or generated icon assets were added.
69+
70+
## Concerns
71+
72+
- `check:desktop-release-config` is expected to fail in this task state because `package.json` does not yet contain the final macOS, Windows, and Linux target configuration and the required icon assets are not present. Those changes belong to later release tasks.
73+
- Artifact-name templates are present in the behavioral fixture but are not validated by the prescribed validator implementation.
74+
75+
## Fix round 1 evidence
76+
77+
### RED mutations
78+
79+
Added mutations for wrong configured native icon paths with `fileExists` returning `true`, plus extra `zip`, `nsis-web`, and `snap` targets. Before the validator changes:
80+
81+
```bash
82+
node --test scripts/verify-desktop-release-config.test.mjs
83+
```
84+
85+
```text
86+
TAP version 13
87+
# Subtest: accepts the approved desktop release contract
88+
ok 1 - accepts the approved desktop release contract
89+
# Subtest: rejects an identity, target, or icon regression
90+
ok 2 - rejects an identity, target, or icon regression
91+
# Subtest: rejects wrong configured native icon paths even when expected files exist
92+
not ok 3 - rejects wrong configured native icon paths even when expected files exist
93+
# Subtest: rejects unintended extra target formats on every platform
94+
not ok 4 - rejects unintended extra target formats on every platform
95+
1..4
96+
# tests 4
97+
# pass 2
98+
# fail 2
99+
```
100+
101+
### GREEN focused test
102+
103+
```bash
104+
npm run test:desktop-release-config
105+
```
106+
107+
```text
108+
TAP version 13
109+
# Subtest: accepts the approved desktop release contract
110+
ok 1 - accepts the approved desktop release contract
111+
# Subtest: rejects an identity, target, or icon regression
112+
ok 2 - rejects an identity, target, or icon regression
113+
# Subtest: rejects wrong configured native icon paths even when expected files exist
114+
ok 3 - rejects wrong configured native icon paths even when expected files exist
115+
# Subtest: rejects unintended extra target formats on every platform
116+
ok 4 - rejects unintended extra target formats on every platform
117+
1..4
118+
# tests 4
119+
# pass 4
120+
# fail 0
121+
```
122+
123+
### Direct check
124+
125+
```bash
126+
npm run check:desktop-release-config
127+
```
128+
129+
Expected current-package failure (exit code 1):
130+
131+
```text
132+
Error: macOS targets must be exactly dmg
133+
macOS DMG must target arm64 and x64
134+
Windows targets must be exactly nsis
135+
Windows NSIS must target x64
136+
Linux targets must be exactly AppImage and deb
137+
Linux AppImage must target x64
138+
Linux DEB must target x64
139+
macOS icon must be configured as build/icons/icon.icns
140+
macOS icon is missing: build/icons/icon.icns
141+
Windows icon must be configured as build/icons/icon.ico
142+
Windows icon is missing: build/icons/icon.ico
143+
Linux icon must be configured as build/icons/png
144+
Linux icon is missing: build/icons/png
145+
```
146+
147+
## Fix round 1 changes
148+
149+
- Native icon validation now compares each configured platform icon with its expected native path before checking file existence.
150+
- Target validation now rejects any platform target-name set other than macOS `dmg`, Windows `nsis`, and Linux `AppImage` plus `deb`, while retaining the required architecture checks.

0 commit comments

Comments
 (0)