Repository navigation
164 lines (144 loc) · 6.27 KB
/
Copy path_native-build.yml
File metadata and controls
164 lines (144 loc) · 6.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
name: _native-build
on:
workflow_call:
inputs:
upload-artifact-prefix:
description: 'Prefix for uploaded artifact name'
required: false
type: string
default: 'pythinker-code-native'
retention-days:
description: 'Artifact retention in days'
required: false
type: number
default: 3
sign-macos:
description: 'Whether to sign + notarize macOS builds (requires Apple secrets)'
required: false
type: boolean
default: false
sign-windows:
description: 'Whether to sign Windows builds with Azure Artifact Signing (requires AZURE_* secrets and AZURE_TRUSTED_SIGNING_* variables)'
required: false
type: boolean
default: false
secrets:
APPLE_CERTIFICATE_P12:
required: false
APPLE_CERTIFICATE_PASSWORD:
required: false
APPLE_NOTARIZATION_KEY_P8:
required: false
APPLE_NOTARIZATION_KEY_ID:
required: false
APPLE_NOTARIZATION_ISSUER_ID:
required: false
AZURE_TENANT_ID:
required: false
AZURE_CLIENT_ID:
required: false
AZURE_CLIENT_SECRET:
required: false
permissions:
contents: read
id-token: write
attestations: write
artifact-metadata: write
jobs:
native-bundle:
name: Native bundle (${{ matrix.target }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-24.04
target: linux-x64
- os: ubuntu-24.04-arm
target: linux-arm64
- os: macos-15-intel
target: darwin-x64
- os: macos-15
target: darwin-arm64
- os: windows-2025-vs2026
target: win32-x64
- os: windows-11-arm
target: win32-arm64
env:
# secrets.* isn't allowed in `if:` conditions, so resolve the effective
# signing gate here (job-level env does allow secrets) and branch on the
# env var in steps below. A requested release signature is fail-closed.
APPLE_SIGNING_AVAILABLE: ${{ inputs.sign-macos && secrets.APPLE_CERTIFICATE_P12 != '' && secrets.APPLE_CERTIFICATE_PASSWORD != '' && secrets.APPLE_NOTARIZATION_KEY_P8 != '' && secrets.APPLE_NOTARIZATION_KEY_ID != '' && secrets.APPLE_NOTARIZATION_ISSUER_ID != '' }}
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pinned from v6.0.2
with:
persist-credentials: false
- name: Setup pnpm
uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # pinned from v6
- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # pinned from v7.0.0
with:
node-version-file: .nvmrc
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Require macOS signing secrets
if: runner.os == 'macOS' && inputs.sign-macos && env.APPLE_SIGNING_AVAILABLE != 'true'
run: |
echo "::error::A signed release requires every APPLE_CERTIFICATE_* and APPLE_NOTARIZATION_* secret."
exit 1
- name: Setup macOS keychain (release only)
if: runner.os == 'macOS' && env.APPLE_SIGNING_AVAILABLE == 'true'
uses: ./.github/actions/macos-keychain-setup
with:
certificate-p12: ${{ secrets.APPLE_CERTIFICATE_P12 }}
certificate-password: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
- name: Generate built-in catalog (release artifacts)
if: inputs.sign-macos
shell: bash
run: |
CATALOG_FILE="$RUNNER_TEMP/pythinker-code-built-in-catalog.json"
node apps/pythinker-code/scripts/update-catalog.mjs --out "$CATALOG_FILE"
echo "PYTHINKER_CODE_BUILT_IN_CATALOG_FILE=$CATALOG_FILE" >> "$GITHUB_ENV"
- name: Build Pythinker web assets
# The SEA blob step embeds apps/pythinker-code/dist-web. This repo keeps
# the web source (apps/pythinker-web), so build it and stage the bundle.
run: |
pnpm --filter @pymodel/pythinker-web run build
node apps/pythinker-code/scripts/copy-web-assets.mjs
- name: Build native executable (release profile, macOS signed)
if: runner.os == 'macOS' && env.APPLE_SIGNING_AVAILABLE == 'true'
run: pnpm --filter @pymodel/pythinker-code run build:native:release
- name: Build native executable (local profile)
if: '!(runner.os == ''macOS'' && env.APPLE_SIGNING_AVAILABLE == ''true'')'
run: pnpm --filter @pymodel/pythinker-code run build:native:sea
- name: Notarize macOS binary
if: runner.os == 'macOS' && env.APPLE_SIGNING_AVAILABLE == 'true'
uses: ./.github/actions/macos-notarize
with:
binary-path: ${{ github.workspace }}/apps/pythinker-code/dist-native/bin/${{ matrix.target }}/pythinker
notarization-key-p8: ${{ secrets.APPLE_NOTARIZATION_KEY_P8 }}
notarization-key-id: ${{ secrets.APPLE_NOTARIZATION_KEY_ID }}
notarization-issuer-id: ${{ secrets.APPLE_NOTARIZATION_ISSUER_ID }}
- name: Cleanup macOS keychain
if: always() && runner.os == 'macOS' && env.APPLE_SIGNING_AVAILABLE == 'true'
uses: ./.github/actions/macos-keychain-cleanup
- name: Smoke test native executable
run: pnpm --filter @pymodel/pythinker-code run test:native:smoke
- name: Package native artifact
run: pnpm --filter @pymodel/pythinker-code run package:native
- name: Attest native zip provenance
if: inputs.sign-macos
uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # pinned from v4.2.2
with:
subject-path: apps/pythinker-code/dist-native/artifacts/pythinker-code-${{ matrix.target }}.zip
- name: Upload native artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # pinned from v7
with:
name: ${{ inputs.upload-artifact-prefix }}-${{ matrix.target }}
retention-days: ${{ inputs.retention-days }}
path: |
apps/pythinker-code/dist-native/artifacts/pythinker-code-${{ matrix.target }}.zip
apps/pythinker-code/dist-native/artifacts/pythinker-code-${{ matrix.target }}.zip.sha256
if-no-files-found: error