Skip to content

Commit 3c8bf65

Browse files
adoisticclaude
andcommitted
ci(github): typecheck/lint/test on PR + DMG build on tag
- .github/workflows/ci.yml — runs on every PR + push to main: typecheck + lint + format check + Vitest. Skips Playwright Electron E2E because docs/eng-plan.md §1 marks it local-only (font antialiasing differs across CI machines and breaks the pixel diff). - .github/workflows/release.yml — triggered by `v*.*.*` tags or manual workflow_dispatch. Builds the unsigned arm64 DMG on macos-14 and attaches it to the GitHub Release for the matching tag (creating the release if the tag was pushed without one). Sets CSC_IDENTITY_AUTO_DISCOVERY=false to make the no-sign intent explicit. Code-signing + notarization is the v0.8 follow-up: add APPLE_ID + APPLE_APP_SPECIFIC_PASSWORD + APPLE_TEAM_ID secrets, set mac.identity to the Developer ID Application cert, and switch the dist script to dist:notarized. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 6ac72cb commit 3c8bf65

2 files changed

Lines changed: 141 additions & 0 deletions

File tree

.github/workflows/ci.yml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# CI — runs on every PR and on every push to main.
2+
# Cheap, fast checks only: typecheck + lint + Vitest unit tests.
3+
# Playwright Electron E2E is local-only per docs/eng-plan.md §1
4+
# (font antialiasing differs across CI runners and breaks pixel-diff).
5+
6+
name: CI
7+
8+
on:
9+
push:
10+
branches: [main]
11+
pull_request:
12+
branches: [main]
13+
14+
concurrency:
15+
group: ci-${{ github.ref }}
16+
cancel-in-progress: true
17+
18+
jobs:
19+
check:
20+
name: typecheck + lint + unit tests
21+
runs-on: macos-14
22+
timeout-minutes: 15
23+
24+
steps:
25+
- name: Checkout
26+
uses: actions/checkout@v5
27+
28+
- name: Set up Bun
29+
uses: oven-sh/setup-bun@v2
30+
with:
31+
bun-version: latest
32+
33+
- name: Install dependencies
34+
run: bun install --frozen-lockfile
35+
36+
- name: Typecheck
37+
run: bun run typecheck
38+
39+
- name: Lint
40+
run: bun run lint
41+
42+
- name: Format check
43+
run: bun run format:check
44+
45+
- name: Unit + integration tests
46+
run: bun run test

.github/workflows/release.yml

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# Release — builds an unsigned macOS arm64 DMG and attaches it to
2+
# the GitHub Release for the matching tag.
3+
#
4+
# Trigger: pushing a tag matching `v*.*.*` (e.g. v0.6, v0.6.1).
5+
# Manual: Actions tab → Release → Run workflow → tag name.
6+
#
7+
# Code signing + notarization is NOT done here yet (no Apple Developer
8+
# ID configured). Adding it later will mean: (1) putting the .p12 + key
9+
# password into repo secrets, (2) adding `mac.identity` env to electron-
10+
# builder, (3) the `dist:notarized` script in package.json runs instead.
11+
# Until then, the DMG is unsigned and Gatekeeper will require right-
12+
# click → Open on first launch.
13+
14+
name: Release
15+
16+
on:
17+
push:
18+
tags:
19+
- "v*.*.*"
20+
- "v*.*"
21+
workflow_dispatch:
22+
inputs:
23+
tag:
24+
description: "Release tag (e.g. v0.6.0)"
25+
required: true
26+
type: string
27+
28+
concurrency:
29+
group: release-${{ github.ref }}
30+
cancel-in-progress: false
31+
32+
jobs:
33+
build-dmg:
34+
name: Build macOS arm64 DMG
35+
runs-on: macos-14
36+
timeout-minutes: 30
37+
permissions:
38+
contents: write # gh release upload
39+
40+
steps:
41+
- name: Checkout
42+
uses: actions/checkout@v5
43+
with:
44+
ref: ${{ github.event.inputs.tag || github.ref }}
45+
46+
- name: Set up Bun
47+
uses: oven-sh/setup-bun@v2
48+
with:
49+
bun-version: latest
50+
51+
- name: Install dependencies
52+
run: bun install --frozen-lockfile
53+
54+
- name: Typecheck
55+
run: bun run typecheck
56+
57+
- name: Build renderer + main
58+
run: bun run build
59+
60+
- name: Rebuild native modules for Electron
61+
run: bun run rebuild:electron
62+
63+
- name: Build DMG (unsigned)
64+
run: bun run dist
65+
env:
66+
# Tell electron-builder explicitly: do not try to sign or notarize.
67+
CSC_IDENTITY_AUTO_DISCOVERY: "false"
68+
69+
- name: List build output
70+
run: ls -lh release-builds/
71+
72+
- name: Resolve tag name
73+
id: tag
74+
run: |
75+
if [ -n "${{ github.event.inputs.tag }}" ]; then
76+
echo "name=${{ github.event.inputs.tag }}" >> "$GITHUB_OUTPUT"
77+
else
78+
echo "name=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT"
79+
fi
80+
81+
- name: Upload DMG to GitHub Release
82+
env:
83+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
84+
run: |
85+
# Create the release if it doesn't exist yet (workflow_dispatch path),
86+
# otherwise just attach the DMG to the existing one.
87+
if ! gh release view "${{ steps.tag.outputs.name }}" >/dev/null 2>&1; then
88+
gh release create "${{ steps.tag.outputs.name }}" \
89+
--title "${{ steps.tag.outputs.name }}" \
90+
--notes "Automated build. See README for what's in this release." \
91+
--draft=false
92+
fi
93+
gh release upload "${{ steps.tag.outputs.name }}" \
94+
release-builds/Forme-*-arm64.dmg \
95+
--clobber

0 commit comments

Comments
 (0)