Skip to content

feat(dist): tag-based asset names; pre-release builds that don't notify - #27

Merged
Xander-git merged 2 commits into
mainfrom
feat/release-asset-naming-and-prerelease-guard
May 31, 2026
Merged

feat(dist): tag-based asset names; pre-release builds that don't notify#27
Xander-git merged 2 commits into
mainfrom
feat/release-asset-naming-and-prerelease-guard

Conversation

@Xander-git

Copy link
Copy Markdown
Collaborator

Summary

Three requested distribution refinements. Two were already satisfied by GitHub's semantics — this PR makes them explicit/robust and documents them — while the asset renaming is a behavioural change.

1. Tag-based asset names (changed)

Per-OS installers are renamed to ExLabWizard_v<release-tag>.<ext>ExLabWizard_v0.2.0.exe / .dmg / .AppImage. The name comes from the release tag with a leading v/V normalised (both v0.2.0 and 0.2.0ExLabWizard_v0.2.0, never _vv0.2.0); pre-release tags pass through (ExLabWizard_v1.0.0-rc1.exe). Non-release builds (dispatch/PR) fall back to the package __version__.

Raw onedir archives keep an OS suffix (ExLabWizard_v<tag>-<suffix>.zip|tar.gz) — macOS and Linux both emit .tar.gz and would otherwise collide as release assets. The Inno .iss takes a new /DOutputBaseName define; upload + release globs updated to ExLabWizard_v*.

2. Pre-releases also build binaries (already worked; documented)

release: types: [published] already fires for pre-releases (per GitHub docs), so a published pre-release builds + attaches the full installer set — letting you test a release candidate. No trigger change (adding prereleased would double-run); documented in the workflow header.

3. Pre-releases do NOT trigger the update notification (already worked; now guarded + tested)

The startup checker polls releases/latest, which GitHub defines as the most recent non-prerelease, non-draft release — so a pre-release can never be returned and never prompts an upgrade. fetch_latest_tag now also defensively skips any payload flagged prerelease/draft, encoding the requirement in our code rather than relying on the endpoint.

Files

  • .github/workflows/build.yml — tag-derived release_name; renamed exe/dmg/AppImage/archive outputs; /DOutputBaseName to Inno; updated globs; header docs; release tag routed through env: (no shell injection).
  • packaging/windows/exlab-wizard.issOutputBaseName define → OutputBaseFilename.
  • src/exlab_wizard/update_check/checker.py — skip prerelease/draft payloads.
  • tests/unit/update_check/test_checker.py — +2 tests (prerelease, draft → None).
  • README.md — new asset-name wording + pre-release behaviour.

Verification run locally

  • pytest tests/unit/update_check → 19 passed (incl. the 2 new pre-release/draft tests)
  • ruff check + ruff format --check clean on the touched files; mypy src/exlab_wizard/update_check clean
  • workflow YAML parses; naming logic checked for v0.2.0 / 0.2.0 / v1.0.0-rc1 / V2.3.4
  • The CI build matrix on this PR is the authoritative check that the installers build with the new names; a v0.0.0-rc1 dry-run tag would additionally exercise the release-attach + pre-release path.

🤖 Generated with Claude Code

Xander-git and others added 2 commits May 30, 2026 23:19
Release-asset naming: per-OS installers are now named
ExLabWizard_v<release-tag>.<ext> (e.g. ExLabWizard_v0.2.0.exe/.dmg/.AppImage).
The name is driven by the release tag with a leading v/V normalised, so both
v0.2.0 and 0.2.0 produce ExLabWizard_v0.2.0 (never _vv0.2.0). Non-release
builds (dispatch/PR) fall back to the package __version__. Raw onedir archives
keep an OS suffix (ExLabWizard_v<tag>-<suffix>.{zip,tar.gz}) because macOS and
Linux both emit .tar.gz and would otherwise collide as release assets. The
Inno .iss takes a /DOutputBaseName define; upload + release globs updated to
ExLabWizard_v*.

Pre-releases: the `published` activity type already fires for pre-releases, so
publishing a pre-release builds + attaches the full installer set (test an RC
before shipping). No trigger change; documented in the workflow header.

Pre-releases do NOT notify: the startup checker polls releases/latest, which
GitHub defines as the most recent non-prerelease, non-draft release -- so a
pre-release never prompts an upgrade. Added a defensive guard in
fetch_latest_tag (skip payloads flagged prerelease/draft) + two unit tests so
the requirement is encoded in our code, not just implied by the endpoint.

README updated for the new asset names and the pre-release behaviour.

Tag-name input is routed through env (not interpolated into the run body) to
avoid shell injection.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The two happy-path tests waited for the queue ROW to reach a terminal
state (wait_for_job_state) and then immediately read creation.json's
sync_status. That field is stamped by a separate async step
(_mark_synced / _mark_cleaned) that lags the queue-row transition, so a
loaded CI runner observed the pre-stamp 'pending' value and the assert
failed (a residual instance of the #25 timing-flake class -- these two
were the spots #25 did not fully convert).

Poll the file itself with wait_until until sync_status reaches the
asserted value, instead of reading it the instant the row goes terminal.
No production code change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Xander-git
Xander-git merged commit facb4e4 into main May 31, 2026
8 checks passed
@Xander-git
Xander-git deleted the feat/release-asset-naming-and-prerelease-guard branch May 31, 2026 07:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant