-
Notifications
You must be signed in to change notification settings - Fork 0
206 lines (186 loc) · 9.34 KB
/
Copy pathrelease.yml
File metadata and controls
206 lines (186 loc) · 9.34 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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
name: Release
# Basta pushare un tag "v<versione>" (es. v0.1.9) — questo workflow
# aggiorna da solo il numero di versione in Cargo.toml/tauri.conf.json,
# compila app.exe + i 9 watcher + il launcher, impacchetta e firma il
# pacchetto di aggiornamento, compila l'installer NSIS, e pubblica tutto
# come release GitHub. Vedi BLUEPRINT.md sezione 25 per l'intero
# sistema di auto-aggiornamento a cui questo si collega.
on:
push:
tags:
- "v*"
permissions:
contents: write
env:
WATCHERS: afk app-icons claude-code excel screenshot tray vpn vscode window
jobs:
build-and-release:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- name: Ricava la versione dal tag
id: version
shell: pwsh
run: |
$version = "${{ github.ref_name }}" -replace '^v', ''
"version=$version" >> $env:GITHUB_OUTPUT
# Così un tag è l'UNICA cosa da preparare per una release — non
# serve ricordarsi di bumpare a mano questi due file prima di
# taggare, cosa fatta manualmente (ed error-prone) per tutte le
# release di questa sessione.
- name: Imposta la versione in Cargo.toml e tauri.conf.json
shell: pwsh
run: |
$version = "${{ steps.version.outputs.version }}"
(Get-Content src-tauri/Cargo.toml) -replace '(?m)^version = ".*"', "version = `"$version`"" |
Set-Content src-tauri/Cargo.toml
$conf = Get-Content src-tauri/tauri.conf.json -Raw | ConvertFrom-Json
$conf.version = $version
$conf | ConvertTo-Json -Depth 10 | Set-Content src-tauri/tauri.conf.json
- uses: actions/setup-node@v4
with:
node-version: 20
- uses: dtolnay/rust-toolchain@stable
# Ogni runner GitHub parte da una macchina vuota — senza questo,
# OGNI push di un tag ricompila tutti gli 11 crate (9 watcher +
# app.exe + launcher.exe) completamente da zero, anche se cambia
# una sola riga in uno solo di essi (~15-20 minuti). Con la cache,
# solo i crate il cui codice/dipendenze sono davvero cambiati
# vengono ricompilati — gli altri riusano il target/ della run
# precedente. Un percorso per crate (nessun workspace Cargo unico
# li collega): se si aggiunge/rinomina un watcher, va aggiornato
# anche qui oltre che in WATCHERS più sopra.
- uses: Swatinem/rust-cache@v2
with:
workspaces: |
aw-watcher-afk-rust -> target
aw-watcher-app-icons-rust -> target
aw-watcher-claude-code-rust -> target
aw-watcher-excel-rust -> target
aw-watcher-screenshot-rust -> target
aw-watcher-tray-rust -> target
aw-watcher-vpn-rust -> target
aw-watcher-vscode-rust -> target
aw-watcher-window-rust -> target
src-tauri -> target
launcher -> target
# Bug reale trovato testando v0.1.11: di default il NOME del
# job entra nella chiave di cache (add-job-id-key, true di
# default) — il job qui si chiama "build-and-release", quello
# di cache-warmup.yml "warmup", quindi le due chiavi
# differivano già a monte e la cache dell'uno non veniva mai
# trovata dall'altro, indipendentemente dal fallback tra
# branch. Disattivato qui E nell'altro workflow (deve
# combaciare in entrambi) perché l'intento è proprio
# condividerla tra i due job.
add-job-id-key: false
- name: Installa NSIS
run: choco install nsis -y
- run: npm install
- run: npm run build
# Ogni watcher è un crate indipendente (nessun workspace Cargo
# condiviso) — build.rs di src-tauri si aspetta di trovarli già
# pronti in src-tauri/binaries/<nome>-x86_64-pc-windows-msvc.exe
# (convenzione "sidecar" di Tauri) prima di compilare l'app.
- name: Compila i watcher
shell: pwsh
run: |
foreach ($w in $env:WATCHERS -split " ") {
cargo build --release --manifest-path "aw-watcher-$w-rust/Cargo.toml"
Copy-Item "aw-watcher-$w-rust/target/release/aw-watcher-$w.exe" `
"src-tauri/binaries/aw-watcher-$w-x86_64-pc-windows-msvc.exe" -Force
}
- name: Compila app.exe
run: cargo build --release --manifest-path src-tauri/Cargo.toml
- name: Compila launcher.exe
run: cargo build --release --manifest-path launcher/Cargo.toml
# Stesso identico contenuto che l'installer mette in
# versions/<versione>/ — vedi src-tauri/src/updater.rs per il
# formato atteso (nome file, root dello zip senza sottocartella).
- name: Impacchetta il pacchetto di aggiornamento
shell: pwsh
run: |
$version = "${{ steps.version.outputs.version }}"
New-Item -ItemType Directory -Path "stage/icons" -Force | Out-Null
Copy-Item "src-tauri/target/release/app.exe" "stage/"
foreach ($w in $env:WATCHERS -split " ") {
Copy-Item "src-tauri/target/release/aw-watcher-$w.exe" "stage/"
}
Copy-Item -Recurse "dist" "stage/dist"
Copy-Item -Recurse "src-tauri/watcher-templates" "stage/watcher-templates"
Copy-Item "src-tauri/icons/128x128.png" "stage/icons/notification-icon.png"
Compress-Archive -Path "stage/*" `
-DestinationPath "trackflow-$version-update-package.zip" -CompressionLevel Optimal
# La chiave privata (TRACKFLOW_SIGNING_KEY) è un secret del
# repository, mai nel codice — vedi ~/.trackflow-updater.key sulla
# macchina che l'ha generata, MAI committata. Password vuota per
# scelta (generata con `tauri signer generate --ci`), non è un
# secret in sé quindi può stare in chiaro qui.
- name: Firma il pacchetto di aggiornamento
shell: pwsh
env:
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TRACKFLOW_SIGNING_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ""
run: |
$version = "${{ steps.version.outputs.version }}"
npx tauri signer sign "trackflow-$version-update-package.zip"
- name: Compila l'installer
shell: pwsh
run: |
$version = "${{ steps.version.outputs.version }}"
# choco install nsis mette makensis.exe qui, ma non lo aggiunge
# al PATH nello stesso step in cui viene poi chiamato (bug
# reale trovato nel primo run di test, v0.1.9) — percorso
# esplicito invece di affidarsi al PATH, con fallback su
# "makensis" nudo nel caso l'installazione choco cambi percorso
# in futuro.
$makensis = "C:\Program Files (x86)\NSIS\makensis.exe"
if (-not (Test-Path $makensis)) { $makensis = "makensis" }
& $makensis "/DVERSION=$version" installer\trackflow-installer.nsi
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
- name: Pubblica la release
env:
GH_TOKEN: ${{ github.token }}
shell: pwsh
run: |
$version = "${{ steps.version.outputs.version }}"
# Corpo della release preso dalla sezione "### en" di questa
# versione in docs/CHANGELOG.md, invece delle note generate
# automaticamente da GitHub (che senza pull request associate
# mostrano solo un link "Full Changelog: vX...vY", inutile per
# chi guarda la pagina della release senza cliccare altrove).
# Fallback su --generate-notes se la sezione non si trova (es.
# changelog dimenticato per questa versione, vedi RELEASE.md
# sezione 2) invece di far fallire tutta la pubblicazione.
$changelog = Get-Content "docs\CHANGELOG.md" -Raw
$pattern = "(?ms)^## $([regex]::Escape($version))\s*?\r?\n.*?^### en\s*?\r?\n(.*?)(?=\r?\n## |\z)"
if ($changelog -match $pattern) {
$note = $matches[1].Trim()
$notePath = "release-notes.md"
Set-Content -Path $notePath -Value $note -Encoding utf8
gh release create "v$version" `
"trackflow-$version-update-package.zip" `
"trackflow-$version-update-package.zip.sig" `
"installer\trackflow-setup-$version.exe" `
--title "v$version" `
--notes-file $notePath
} else {
Write-Warning "Nessuna sezione '## $version' / '### en' trovata in docs\CHANGELOG.md — uso le note generate automaticamente."
gh release create "v$version" `
"trackflow-$version-update-package.zip" `
"trackflow-$version-update-package.zip.sig" `
"installer\trackflow-setup-$version.exe" `
--title "v$version" `
--generate-notes
}
$assets = gh api "repos/${{ github.repository }}/releases/tags/v$version" --jq '.assets[] | "\(.id) \(.name)"'
foreach ($riga in $assets) {
$id, $nome = $riga -split " ", 2
$etichetta = switch -Wildcard ($nome) {
"*update-package.zip" { "Update package (used internally by the app — not for manual download)" }
"*update-package.zip.sig" { "Update package signature" }
"*setup*.exe" { "Windows installer" }
default { $nome }
}
gh api -X PATCH "repos/${{ github.repository }}/releases/assets/$id" -f "label=$etichetta" | Out-Null
}