|
1
|
name: "Release Siti AI Windows Microsoft Store" |
|
2
|
|
|
3
|
on: |
|
4
|
push: |
|
5
|
branches: |
|
6
|
- release/windows-microsoft-store |
|
7
|
workflow_dispatch: |
|
8
|
|
|
9
|
# Push to the release branch above to build, sign, and draft-release the |
|
10
|
# Windows Microsoft Store artifacts. The signed .msi/.exe are for direct |
|
11
|
# download; the MSIX is what gets submitted to Partner Center (the Store |
|
12
|
# re-signs it), which is the only form that carries the package identity Store |
|
13
|
# services need. |
|
14
|
jobs: |
|
15
|
publish-tauri: |
|
16
|
permissions: |
|
17
|
contents: write |
|
18
|
runs-on: windows-latest |
|
19
|
# Job-level env so the MSIX steps' own `if:` conditions can read these. |
|
20
|
# When the MSIX identity secrets are absent the MSIX steps skip and the |
|
21
|
# signed .msi/.exe still ship. |
|
22
|
env: |
|
23
|
MSIX_PUBLISHER: ${{ secrets.MSIX_PUBLISHER }} |
|
24
|
MSIX_IDENTITY_NAME: ${{ secrets.MSIX_IDENTITY_NAME }} |
|
25
|
steps: |
|
26
|
- uses: actions/checkout@v7 |
|
27
|
|
|
28
|
- name: setup node |
|
29
|
uses: actions/setup-node@v7 |
|
30
|
with: |
|
31
|
node-version: 22 |
|
32
|
|
|
33
|
# No version pin: reads the exact pnpm from package.json's |
|
34
|
# packageManager field (pnpm@11.8.0), matching ci.yml. |
|
35
|
- uses: pnpm/action-setup@v6 |
|
36
|
|
|
37
|
- name: Install Rust stable |
|
38
|
uses: dtolnay/rust-toolchain@stable |
|
39
|
|
|
40
|
# The full dependency tree build is slow cold. Cache the cargo registry |
|
41
|
# and target/ keyed on Cargo.lock so a repeat run (a manifest tweak, |
|
42
|
# another Partner Center validation round) restores in minutes instead of |
|
43
|
# rebuilding from scratch. |
|
44
|
- name: Cache Rust build |
|
45
|
uses: Swatinem/rust-cache@v2 |
|
46
|
with: |
|
47
|
workspaces: src-tauri |
|
48
|
|
|
49
|
# The enabled Windows chat backend pulls in native crypto/C dependencies. |
|
50
|
# NASM keeps their x64 assembly path available on the Windows runner. |
|
51
|
- name: Install NASM |
|
52
|
run: choco install nasm -y --no-progress |
|
53
|
shell: pwsh |
|
54
|
|
|
55
|
# Validate the MSIX manifest before the long Rust build rather than after |
|
56
|
# it. makeappx checks the manifest against its schema regardless of what |
|
57
|
# the payload files contain, so a stub exe is enough to catch a schema |
|
58
|
# error in seconds instead of after a full build. Skipped when the MSIX |
|
59
|
# secrets are absent so the .msi/.exe build still ships. |
|
60
|
- name: Validate MSIX manifest (fast fail) |
|
61
|
if: ${{ env.MSIX_PUBLISHER != '' && env.MSIX_IDENTITY_NAME != '' }} |
|
62
|
shell: pwsh |
|
63
|
run: ./scripts/build-msix.ps1 -ValidateOnly |
|
64
|
|
|
65
|
- name: Install frontend dependencies |
|
66
|
run: pnpm install --frozen-lockfile |
|
67
|
|
|
68
|
- name: Patch src-tauri/.cargo/config.toml for native Windows build |
|
69
|
shell: pwsh |
|
70
|
run: | |
|
71
|
# The .cargo/config.toml is authored for macOS hosts: the [env] |
|
72
|
# section force-sets CC/CXX to /usr/bin/clang and a macOS deployment |
|
73
|
# target, none of which exist on this runner. Strip that section so |
|
74
|
# Rust falls back to the runner's native MSVC toolchain. The |
|
75
|
# per-Apple-target and Android sections are inert here and left alone. |
|
76
|
$path = "src-tauri/.cargo/config.toml" |
|
77
|
if (Test-Path $path) { |
|
78
|
$lines = Get-Content $path |
|
79
|
$out = [System.Collections.Generic.List[string]]::new() |
|
80
|
$skipSection = $false |
|
81
|
|
|
82
|
foreach ($line in $lines) { |
|
83
|
if ($line -match '^\[env\]') { |
|
84
|
$skipSection = $true |
|
85
|
continue |
|
86
|
} |
|
87
|
if ($skipSection -and $line -match '^\[') { |
|
88
|
$skipSection = $false |
|
89
|
} |
|
90
|
if (-not $skipSection) { |
|
91
|
$out.Add($line) |
|
92
|
} |
|
93
|
} |
|
94
|
|
|
95
|
$out | Set-Content $path -Encoding UTF8 |
|
96
|
Write-Host "Patched src-tauri/.cargo/config.toml — removed macOS-only [env] section" |
|
97
|
} else { |
|
98
|
Write-Host "No src-tauri/.cargo/config.toml to patch" |
|
99
|
} |
|
100
|
|
|
101
|
- name: Setup MSVC developer environment |
|
102
|
uses: ilammy/msvc-dev-cmd@v1 |
|
103
|
|
|
104
|
# Fail before the long Windows build if SSL.com signing credentials are |
|
105
|
# not available to this run. GitHub substitutes absent secrets as empty |
|
106
|
# strings, which otherwise surfaces only after the artifacts are built. |
|
107
|
- name: Validate code-signing secrets |
|
108
|
shell: pwsh |
|
109
|
env: |
|
110
|
ES_USERNAME: ${{ secrets.ES_USERNAME }} |
|
111
|
ES_PASSWORD: ${{ secrets.ES_PASSWORD }} |
|
112
|
ES_CREDENTIAL_ID: ${{ secrets.ES_CREDENTIAL_ID }} |
|
113
|
ES_TOTP_SECRET: ${{ secrets.ES_TOTP_SECRET }} |
|
114
|
run: | |
|
115
|
$required = @( |
|
116
|
"ES_USERNAME", |
|
117
|
"ES_PASSWORD", |
|
118
|
"ES_CREDENTIAL_ID", |
|
119
|
"ES_TOTP_SECRET" |
|
120
|
) |
|
121
|
$missing = $required | Where-Object { |
|
122
|
[string]::IsNullOrWhiteSpace([Environment]::GetEnvironmentVariable($_)) |
|
123
|
} |
|
124
|
if ($missing.Count -gt 0) { |
|
125
|
throw "Missing required GitHub Actions secret(s): $($missing -join ', '). Configure them under Settings > Secrets and variables > Actions." |
|
126
|
} |
|
127
|
|
|
128
|
- name: Build App |
|
129
|
shell: pwsh |
|
130
|
run: | |
|
131
|
pnpm tauri build -c src-tauri/tauri.prod-windows-microsoftstore.conf.json |
|
132
|
# Move installer artifacts to a dedicated input directory for |
|
133
|
# CodeSignTool. The MSIX is packed separately below and deliberately |
|
134
|
# left unsigned for Partner Center. |
|
135
|
mkdir "${env:GITHUB_WORKSPACE}\src-tauri\target\release\bundle\to-sign" |
|
136
|
mkdir "${env:GITHUB_WORKSPACE}\src-tauri\target\release\bundle\signed" |
|
137
|
Move-Item "${env:GITHUB_WORKSPACE}\src-tauri\target\release\bundle\msi\*" "${env:GITHUB_WORKSPACE}\src-tauri\target\release\bundle\to-sign\" -Force |
|
138
|
Move-Item "${env:GITHUB_WORKSPACE}\src-tauri\target\release\bundle\nsis\*" "${env:GITHUB_WORKSPACE}\src-tauri\target\release\bundle\to-sign\" -Force |
|
139
|
|
|
140
|
- name: Sign Artifact with CodeSignTool |
|
141
|
uses: sslcom/esigner-codesign@v1.3.2 |
|
142
|
timeout-minutes: 20 |
|
143
|
with: |
|
144
|
command: batch_sign |
|
145
|
username: ${{ secrets.ES_USERNAME }} |
|
146
|
password: ${{ secrets.ES_PASSWORD }} |
|
147
|
credential_id: ${{ secrets.ES_CREDENTIAL_ID }} |
|
148
|
totp_secret: ${{ secrets.ES_TOTP_SECRET }} |
|
149
|
dir_path: ${GITHUB_WORKSPACE}\src-tauri\target\release\bundle\to-sign |
|
150
|
output_path: ${GITHUB_WORKSPACE}\src-tauri\target\release\bundle\signed |
|
151
|
malware_block: false |
|
152
|
clean_logs: true |
|
153
|
jvm_max_memory: 1024M |
|
154
|
signing_method: v1 |
|
155
|
|
|
156
|
# The .msi/.exe above are for direct download only. A Store MSI/EXE |
|
157
|
# submission is just a hosted installer URL, so it never gets package |
|
158
|
# identity and Windows.Services.Store add-ons would fail from it. The MSIX |
|
159
|
# below is what goes to Partner Center. It is deliberately left unsigned: |
|
160
|
# the Store re-signs with the publisher cert. Skipped when the MSIX |
|
161
|
# secrets are absent. |
|
162
|
- name: Pack MSIX for Partner Center |
|
163
|
if: ${{ env.MSIX_PUBLISHER != '' && env.MSIX_IDENTITY_NAME != '' }} |
|
164
|
shell: pwsh |
|
165
|
run: ./scripts/build-msix.ps1 |
|
166
|
|
|
167
|
- name: Extract version from tauri.prod-windows-microsoftstore.conf.json |
|
168
|
id: get_version |
|
169
|
shell: pwsh |
|
170
|
run: | |
|
171
|
$json = Get-Content src-tauri/tauri.prod-windows-microsoftstore.conf.json | ConvertFrom-Json |
|
172
|
echo "VERSION=$($json.version)" >> $env:GITHUB_ENV |
|
173
|
|
|
174
|
- name: Release |
|
175
|
uses: softprops/action-gh-release@v2 |
|
176
|
with: |
|
177
|
tag_name: "windows-microsoft-store-siti-ai-v${{ env.VERSION }}" |
|
178
|
draft: true |
|
179
|
prerelease: false |
|
180
|
body: "See the assets to download this version and install." |
|
181
|
name: "Siti AI v${{ env.VERSION }} (Windows Microsoft Store)" |
|
182
|
files: | |
|
183
|
src-tauri/target/release/bundle/signed/*.msi |
|
184
|
src-tauri/target/release/bundle/signed/*.exe |
|
185
|
src-tauri/target/release/bundle/msix/*.msix |