v12.1.0.3
Warbrand-Fast-Mail
v12.1.0.3 (2026-08-19)
Full Changelog Previous Releases
- Let the packager publish the GitHub release too
The zip already goes to CurseForge on a tag; the GitHub release was still
being cut by hand, which meant the two could drift and the release carried
a zip built on a laptop rather than the one that was actually shipped.
Same version split as the CurseForge token: @v2 reads GITHUB_OAUTH, master
reads GITHUB_API_TOKEN, so both are set from the Actions-issued
GITHUB_TOKEN. Nothing has to be created for this one.
permissions: contents: write is required for that token to create a
release; read is enough for everything else the job does.
Release notes now come from the generated changelog instead of being
written by hand.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Feed the token under the name this packager version reads
Pinning the action to @v2 while reading the README on master was the
mistake. That version's release.sh does:
[ -z "$cf_token" ] && cf_token=$CF_API_KEY
CF_API_TOKEN is the newer name and means nothing to it, so cf_token stayed
empty and the upload guard
if [[ "$slug" =~ ^[0-9]+$ && -z "$skip_cf_upload" && -n "$cf_token" ]]
never opened. An absent token is the packager's normal "nothing to upload
to" case, so three runs packaged, exited 0 and reported success without
ever mentioning an upload.
The secret keeps its name; the workflow maps it to both variables, which
also survives a later bump to master.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Pass the CurseForge project id on the command line
The v12.1.0.3 run had a token, printed "CurseForge ID: 1655846", packaged
cleanly and never attempted an upload. It printed "GitHub:
sorglos-it/Warbrand-Fast-Mail" in the same breath and did not upload there
either, so those lines report configured targets rather than intent.
The upload is guarded by a numeric test on the project id. Passing -p sets
it through the documented path instead of relying on the TOC field being
picked up for that particular check. The TOC keeps the field as well; it
costs nothing and documents the id where a reader expects it.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Let the job see the CurseForge token
CF_API_TOKEN is an environment secret on the "curseforge" environment, not
a repository secret. A job only receives environment secrets when it names
the environment, so ${{ secrets.CF_API_TOKEN }} expanded to an empty string
and the packager skipped the upload -- silently, since a missing token is a
normal "nothing to upload to" case for it.
Declaring the environment is the better half of the fix anyway: it keeps
the credential scoped to the job that deploys instead of exposing it to
every workflow in the repository.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Make the .pkgmeta ignore list actually take effect
Every entry was dead. The packager parses this file with shell tools
rather than a YAML parser, so a trailing comment becomes part of the value
and it looked for a path called "tools # build_lang.py, not loaded
in game". No match, no exclusion, no complaint.
The v12.1.0.3 dry run shipped tools/, screenshots/, both logos and
curseforge.md inside the addon zip as a result -- roughly 2.5 MB of
artwork and page text for players to download alongside the code.
Values are bare now and the reasoning sits in the header instead.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Release 12.1.0.3
Fourth digit only. First automated release: pushing the tag hands
packaging to the workflow instead of building the zip by hand.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Give the release commands one per line
"git tag X && git push origin X" is a parser error in Windows PowerShell
5.1, which has no && operator, and a parse error means nothing on the line
runs -- not even the tag. One command per line is valid in bash and in both
PowerShell generations, so a single form covers everyone.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Add project page artwork and screenshots
Four in-game screenshots and a smaller logo for the CurseForge page,
checked by the author before committing.
Both logos and the screenshots folder are on the .pkgmeta ignore list, so
none of it lands in the addon zip -- players download code, not artwork.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Point the packager at CurseForge project 1655846
The TOC field is the canonical place for it and the id is public -- it is
printed in the "About Project" box on the project page -- so it belongs in
the repository rather than in a workflow argument.
The CF_API_TOKEN secret is still outstanding and is the only thing left
between a pushed tag and an upload.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Package and upload to CurseForge from a tag
Pushing a v* tag now runs BigWigsMods/packager@v2, which builds the zip
from .pkgmeta and uploads it to CurseForge. The tag decides the release
type: one containing "alpha" or "beta" is uploaded as such, anything else
as a full release.
.pkgmeta keeps tools/, screenshots/, logo.png and curseforge.md out of the
package. curseforge.md is the project page text, not something to ship to
players, and logo.png is 2 MB with no business in an addon folder.
fetch-depth: 0 on the checkout is deliberate. The packager walks tags and
history to build its changelog, and a shallow clone produces an empty one
without complaining.
Two things still have to be created by hand, and only the project owner
can do either:
- "## X-Curse-Project-ID: " in the TOC. The line is present but
commented out, because a placeholder id would upload to whatever
project happens to own that number.
- The CF_API_TOKEN repository secret.
Neither is a blocker for merging: without them the workflow still runs and
still builds the zip, it just skips the upload.
GitHub releases stay manual so the notes stay hand-written; the README
says which two lines hand those to the packager as well.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com