Commit 36d80e3
packaging: a Windows installer, built from the signed archives (#147)
* packaging: the Windows installer, built from the two signed archives
One installer carries both programs for every account on the machine:
Program Files, the folder on the machine's PATH once, the window in the
Start menu started in its own folder, which the window now recognises.
build_msi.py builds it from the signed amd64 archives with WiX 5.0.2, from
the tree it sits in, so a release can build it from the tagged tree. A
release candidate gets none, and a version Windows Installer cannot hold
is refused. Nothing that is running is ended - the Restart Manager is off
from the first installer on, measured to upgrade in place while tfg runs.
Guards read the rendered source as XML and hold the lines the
measurements rest on, pin the UpgradeCode for good, and run every
refusal of the script without WiX.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* release: the signing script builds, signs and expects the installer
sign_release.py builds the installer from the signed amd64 archives with
build_msi.py taken from the tree of the tag, exported with git archive,
so what was tagged is what ships whatever the checkout stands on. It
asks whether the installer can be built before the card signs anything,
signs it with a timestamp and reads its certificate back like the
programs'. A draft is complete with exactly one installer for a
release, and none for a candidate - a tag with a hyphen, the one rule
release.yml, build_msi.py and this script share.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* ci: install the installer on a Windows runner and ask what it did
Built unsigned from the latest release's two amd64 archives, checked
against its checksums, and this commit's template. Installed silently:
one entry in Programs and Features, the folder holding exactly the two
archives, the folder on the machine's PATH once with the software
renderer one level down, tfg version answering through PATH, the
shortcut starting the window in its own folder. Built again and
installed over itself while a tfg run is in progress, which carries on.
Removed with a file of somebody else's in the folder, which alone is
left. The same checks passed on Windows Server 2025 under Windows
PowerShell 5.1 before this was pushed. A guard holds the job to the
lines that ask all this and to the WiX version build_msi.py builds with.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* release: the last phase asks the published page for the installer
One installer for a release, under the name build_msi.py gives it, and
none for a candidate. Its signature is a step of its own - valid, with
a timestamp, by the pinned certificate - with its own line in the
verdict, so the step over the three archives and a candidate's run
stay as they were. Both steps were run as written: the count in five
folders, the signature on no installer and on an unsigned one.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* packaging: the installer's place on the release page, and what it does in words
The installer sorts among the programs, between the window's archives
and the command line's - asked of the name build_msi.py gives it. The
changelog says what it installs and what an upgrade while tfg runs
does, and the packaging readme says how it is built and why each line
of it is there. The site, the readme and the release notes change with
the release that first carries it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* release: the tagged tree's extraction is settled for semgrep, with the measurement beside it
The data filter keeps every name inside the folder - measured with a
crafted archive: a name with .. and a link pointing out are refused, an
absolute name lands inside, and nothing appears beside the folder.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* guard: the installer source is read to its end with errors.Is
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* release: the semgrep note sits above the line the rule reports
Measured with semgrep 1.177.0, the version CI pins: the rule reports the
with statement, not the extraction under it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* packaging: one name to Windows is one file, and the tagged tree goes whatever happens
Outside review of #147. Two archives holding LICENSE and License with
different bytes put one over the other on a Windows disk without a word,
because the names were compared as written - they are compared folded
to one case now, and refused like any two copies that differ. The tree
of the tag is exported for the check before the card and again for the
installer, and removed after each whatever happened in between, so a
refusal no longer leaves it beside the release's files.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* packaging: the installer's signature names the product, and so does the prompt
sign_release.py asks build_msi.py from the tagged tree for the name the
package carries (--product-name) and signs the installer with it as the
signature's description. Measured on Windows 11 with two copies signed by
the card: without it the elevation prompt named a string of digits, with it
the product and the verified publisher. check_installer asks for the name
before the card signs anything.
The packaging README and the changelog say what a double click shows while
the window is open, measured at the console of the Windows Server 2025 VM:
Windows Installer lists the window and offers Cancel, Retry and Ignore, and
closes nothing itself.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* guard: the product name is read with its edges, and a tag that names none is refused
The probe of the tagged tree printed the name at the end of a line, so a
name still carrying its newline passed as well. It is printed in brackets
now, and a release candidate - whose build_msi.py refuses - has to end in
the signing script's refusal rather than in an empty description.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>1 parent d977cbf commit 36d80e3
12 files changed
Lines changed: 1595 additions & 23 deletions
File tree
- .github
- scripts
- workflows
- internal/guard
- packaging
- msi
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 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 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
312 | 312 | | |
313 | 313 | | |
314 | 314 | | |
315 | | - | |
| 315 | + | |
| 316 | + | |
316 | 317 | | |
317 | 318 | | |
318 | 319 | | |
319 | 320 | | |
320 | 321 | | |
321 | 322 | | |
322 | 323 | | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
323 | 328 | | |
324 | 329 | | |
325 | 330 | | |
| |||
0 commit comments