Commit graph

3 commits

Author SHA1 Message Date
Vadim Peretokin
71f736297b
infrastructure: reject a release tag that does not match APP_VERSION (#9701)
#### Brief overview of PR changes/additions
- Adds `CI/check-release-tag.sh`: APP_VERSION must be three-component,
and a release tag must be exactly `Mudlet-<APP_VERSION>`.
- Wires it into the tag-build validation (`CI/validate_deployment.sh`,
`CI/validate-deployment-for-windows.sh`) so a bad tag fails minutes
after the push, before an asset exists, and into
`create-github-release.yml` as the last gate before anything is
published. The PTB path gets the version-shape half, which nothing
checks on `development` today.
- Covers it with `test/ci/release-tag-version-test.sh`, registered as
`ReleaseTagVersionTest`.

#### Motivation for adding to Mudlet
Tagging `Mudlet-5.0` instead of `Mudlet-5.0.0` would strand the entire
4.22.0 user base with no error anywhere, and it is the one version
mistake CI does not currently catch.

The updater takes the version it offers from the tag, not the binary:
`Release::Release()` strips the `Mudlet-` prefix
(`src/updater/Release.cpp:49`) and `SemVer::getRegExp()` needs three
components (`src/updater/SemVer.cpp:111`), so `"5.0"` is invalid,
`Release::operator<` (`src/updater/Release.cpp:96`) reports the release
as not newer, and `Feed::getUpdates()` returns nothing. The update check
goes on logging `0 update(s) available` - the same line as a week with
no release.

The asymmetry is what makes it dangerous. A stale APP_VERSION with a
correct tag fails loudly, because `CI/prepare-release-assets.sh:62`
rejects assets by tag prefix. A short tag with a correct APP_VERSION
passes everything, because `Mudlet-5.0.0-linux-x64.AppImage.tar`
genuinely does start with `Mudlet-5.0`.

**Why the build scripts and not only the workflow:**
`create-github-release.yml` is `workflow_run`-triggered, so it cannot
fail before the assets are built - by the time it runs, the full matrix
has already finished. The validate scripts run at the start of every tag
build on all three platforms and already parse APP_VERSION, so that is
where the fast failure belongs. The workflow keeps a copy because it
always runs from the default branch, so it still guards a tag placed on
a commit that predates this change.

APP_VERSION is deliberately left at 4.22.0 - bumping it is a release
decision, not a QA fix. This guard is what catches a mismatch when the
bump happens.

#### Other info (issues closed, discussion etc)
From the 5.0 release QA sweep, finding C1, "A two-component release tag
silently disables auto-update for every existing user". Pre-existing
mechanism, no single commit introduced it.

Three claims from an earlier draft did not survive checking and were
corrected: `src/sparkleupdater.mm` installs no
`versionComparatorForUpdater:`, so Sparkle's default component-wise
comparator would still offer `5.0` over `4.22.0` (macOS breaks on the
opposite mismatch instead); the update check does log, it is just
indistinguishable from having nothing to offer; and SemVer does accept a
prerelease component, so rejecting `Mudlet-5.0.0-rc1` follows from
APP_VERSION being unable to carry a suffix, not from the updater.

No video - a CI guard is not visually observable. The shell output below
is the evidence instead.

**Test case:** `ctest -R ReleaseTagVersionTest`, and the guard run
directly:

```
$ CI/check-release-tag.sh 5.0.0 Mudlet-5.0.0
Release tag 'Mudlet-5.0.0' matches APP_VERSION '5.0.0'.
exit=0

$ CI/check-release-tag.sh 5.0.0 Mudlet-5.0
error: release tag 'Mudlet-5.0' does not match APP_VERSION '5.0.0'.
The tag has to be exactly 'Mudlet-5.0.0'.

Publishing under a mismatched tag breaks auto-update, without saying so. [...]
exit=1
```

Replayed over every release tag since 4.18.5, each against the
APP_VERSION at that tag - all accepted, so the guard blocks nothing
Mudlet has actually shipped. Executing the real `Determine release type`
step under GitHub's shell flags fails on `Mudlet-5.0` + `5.0.0` and on a
PTB with APP_VERSION `5.0`, and passes on `Mudlet-5.0.0` + `5.0.0` and
on a normal PTB. The updater trace was confirmed by compiling
`Release.cpp` + `SemVer.cpp` and comparing: tag `Mudlet-5.0.0` gives
`(4.22.0 < release) = true`, tag `Mudlet-5.0` gives `false`.

Assisted-by: Claude:claude-opus-5
2026-08-07 06:14:11 +02:00
Vadim Peretokin
a099a20aee
infrastructure: fix milestone assignment, unbreak the key sequence tests (#9679)
#### Brief overview of PR changes/additions

- `add-milestone` resolves the milestone by exact title first and then
by version prefix, so `5.0.0` finds `5.0.0 next release` again, and
fails loudly instead of assigning nothing. 191 PRs merged since 4.22.0
have no milestone.
- `TKeySequenceEditTest`'s two focus traversal cases no longer fail
under a bare Xvfb: ctest pins the offscreen platform on X11, and a
direct run without a window manager skips with a message instead of
burning the activation timeout twice.

#### Motivation for adding to Mudlet

Both were failing silently. The milestone step matched a title that no
longer exists and exited 0; and the traversal tests were the one red
mark in an otherwise green local suite, which everybody had to re-derive
as environmental.

The milestone lookup is now a script under `.github/scripts/`, covered
by a new `MilestoneResolutionTest` that runs it against a stubbed `gh`.
Re-introducing the original bug makes that test fail.

Worth knowing: `add-milestone` on this PR still assigned nothing,
because `pull_request_target` runs the copy of the workflow that is on
the base branch. It takes effect for pull requests opened after this
merges.

#### Other info (issues closed, discussion etc)

- Closes #9671 - CI: add-milestone silently assigns nothing - metadata
says "4.23.0" but the milestone is titled "4.23.0 next release"
- Closes #9575 - TKeySequenceEditTest: two traversal tests fail under
bare Xvfb (no window manager)

Test case: `ctest -R 'MilestoneResolutionTest|TKeySequenceEditTest'`,
plus `xvfb-run --auto-servernum ctest -R TKeySequenceEditTest` for the
case #9575 is about.

Assisted-by: Claude:claude-opus-5
2026-08-06 06:07:10 +02:00
Vadim Peretokin
9634c394b8
fix: Windows auto-update failing on a release binary with no checksum (#9617)
#### Brief overview of PR changes/additions

- Never publish a release binary without a matching `SHA256SUMS.txt`
entry: merge over the already-published file instead of overwriting it,
set aside assets belonging to a different build than the release tag,
and gate the upload on every binary having an entry that matches its
bytes.
- Say which check failed in the updater - missing checksums,
undownloadable checksums, no entry for this platform, unreadable
checksum file - instead of one message for all of them.
- Add `UpdaterChecksumTest` and `ReleaseChecksumsTest`; both fail if the
fix is reverted.

#### Motivation for adding to Mudlet

Windows auto-update failed with "Could not verify the integrity of the
download", so PTB users could not update at all.
`create-github-release.yml` runs once per platform build workflow and
uploads with `--clobber`, so the 2026-08-02 run regenerated
`SHA256SUMS.txt` from its own subset of sidecars and overwrote the
complete file while the earlier `.exe` stayed published. The updater was
right to refuse it.

#### Other info (issues closed, discussion etc)

Test case: `ctest -R 'UpdaterChecksumTest|ReleaseChecksumsTest'`.

Verified on a Windows 11 VM against a scratch release reproducing the
exact layout: before, the Download Error dialog; after replacing only
`SHA256SUMS.txt` with what the new script produces, the installer
downloaded, verified and staged.

`requireChecksums` is unchanged - nothing accepts an unverified download
that did not before.

Not fixed here: PTBs ship Windows-only when the scheduled Linux/macOS
build is still queued, which is why the 2026-08-03 PTB has one asset.

Assisted-by: Claude:claude-opus-5
2026-08-03 12:30:14 +02:00