Skip to content

Commit f5e6178

Browse files
committed
add creds
1 parent 9ff9b27 commit f5e6178

File tree

4 files changed

+96
-97
lines changed

4 files changed

+96
-97
lines changed

README.md

Lines changed: 71 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,63 @@ pnpm run make
3232
pnpm run check:write # Linting & typecheck
3333
```
3434

35+
### Liquid Glass Icon (macOS 26+)
36+
37+
The app supports macOS liquid glass icons for a modern, layered appearance. The icon configuration is in `build/icon.icon/`.
38+
39+
**Compiling the liquid glass icon requires Xcode** (Command Line Tools are not sufficient):
40+
41+
```bash
42+
# Compile liquid glass icon (requires Xcode)
43+
bash scripts/compile-glass-icon.sh
44+
```
45+
46+
If you don't have Xcode installed, the build will automatically fall back to the standard `.icns` icon. To enable liquid glass icons:
47+
48+
1. Install Xcode from the App Store
49+
2. Run the compile script above, or
50+
3. Compile `Assets.car` on a machine with Xcode and commit it to the repo
51+
52+
The `generateAssets` hook will automatically attempt to compile the icon during packaging if Xcode is available.
53+
54+
### Environment Variables
55+
56+
You can set these environment variables instead of entering credentials in the app:
57+
58+
- `POSTHOG_API_KEY` - Your PostHog personal API key
59+
- `POSTHOG_API_HOST` - PostHog instance URL (defaults to https://us.posthog.com)
60+
61+
## Architecture
62+
63+
- **Electron** - Desktop app framework
64+
- **React** - UI framework
65+
- **TypeScript** - Type safety
66+
- **Tailwind CSS** - Styling
67+
- **Zustand** - State management - we should probably switch to kea
68+
- **Vite** - Build tool
69+
70+
## Project Structure
71+
72+
```
73+
array/
74+
├── src/
75+
│ ├── main/ # Electron main process
76+
│ ├── renderer/ # React app
77+
│ ├── api/ # API client
78+
│ └── shared/ # Shared types
79+
├── dist/ # Build output
80+
└── release/ # Packaged apps
81+
```
82+
83+
## Keyboard Shortcuts
84+
85+
- `↑/↓` - Navigate tasks
86+
- `Enter` - Open selected task
87+
- `⌘R` - Refresh task list
88+
- `⌘⇧[/]` - Switch between tabs
89+
- `⌘W` - Close current tab
90+
91+
3592
### Building Distributables
3693

3794
To create production distributables (DMG, ZIP):
@@ -69,86 +126,38 @@ Set `ELECTRON_DISABLE_AUTO_UPDATE=1` if you ever need to ship a build with auto
69126

70127
### macOS Code Signing & Notarization
71128

72-
macOS builds are automatically signed (and optionally notarized) when the relevant environment variables are present. We standardise on Apple ID + app-specific password credentials for notarization:
129+
macOS packages are signed and notarized automatically when these environment variables are present:
73130

74131
```bash
75-
# Required for code signing
76132
export APPLE_CODESIGN_IDENTITY="Developer ID Application: Your Name (TEAMID)"
77-
78-
# Notarytool authentication
79133
export APPLE_ID="[email protected]"
80134
export APPLE_APP_SPECIFIC_PASSWORD="xxxx-xxxx-xxxx-xxxx"
81135
export APPLE_TEAM_ID="TEAMID"
82136
```
83137

84-
The signing step uses hardened runtime with the entitlements in `build/entitlements.mac.plist` and will sign the DMG plus the zipped `.app`. When the notarization variables are present, packages are also notarized. Without these variables the build proceeds unsigned, which is convenient for local development.
85-
86-
For CI releases, add the same values as GitHub Actions repository secrets:
138+
For CI releases, configure matching GitHub Actions secrets:
87139

88140
- `APPLE_CODESIGN_IDENTITY`
89141
- `APPLE_ID`
90142
- `APPLE_APP_SPECIFIC_PASSWORD`
91143
- `APPLE_TEAM_ID`
92-
- `APPLE_CODESIGN_CERT_BASE64` - Base64 encoded `.p12` export of your Developer ID Application certificate
93-
- `APPLE_CODESIGN_CERT_PASSWORD` - Password used when exporting the `.p12`
94-
- `APPLE_CODESIGN_KEYCHAIN_PASSWORD` - Password for the temporary keychain created in CI
95-
96-
The `Publish Release` workflow will automatically sign and notarize when these secrets are present.
97-
98-
> If you prefer API-key or keychain profile credentials for notarization, the Forge configuration already supports them—add the matching env vars locally and in CI instead of the defaults above.
99-
100-
### Liquid Glass Icon (macOS 26+)
144+
- `APPLE_CODESIGN_CERT_BASE64` – Base64-encoded `.p12` export of the Developer ID Application certificate (include the private key)
145+
- `APPLE_CODESIGN_CERT_PASSWORD` – Password used when exporting the `.p12`
146+
- `APPLE_CODESIGN_KEYCHAIN_PASSWORD` – Password for the temporary keychain the workflow creates on the runner
101147

102-
The app supports macOS liquid glass icons for a modern, layered appearance. The icon configuration is in `build/icon.icon/`.
148+
The `Publish Release` workflow imports the certificate into a temporary keychain, signs each artifact with hardened runtime enabled (using Electron’s default entitlements), and notarizes it before upload whenever these secrets are available.
103149

104-
**Compiling the liquid glass icon requires Xcode** (Command Line Tools are not sufficient):
150+
For local testing, copy `codesign.env.example` to `.env.codesign`, fill in the real values, and load it before running `pnpm run make`:
105151

106152
```bash
107-
# Compile liquid glass icon (requires Xcode)
108-
bash scripts/compile-glass-icon.sh
153+
set -a
154+
source .env.codesign
155+
set +a
156+
pnpm run make
109157
```
110158

111-
If you don't have Xcode installed, the build will automatically fall back to the standard `.icns` icon. To enable liquid glass icons:
112-
113-
1. Install Xcode from the App Store
114-
2. Run the compile script above, or
115-
3. Compile `Assets.car` on a machine with Xcode and commit it to the repo
116-
117-
The `generateAssets` hook will automatically attempt to compile the icon during packaging if Xcode is available.
118-
119-
### Environment Variables
120-
121-
You can set these environment variables instead of entering credentials in the app:
122-
123-
- `POSTHOG_API_KEY` - Your PostHog personal API key
124-
- `POSTHOG_API_HOST` - PostHog instance URL (defaults to https://us.posthog.com)
125-
126-
## Architecture
159+
Set `SKIP_NOTARIZE=1` if you need to generate signed artifacts without submitting to Apple (e.g., while debugging credentials):
127160

128-
- **Electron** - Desktop app framework
129-
- **React** - UI framework
130-
- **TypeScript** - Type safety
131-
- **Tailwind CSS** - Styling
132-
- **Zustand** - State management - we should probably switch to kea
133-
- **Vite** - Build tool
134-
135-
## Project Structure
136-
137-
```
138-
array/
139-
├── src/
140-
│ ├── main/ # Electron main process
141-
│ ├── renderer/ # React app
142-
│ ├── api/ # API client
143-
│ └── shared/ # Shared types
144-
├── dist/ # Build output
145-
└── release/ # Packaged apps
161+
```bash
162+
SKIP_NOTARIZE=1 pnpm run make
146163
```
147-
148-
## Keyboard Shortcuts
149-
150-
- `↑/↓` - Navigate tasks
151-
- `Enter` - Open selected task
152-
- `⌘R` - Refresh task list
153-
- `⌘⇧[/]` - Switch between tabs
154-
- `⌘W` - Close current tab

