@@ -15,6 +15,10 @@ concurrency:
15
15
group : ${{ github.workflow }}
16
16
cancel-in-progress : true
17
17
18
+ env :
19
+ APPLE_CERTIFICATE : ${{ secrets.APPLE_CERTIFICATE_P12 }}
20
+ APPLE_CERTIFICATE_PASSWORD : ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
21
+
18
22
jobs :
19
23
tag-check :
20
24
runs-on : ubuntu-latest
47
51
48
52
build :
49
53
needs : tag-check
50
- name : ${{ matrix.runner }} - ${{ matrix.target }}
54
+ name : Build - ${{ matrix.runner }} - ${{ matrix.target }}
51
55
runs-on : ${{ matrix.runner }}
52
56
timeout-minutes : 30
53
57
defaults :
@@ -94,11 +98,117 @@ jobs:
94
98
- if : ${{ matrix.target == 'x86_64-unknown-linux-musl' || matrix.target == 'aarch64-unknown-linux-musl'}}
95
99
name : Install musl build tools
96
100
run : |
97
- sudo apt install -y musl-tools pkg-config
101
+ sudo apt-get update
102
+ sudo apt-get install -y musl-tools pkg-config
98
103
99
104
- name : Cargo build
100
105
run : cargo build --target ${{ matrix.target }} --release --bin codex --bin codex-responses-api-proxy
101
106
107
+ - if : ${{ matrix.runner == 'macos-14' }}
108
+ name : Configure Apple code signing
109
+ shell : bash
110
+ env :
111
+ KEYCHAIN_PASSWORD : actions
112
+ run : |
113
+ set -euo pipefail
114
+
115
+ if [[ -z "${APPLE_CERTIFICATE:-}" ]]; then
116
+ echo "APPLE_CERTIFICATE is required for macOS signing"
117
+ exit 1
118
+ fi
119
+
120
+ if [[ -z "${APPLE_CERTIFICATE_PASSWORD:-}" ]]; then
121
+ echo "APPLE_CERTIFICATE_PASSWORD is required for macOS signing"
122
+ exit 1
123
+ fi
124
+
125
+ cert_path="${RUNNER_TEMP}/apple_signing_certificate.p12"
126
+ echo "$APPLE_CERTIFICATE" | base64 -d > "$cert_path"
127
+
128
+ keychain_path="${RUNNER_TEMP}/codex-signing.keychain-db"
129
+ security create-keychain -p "$KEYCHAIN_PASSWORD" "$keychain_path"
130
+ security set-keychain-settings -lut 21600 "$keychain_path"
131
+ security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$keychain_path"
132
+
133
+ keychain_args=()
134
+ cleanup_keychain() {
135
+ if ((${#keychain_args[@]} > 0)); then
136
+ security list-keychains -s "${keychain_args[@]}" || true
137
+ security default-keychain -s "${keychain_args[0]}" || true
138
+ else
139
+ security list-keychains -s || true
140
+ fi
141
+ if [[ -f "$keychain_path" ]]; then
142
+ security delete-keychain "$keychain_path" || true
143
+ fi
144
+ }
145
+
146
+ while IFS= read -r keychain; do
147
+ [[ -n "$keychain" ]] && keychain_args+=("$keychain")
148
+ done < <(security list-keychains | sed 's/^[[:space:]]*//;s/[[:space:]]*$//;s/"//g')
149
+
150
+ if ((${#keychain_args[@]} > 0)); then
151
+ security list-keychains -s "$keychain_path" "${keychain_args[@]}"
152
+ else
153
+ security list-keychains -s "$keychain_path"
154
+ fi
155
+
156
+ security default-keychain -s "$keychain_path"
157
+ security import "$cert_path" -k "$keychain_path" -P "$APPLE_CERTIFICATE_PASSWORD" -T /usr/bin/codesign -T /usr/bin/security
158
+ security set-key-partition-list -S apple-tool:,apple: -s -k "$KEYCHAIN_PASSWORD" "$keychain_path" > /dev/null
159
+
160
+ codesign_hashes=()
161
+ while IFS= read -r hash; do
162
+ [[ -n "$hash" ]] && codesign_hashes+=("$hash")
163
+ done < <(security find-identity -v -p codesigning "$keychain_path" \
164
+ | sed -n 's/.*\([0-9A-F]\{40\}\).*/\1/p' \
165
+ | sort -u)
166
+
167
+ if ((${#codesign_hashes[@]} == 0)); then
168
+ echo "No signing identities found in $keychain_path"
169
+ cleanup_keychain
170
+ rm -f "$cert_path"
171
+ exit 1
172
+ fi
173
+
174
+ if ((${#codesign_hashes[@]} > 1)); then
175
+ echo "Multiple signing identities found in $keychain_path:"
176
+ printf ' %s\n' "${codesign_hashes[@]}"
177
+ cleanup_keychain
178
+ rm -f "$cert_path"
179
+ exit 1
180
+ fi
181
+
182
+ APPLE_CODESIGN_IDENTITY="${codesign_hashes[0]}"
183
+ # export APPLE_CODESIGN_IDENTITY
184
+ # echo "Resolved codesign identity: $APPLE_CODESIGN_IDENTITY"
185
+
186
+ rm -f "$cert_path"
187
+
188
+ echo "APPLE_CODESIGN_IDENTITY=$APPLE_CODESIGN_IDENTITY" >> "$GITHUB_ENV"
189
+ echo "APPLE_CODESIGN_KEYCHAIN=$keychain_path" >> "$GITHUB_ENV"
190
+
191
+ - if : ${{ matrix.runner == 'macos-14' }}
192
+ name : Sign macOS binaries
193
+ shell : bash
194
+ run : |
195
+ set -euo pipefail
196
+
197
+ if [[ -z "${APPLE_CODESIGN_IDENTITY:-}" ]]; then
198
+ echo "APPLE_CODESIGN_IDENTITY is required for macOS signing"
199
+ exit 1
200
+ fi
201
+
202
+ keychain_args=()
203
+ if [[ -n "${APPLE_CODESIGN_KEYCHAIN:-}" && -f "${APPLE_CODESIGN_KEYCHAIN}" ]]; then
204
+ keychain_args+=(--keychain "${APPLE_CODESIGN_KEYCHAIN}")
205
+ fi
206
+
207
+ for binary in codex codex-responses-api-proxy; do
208
+ path="target/${{ matrix.target }}/release/${binary}"
209
+ codesign --force --options runtime --timestamp --sign "$APPLE_CODESIGN_IDENTITY" "${keychain_args[@]}" "$path"
210
+ done
211
+
102
212
- name : Stage artifacts
103
213
shell : bash
104
214
run : |
@@ -157,6 +267,29 @@ jobs:
157
267
zstd -T0 -19 --rm "$dest/$base"
158
268
done
159
269
270
+ - name : Remove signing keychain
271
+ if : ${{ always() && matrix.runner == 'macos-14' }}
272
+ shell : bash
273
+ env :
274
+ APPLE_CODESIGN_KEYCHAIN : ${{ env.APPLE_CODESIGN_KEYCHAIN }}
275
+ run : |
276
+ set -euo pipefail
277
+ if [[ -n "${APPLE_CODESIGN_KEYCHAIN:-}" ]]; then
278
+ keychain_args=()
279
+ while IFS= read -r keychain; do
280
+ [[ "$keychain" == "$APPLE_CODESIGN_KEYCHAIN" ]] && continue
281
+ [[ -n "$keychain" ]] && keychain_args+=("$keychain")
282
+ done < <(security list-keychains | sed 's/^[[:space:]]*//;s/[[:space:]]*$//;s/"//g')
283
+ if ((${#keychain_args[@]} > 0)); then
284
+ security list-keychains -s "${keychain_args[@]}"
285
+ security default-keychain -s "${keychain_args[0]}"
286
+ fi
287
+
288
+ if [[ -f "$APPLE_CODESIGN_KEYCHAIN" ]]; then
289
+ security delete-keychain "$APPLE_CODESIGN_KEYCHAIN"
290
+ fi
291
+ fi
292
+
160
293
- uses : actions/upload-artifact@v4
161
294
with :
162
295
name : ${{ matrix.target }}
0 commit comments