Release notes come from a file in the repo, not the tag
Build PCM package / build (push) Successful in 9s

Deriving the body from the tag annotation does not survive CI: the
release action does not fall back to it (v1.2.0 published empty), and
checkout leaves the tag lightweight, so %(contents) yields the commit
message instead - which is what v1.2.1 first published. Keep the notes
at docs/release-notes/v<version>.md, pass that as body_path, and fail
the run when it is missing.
This commit is contained in:
2026-07-22 16:27:31 +07:00
parent 4dd33e6f43
commit d7c3089031
3 changed files with 59 additions and 19 deletions
+11 -15
View File
@@ -13,11 +13,6 @@ jobs:
# third-party actions pinned to commit SHAs: mutable tags could be # third-party actions pinned to commit SHAs: mutable tags could be
# repointed at malicious code that runs with repo/token access # repointed at malicious code that runs with repo/token access
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
# the annotated tag carries the release notes, and checkout
# fetches with --no-tags unless asked - at any fetch-depth
fetch-depth: 0
fetch-tags: true
- name: Check tag matches metadata.json version - name: Check tag matches metadata.json version
if: startsWith(github.ref, 'refs/tags/v') if: startsWith(github.ref, 'refs/tags/v')
@@ -40,25 +35,26 @@ jobs:
dist/*.zip dist/*.zip
dist/metadata-registry.json dist/metadata-registry.json
# the action does not fall back to the tag annotation, so an # The release body comes from a file in the repo: the action does
# un-bodied release publishes with empty notes (as v1.2.0 did) # not fall back to the tag annotation (v1.2.0 published empty), and
- name: Release notes from the annotated tag # reading the annotation here is unreliable - checkout leaves the
# tag lightweight, so %(contents) yields the commit message instead.
- name: Check the release notes exist
if: startsWith(github.ref, 'refs/tags/v') if: startsWith(github.ref, 'refs/tags/v')
run: | run: |
git tag -l --format='%(contents:body)' "$GITHUB_REF_NAME" \ notes="docs/release-notes/${GITHUB_REF_NAME}.md"
> release-notes.md if [ ! -s "$notes" ]; then
if [ ! -s release-notes.md ]; then echo "$notes is missing or empty - write the release notes" \
echo "no annotated message on $GITHUB_REF_NAME - refusing to" \ "before tagging" >&2
"publish a release with empty notes" >&2
exit 1 exit 1
fi fi
cat release-notes.md cat "$notes"
- name: Create release with the zip, registry metadata and figures - name: Create release with the zip, registry metadata and figures
if: startsWith(github.ref, 'refs/tags/v') if: startsWith(github.ref, 'refs/tags/v')
uses: akkuman/gitea-release-action@b8d9144f302c68610911db1aaf722708d5c02d94 # v1 uses: akkuman/gitea-release-action@b8d9144f302c68610911db1aaf722708d5c02d94 # v1
with: with:
body_path: release-notes.md body_path: docs/release-notes/${{ github.ref_name }}.md
files: | files: |
dist/*.zip dist/*.zip
dist/metadata-registry.json dist/metadata-registry.json
+12 -4
View File
@@ -4,7 +4,7 @@ The PCM addon zip is built by CI (`.gitea/workflows/build-pcm.yml`).
Every push to `main` builds it as a downloadable artifact; pushing a Every push to `main` builds it as a downloadable artifact; pushing a
`v<version>` tag additionally creates a Gitea release with the zip `v<version>` tag additionally creates a Gitea release with the zip
attached. The release job checks that the tag matches `metadata.json` attached. The release job checks that the tag matches `metadata.json`
and fails on a mismatch. and that the release notes exist, and fails on either mismatch.
## Steps ## Steps
@@ -23,17 +23,25 @@ and fails on a mismatch.
] ]
``` ```
2. **Commit, tag, push** (tag = `v` + the manifest version): 2. **Write the release notes** at `docs/release-notes/v<version>.md`.
This file becomes the release description verbatim; the job fails if
it is missing or empty (the release action publishes empty notes
rather than falling back to the tag message, which is how v1.2.0
shipped with a blank description). Say what changed for a user of
the previous version — in particular, whether results move for an
unchanged board.
3. **Commit, tag, push** (tag = `v` + the manifest version):
```powershell ```powershell
git add metadata.json git add metadata.json docs/release-notes/v1.0.2.md
git commit -m "Release 1.0.2" git commit -m "Release 1.0.2"
git tag v1.0.2 git tag v1.0.2
git push git push
git push origin v1.0.2 git push origin v1.0.2
``` ```
3. **Verify**: the Actions run for the tag builds 4. **Verify**: the Actions run for the tag builds
`th.co.b4l.fill-resistance_<version>.zip` and publishes it at `th.co.b4l.fill-resistance_<version>.zip` and publishes it at
<https://git.b4l.co.th/B4L/kicad-zone-resistance/releases>, together <https://git.b4l.co.th/B4L/kicad-zone-resistance/releases>, together
with `metadata-registry.json`. The zip installs directly via with `metadata-registry.json`. The zip installs directly via
+36
View File
@@ -0,0 +1,36 @@
Bug-fix release. Results are unchanged from 1.2.0 for a board that
solves cleanly; the fixes are in the in-KiCad overlay push, pad copper
selection and error reporting.
Note for anyone coming from 1.1.0 or earlier: 1.2.0 changed the physics
model (exact SMD and THT pad copper, populated THT holes conducting as
their solder plug and lead, slotted holes as true stadiums) and fixed an
adaptive barrel-refinement bug that could make via-field results read up
to ~13% low. Numbers for an unchanged board differ from 1.1.0 - re-run
any board you track across versions.
Fixed:
- Overlay push: a locked reference image silently survived removal and a
new one was stacked on top of it. KiCad reports the failure per item
while the overall request still reads OK; it is now checked, and the
layer is reported and skipped instead.
- Overlay push: a run covering fewer layers than the previous one left
the earlier solve's heatmap on the unused slots, where it read as
current. Those slots are now cleared.
- Overlay push: the whole push is one commit, so a single undo reverts
it rather than just the last layer.
- Through-hole pad copper was always read from F.Cu even when the joint
protrudes on B.Cu, mis-sizing the modelled solder coat for pads sized
differently per copper layer. The solder side is now probed first.
- A failure before the output directory existed - a broken plugin
Python environment, typically - reported nothing at all on screen.
The error figure now falls back to the temp directory.
- Pads sitting on no single copper layer are noted rather than silently
skipped, and the frequency field keeps its specific rejection reason
("1,500" is a thousands separator, "-5" is negative) as the other
numeric fields already did.
The KiCad overlay push remains experimental and opt-in (off by default).
It writes reference images to User.9-User.12 and replaces what is on
those layers.