build/entitlements.mac.plist

Lines changed: 0 additions & 16 deletions
This file was deleted.

codesign.env.example

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Developer ID signing / notarization credentials
2+
# Copy this file to `.env.codesign` (or similar) and fill in real values.
3+
4+
APPLE_CODESIGN_IDENTITY="Developer ID Application: Your Name (TEAMID)"
5+
6+
APPLE_APP_SPECIFIC_PASSWORD="xxxx-xxxx-xxxx-xxxx"
7+
APPLE_TEAM_ID="TEAMID"
8+
9+
APPLE_CODESIGN_CERT_BASE64="xxx"
10+
APPLE_CODESIGN_CERT_PASSWORD="xxx"
11+
APPLE_CODESIGN_KEYCHAIN_PASSWORD="xxx"

forge.config.ts

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { execSync } from "node:child_process";
22
import { cpSync, existsSync, mkdirSync, rmSync } from "node:fs";
33
import path from "node:path";
4-
import type { SignOptions } from "@electron/osx-sign";
54
import { MakerDMG } from "@electron-forge/maker-dmg";
65
import { MakerZIP } from "@electron-forge/maker-zip";
76
import { VitePlugin } from "@electron-forge/plugin-vite";
@@ -19,8 +18,8 @@ const appleApiIssuer = process.env.APPLE_API_ISSUER;
1918
const appleNotarizeKeychainProfile =
2019
process.env.APPLE_NOTARIZE_KEYCHAIN_PROFILE;
2120
const appleNotarizeKeychain = process.env.APPLE_NOTARIZE_KEYCHAIN;
22-
const entitlementsPath = path.resolve("build", "entitlements.mac.plist");
2321
const shouldSignMacApp = Boolean(appleCodesignIdentity);
22+
const skipNotarize = process.env.SKIP_NOTARIZE === "1";
2423

