Build, sign, notarize, and ship a Scrutinizer Electron release with golden captures and website update.
Install
mkdir -p .claude/skills/release-andyed && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/14724" && unzip -o skill.zip -d .claude/skills/release-andyed && rm skill.zipInstalls to .claude/skills/release-andyed
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Build, sign, notarize, and ship a Scrutinizer Electron release with golden captures and website update.103 chars · catalog descriptionno explicit “when” trigger
About this skill
/release — Scrutinizer Release Skill
Build, sign, notarize, and ship a Scrutinizer Electron release with golden captures and website update.
Usage
/releaseor/release bump— Full release: bump version, tests, golden captures, build signed DMG, GitHub release, update website./release silent— Rebuild current version (hotfix rebuild). No version bump, no changelog, no golden captures, no tag./release patch— Same as bump (default)./release minor— Bump minor version (e.g. 1.7.0 → 1.8.0)./release 1.8.0— Explicit version target.
Args
bump(default) — Bump the patch version (e.g. 1.7.0 → 1.7.1). Pass a specific version like1.8.0to set it explicitly.minor— Bump the minor version (e.g. 1.7.0 → 1.8.0).silent— Rebuild at the current version. No version bump, no changelog, no golden captures, no tag.
Full Release Steps (bump)
Run each step sequentially. After each step, verify before proceeding. STOP on any failure.
1. Pre-flight checks
- Confirm working directory is
~/Documents/dev/scrutinizer-repo/scrutinizer2025 - Verify clean git state:
git status(no uncommitted changes) - Verify
.envhas credentials:
Must return 3.grep -c 'APPLE_ID\|APPLE_ID_PASSWORD\|APPLE_TEAM_ID' .env - Read current version from
package.json - Confirm new version number with the user
- Verify
node_modulesexists; runnpm ciif not
2. Bump version
- Edit
package.jsonversionfield directly - Do NOT use
npm version— edit the file directly
3. Run tests
npm test- All tests must pass. STOP on failure.
4. Capture golden screenshots
- Staleness check: Compare the timestamp of existing captures against shader/mode changes:
If code is newer than captures, captures are stale — must recapture. If only non-visual changes (scripts, tests, docs), captures may still be valid — check# Oldest capture vs newest code change CAPTURE_TIME=$(stat -f %m tests/golden-captures/v*/$(ls tests/golden-captures/v*/ | head -1) 2>/dev/null || echo 0) CODE_TIME=$(stat -f %m renderer/shaders/peripheral.frag shared/modes.json)git diffbetween capture commit and HEAD for shader/mode changes. npm run capture-golden -- --force(use--forceif captures are stale)- Captures to
tests/golden-captures/v{VERSION}/ - Also run mode comparison:
node scripts/capture-mode-comparison.js - Verify captures exist:
ls tests/golden-captures/v{VERSION}/ | head -10
5. Compare golden captures
npm run golden-compare- Or open both version dirs for manual comparison:
open tests/golden-captures/v{PREV}/ tests/golden-captures/v{VERSION}/ - Look for visual regressions
- Ask user to confirm captures look good
6. Write release notes
- Summarize commits since last tag:
git log $(git describe --tags --abbrev=0)..HEAD --oneline - Create
docs/release_notes_v{VERSION}.mdfollowing existing format (seedocs/release_notes_v1.5.0.md,docs/release_notes_v1.6.0.md) - Ask user for highlights or summarize from commits
7. Update CHANGELOG.md, ROADMAP.md, and README.md
- Add version entry to
CHANGELOG.md - Move completed items in
ROADMAP.mdfrom "Next" to their feature sections - Update
README.md: version badge and download link (v{PREV}→v{VERSION})
8. Commit release
- Stage:
Also stage mode comparison captures if they exist:git add package.json docs/release_notes_v{VERSION}.md CHANGELOG.md ROADMAP.md README.md tests/golden-captures/v{VERSION}/git add docs/golden/mode-comparison/ 2>/dev/null || true - Commit:
release: v{VERSION} — {brief summary} - Do NOT push yet
9. Build signed DMG
npm run build- This runs
scripts/build-signed.js→ electron-builder → notarization (5-15 min) - Verify output exists:
ls -lh dist/Scrutinizer-{VERSION}-arm64.dmg dist/Scrutinizer-{VERSION}-arm64-mac.zip - Verify DMG size is reasonable (>50MB)
10. Tag and push
git tag v{VERSION}git push origin main --tags
11. Create GitHub Release
-
gh release create v{VERSION} \ dist/Scrutinizer-{VERSION}-arm64.dmg \ dist/Scrutinizer-{VERSION}-arm64-mac.zip \ dist/latest-mac.yml \ --title "v{VERSION}" \ --notes-file docs/release_notes_v{VERSION}.md - Verify:
gh release view v{VERSION} --json assets --jq '.assets[].name'
12. Update website (scrutinizer-www)
cd ~/Documents/dev/scrutinizer-repo/scrutinizer-www- Edit
src/index.html: update version badge and download URL- Version badge:
v{PREV}→v{VERSION} - Download URL:
v{PREV}/Scrutinizer-{PREV}-arm64.dmg→v{VERSION}/Scrutinizer-{VERSION}-arm64.dmg
- Version badge:
- Commit:
site: update download link to v{VERSION} - Push:
git push origin master(triggers GitHub Pages deploy) - Return to scrutinizer2025 working directory after
13. Verify auto-update
- Confirm
latest-mac.ymlis in the release assets:
If missing, upload it:gh release view v{VERSION} --json assets --jq '.assets[].name' | grep latest-mac.ymlgh release upload v{VERSION} dist/latest-mac.yml --clobber - Verify the yml content matches the built artifacts:
Version field must saygh release download v{VERSION} --pattern latest-mac.yml --output - | head -5{VERSION}and file entries must list the DMG and ZIP with sha512 hashes. - On a machine running the previous version, electron-updater should detect the update via Check for Updates
Silent Update Steps (silent)
Same as full release but skip version bump, golden captures, release notes, changelog, roadmap, and tagging.
1. Pre-flight checks
- Same as full release (clean tree, env vars, read current version)
2. Run tests
npm test- STOP on failure.
3. Build signed DMG
npm run build- Verify DMG and ZIP exist at current version
4. Push
git push origin main(no new tag)
5. Update GitHub release assets
- Replace existing assets on the current version's release:
gh release upload v{VERSION} \ dist/Scrutinizer-{VERSION}-arm64.dmg \ dist/Scrutinizer-{VERSION}-arm64-mac.zip \ dist/latest-mac.yml \ --clobber - Verify:
gh release view v{VERSION} --json assets --jq '.assets[].name'
Key Constraints
- ARM64 only — Scrutinizer builds arm64 (not universal). Build config targets
--macwith arm64 architecture. - Single package.json — Unlike Psychodeli+ (monorepo with root + apps/electron), Scrutinizer has only one
package.jsonat root. - Notarization — Handled by
scripts/notarize.jsviaafterSignhook in electron-builder config. Requires.envwithAPPLE_ID,APPLE_ID_PASSWORD,APPLE_TEAM_ID. - GitHub Releases for auto-update —
electron-updaterchecks GitHub releases forlatest-mac.yml. The publish config inpackage.jsonpoints toprovider: "github",owner: "andyed",repo: "scrutinizer2025". - Sibling website repo —
scrutinizer-wwwat~/Documents/dev/scrutinizer-repo/scrutinizer-www/. Download links and version badge live insrc/index.html. Deploys via GitHub Pages on push tomasterbranch. - Golden captures are version-stamped — Saved to
tests/golden-captures/v{VERSION}/. Compare against previous version visually. - Mode comparison captures —
scripts/capture-mode-comparison.jsoutputs todocs/golden/mode-comparison/. May need staging separately. - Working directory — Always run from
~/Documents/dev/scrutinizer-repo/scrutinizer2025. Don'tcdinto subdirs for git commands. The one exception is step 12 (website update) — return to scrutinizer2025 after. - Trust the user — If they say something looks wrong, investigate the actual code path. Do not theorize the bug away.