Skip to content

Commit 5a6f180

Browse files
Apply PR #19062: core: codesign cli on macos by building it on macos
2 parents 6732201 + 28cb8ef commit 5a6f180

3 files changed

Lines changed: 167 additions & 8 deletions

File tree

.github/workflows/publish.yml

Lines changed: 100 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ jobs:
6767
tag: ${{ steps.version.outputs.tag }}
6868
repo: ${{ steps.version.outputs.repo }}
6969

70-
build-cli:
70+
build-cli-linux-win:
7171
needs: version
7272
runs-on: blacksmith-4vcpu-ubuntu-2404
7373
if: github.repository == 'anomalyco/opencode'
@@ -94,17 +94,111 @@ jobs:
9494
OPENCODE_RELEASE: ${{ needs.version.outputs.release }}
9595
GH_REPO: ${{ needs.version.outputs.repo }}
9696
GH_TOKEN: ${{ steps.committer.outputs.token }}
97+
OPENCODE_BUILD_OS: linux,win32
98+
OPENCODE_SKIP_RELEASE_UPLOAD: "1"
99+
100+
- uses: actions/upload-artifact@v4
101+
with:
102+
name: opencode-cli-linux-win
103+
path: packages/opencode/dist
104+
105+
build-cli-darwin:
106+
needs: version
107+
runs-on: macos-latest
108+
if: github.repository == 'anomalyco/opencode'
109+
steps:
110+
- uses: actions/checkout@v3
111+
with:
112+
fetch-tags: true
113+
114+
- uses: ./.github/actions/setup-bun
115+
116+
- name: Setup git committer
117+
id: committer
118+
uses: ./.github/actions/setup-git-committer
119+
with:
120+
opencode-app-id: ${{ vars.OPENCODE_APP_ID }}
121+
opencode-app-secret: ${{ secrets.OPENCODE_APP_SECRET }}
122+
123+
- uses: apple-actions/import-codesign-certs@v2
124+
with:
125+
keychain: build
126+
p12-file-base64: ${{ secrets.APPLE_CERTIFICATE }}
127+
p12-password: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
128+
129+
- name: Resolve signing identity
130+
run: |
131+
CERT_INFO=$(security find-identity -v -p codesigning build.keychain | grep "Developer ID Application")
132+
CERT_ID=$(echo "$CERT_INFO" | awk -F'"' '{print $2}')
133+
if [ -z "$CERT_ID" ]; then
134+
echo "Developer ID Application identity not found"
135+
exit 1
136+
fi
137+
echo "CERT_ID=$CERT_ID" >> $GITHUB_ENV
138+
139+
- name: Build
140+
id: build
141+
run: |
142+
./packages/opencode/script/build.ts
143+
env:
144+
OPENCODE_VERSION: ${{ needs.version.outputs.version }}
145+
OPENCODE_RELEASE: ${{ needs.version.outputs.release }}
146+
GH_REPO: ${{ needs.version.outputs.repo }}
147+
GH_TOKEN: ${{ steps.committer.outputs.token }}
148+
APPLE_SIGNING_IDENTITY: ${{ env.CERT_ID }}
149+
OPENCODE_BUILD_OS: darwin
150+
OPENCODE_SKIP_RELEASE_UPLOAD: "1"
151+
152+
- name: Verify darwin signatures
153+
run: |
154+
for file in packages/opencode/dist/opencode-darwin-*/bin/opencode; do
155+
codesign -vvv --verify "$file"
156+
done
157+
158+
- uses: actions/upload-artifact@v4
159+
with:
160+
name: opencode-cli-darwin
161+
path: packages/opencode/dist
162+
163+
build-cli-merge:
164+
needs:
165+
- version
166+
- build-cli-linux-win
167+
- build-cli-darwin
168+
runs-on: blacksmith-4vcpu-ubuntu-2404
169+
if: github.repository == 'anomalyco/opencode'
170+
steps:
171+
- uses: actions/checkout@v3
172+
173+
- uses: ./.github/actions/setup-bun
174+
175+
- name: Setup git committer
176+
id: committer
177+
uses: ./.github/actions/setup-git-committer
178+
with:
179+
opencode-app-id: ${{ vars.OPENCODE_APP_ID }}
180+
opencode-app-secret: ${{ secrets.OPENCODE_APP_SECRET }}
181+
182+
- uses: actions/download-artifact@v4
183+
with:
184+
pattern: opencode-cli-*
185+
path: packages/opencode/dist
186+
merge-multiple: true
187+
188+
- name: Upload CLI release assets
189+
if: needs.version.outputs.release
190+
run: gh release upload v${{ needs.version.outputs.version }} ./packages/opencode/dist/*.zip ./packages/opencode/dist/*.tar.gz --clobber --repo ${{ needs.version.outputs.repo }}
191+
env:
192+
GH_TOKEN: ${{ steps.committer.outputs.token }}
97193

98194
- uses: actions/upload-artifact@v4
99195
with:
100196
name: opencode-cli
101197
path: packages/opencode/dist
102-
outputs:
103-
version: ${{ needs.version.outputs.version }}
104198

105199
build-tauri:
106200
needs:
107-
- build-cli
201+
- build-cli-merge
108202
- version
109203
continue-on-error: false
110204
strategy:
@@ -248,7 +342,7 @@ jobs:
248342

249343
build-electron:
250344
needs:
251-
- build-cli
345+
- build-cli-merge
252346
- version
253347
continue-on-error: false
254348
strategy:
@@ -372,7 +466,7 @@ jobs:
372466
publish:
373467
needs:
374468
- version
375-
- build-cli
469+
- build-cli-merge
376470
- build-tauri
377471
- build-electron
378472
runs-on: blacksmith-4vcpu-ubuntu-2404

packages/opencode/script/build.ts

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ console.log(`Loaded ${migrations.length} migrations`)
6363
const singleFlag = process.argv.includes("--single")
6464
const baselineFlag = process.argv.includes("--baseline")
6565
const skipInstall = process.argv.includes("--skip-install")
66+
const skipUpload = process.argv.includes("--skip-release-upload") || process.env.OPENCODE_SKIP_RELEASE_UPLOAD === "1"
67+
const sign = process.env.APPLE_SIGNING_IDENTITY
68+
const entitlements = process.env.OPENCODE_CODESIGN_ENTITLEMENTS || path.join(dir, "script/entitlements.plist")
69+
const raw = process.env.OPENCODE_BUILD_OS?.trim()
6670

6771
const allTargets: {
6872
os: string
@@ -148,14 +152,39 @@ const targets = singleFlag
148152
})
149153
: allTargets
150154

155+
const os = raw
156+
? Array.from(
157+
new Set(
158+
raw
159+
.split(",")
160+
.map((x) => x.trim())
161+
.filter(Boolean),
162+
),
163+
)
164+
: undefined
165+
166+
if (os) {
167+
const set = new Set(allTargets.map((item) => item.os))
168+
const bad = os.filter((item) => !set.has(item))
169+
if (bad.length > 0) {
170+
throw new Error(`Invalid OPENCODE_BUILD_OS value: ${bad.join(", ")}`)
171+
}
172+
}
173+
174+
const list = os ? targets.filter((item) => os.includes(item.os)) : targets
175+
176+
if (list.length === 0) {
177+
throw new Error("No build targets selected")
178+
}
179+
151180
await $`rm -rf dist`
152181

153182
const binaries: Record<string, string> = {}
154183
if (!skipInstall) {
155184
await $`bun install --os="*" --cpu="*" @opentui/core@${pkg.dependencies["@opentui/core"]}`
156185
await $`bun install --os="*" --cpu="*" @parcel/watcher@${pkg.dependencies["@parcel/watcher"]}`
157186
}
158-
for (const item of targets) {
187+
for (const item of list) {
159188
const name = [
160189
pkg.name,
161190
// changing to win32 flags npm for some reason
@@ -203,6 +232,24 @@ for (const item of targets) {
203232
},
204233
})
205234

235+
if (item.os === "darwin") {
236+
if (Script.release && process.platform !== "darwin") {
237+
throw new Error("darwin release binaries must be built on macOS runners")
238+
}
239+
if (Script.release && !sign) {
240+
throw new Error("APPLE_SIGNING_IDENTITY is required for darwin release binaries")
241+
}
242+
if (process.platform === "darwin" && sign) {
243+
if (!fs.existsSync(entitlements)) {
244+
throw new Error(`Codesign entitlements file not found: ${entitlements}`)
245+
}
246+
const file = `dist/${name}/bin/opencode`
247+
console.log(`codesigning ${name}`)
248+
await $`codesign --entitlements ${entitlements} -vvvv --deep --sign ${sign} ${file} --force`
249+
await $`codesign -vvv --verify ${file}`
250+
}
251+
}
252+
206253
// Smoke test: only run if binary is for current platform
207254
if (item.os === process.platform && item.arch === process.arch && !item.abi) {
208255
const binaryPath = `dist/${name}/bin/opencode`
@@ -240,7 +287,9 @@ if (Script.release) {
240287
await $`zip -r ../../${key}.zip *`.cwd(`dist/${key}/bin`)
241288
}
242289
}
243-
await $`gh release upload v${Script.version} ./dist/*.zip ./dist/*.tar.gz --clobber --repo ${process.env.GH_REPO}`
290+
if (!skipUpload) {
291+
await $`gh release upload v${Script.version} ./dist/*.zip ./dist/*.tar.gz --clobber --repo ${process.env.GH_REPO}`
292+
}
244293
}
245294

246295
export { binaries }
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>com.apple.security.cs.allow-jit</key>
6+
<true/>
7+
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
8+
<true/>
9+
<key>com.apple.security.cs.disable-executable-page-protection</key>
10+
<true/>
11+
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
12+
<true/>
13+
<key>com.apple.security.cs.disable-library-validation</key>
14+
<true/>
15+
</dict>
16+
</plist>

0 commit comments

Comments
 (0)