2524
type NotaryToolCredentials =
2625
| {
@@ -38,39 +37,35 @@ type NotaryToolCredentials =
3837
keychain?: string;
3938
};
4039

41-
let notaryToolCredentials: NotaryToolCredentials | undefined;
40+
let notarizeCredentials: NotaryToolCredentials | undefined;
4241

4342
if (appleId && appleIdPassword && appleTeamId) {
44-
notaryToolCredentials = {
45-
appleId,
46-
appleIdPassword,
47-
teamId: appleTeamId,
43+
notarizeCredentials = {
44+
appleId: appleId!,
45+
appleIdPassword: appleIdPassword!,
46+
teamId: appleTeamId!,
4847
};
4948
} else if (appleApiKey && appleApiKeyId && appleApiIssuer) {
50-
notaryToolCredentials = {
49+
notarizeCredentials = {
5150
appleApiKey,
5251
appleApiKeyId,
5352
appleApiIssuer,
5453
};
5554
} else if (appleNotarizeKeychainProfile) {
56-
notaryToolCredentials = {
55+
notarizeCredentials = {
5756
keychainProfile: appleNotarizeKeychainProfile,
5857
...(appleNotarizeKeychain ? { keychain: appleNotarizeKeychain } : {}),
5958
};
6059
}
6160

6261
const notarizeConfig =
63-
shouldSignMacApp && notaryToolCredentials ? notaryToolCredentials : undefined;
64-
65-
// Apply custom entitlements across the app bundle during signing.
66-
const osxSignConfig: SignOptions | undefined = shouldSignMacApp
67-
? {
62+
!skipNotarize && shouldSignMacApp && notarizeCredentials
63+
? notarizeCredentials
64+
: undefined;
65+
const osxSignConfig = shouldSignMacApp
66+
? ({
6867
identity: appleCodesignIdentity!,
69-
optionsForFile: () => ({
70-
entitlements: entitlementsPath,
71-
hardenedRuntime: true,
72-
}),
73-
}
68+
} satisfies Record<string, unknown>)
7469
: undefined;
7570

7671
function copyNativeDependency(

0 commit comments

Comments
 (0)