Files
grabowski 52a40c1c3e release/: the newest stage's manufacturing files and documentation
A stage tag (v*) now builds, with kicad-cli, pandoc and pdflatex in the CI
image (.gitea/scripts/release-files.py):
- per board: Gerbers + Excellon drill zip (JLCPCB-compatible settings), BOM
  (grouped, DNP left out), pick and place, schematic and PCB PDFs, 3D renders;
- docs/*.md and docs/tex/*.tex as PDF, tag and commit in the footer;
- release/README.md with tag, commit, ERC/DRC result, files, SHA-256 and the
  stage's CHANGELOG section.
Every file name carries the tag. release-attach.py attaches the files plus a
zip of the whole folder to the tag's release (replacing assets of an earlier
run); for the newest stage tag (not older stages, not pre-releases) the job
commits them to release/ on main with [skip ci].

.gitignore: !/release/ after Release/ (Windows matches it case-insensitively);
.gitattributes: release/** -text so the SHA-256 match on every checkout.
TEMPLATE.md: "Release files" section, rules and CI updated.

Tested in git.b4l.co.th/b4l/kicad10_auto_node with harNES's board and docs:
v0.1 committed, v0.0 and v0.2-rc.1 left release/ alone, v0.2 tagged on an
older commit landed on top of a moved main; uploads byte-exact against a stub
of the Gitea release API.
2026-10-16 18:50:01 +07:00

70 lines
2.7 KiB
YAML

name: Release
# On a tag v* (a prototype stage), .gitea/scripts/release-files.py builds the
# stage's release files: for every board Gerbers and drill (zip), BOM, pick
# and place, schematic and PCB PDFs and 3D renders; the documentation
# (docs/*.md, docs/tex/*.tex) as PDF. They are attached to the tag's release
# (created when missing) and, when the tag is the newest stage, committed to
# release/ on main, so release/ always holds the latest stage. The commit
# carries [skip ci] and touches no path another workflow watches. The job
# token must be allowed to write releases and to push to main. Firmware and
# software tags (firmware/..., software/...) do not start it.
on:
push:
tags: ['v*']
jobs:
release:
runs-on: kicad10_auto
permissions:
contents: write
concurrency:
group: release-${{ github.repository }}
cancel-in-progress: false
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Release files
run: python3 .gitea/scripts/release-files.py "$GITHUB_REF_NAME" --out /tmp/release
- name: Attach to the release
env:
TOKEN: ${{ secrets.GITEA_TOKEN }}
run: python3 .gitea/scripts/release-attach.py /tmp/release
- name: Commit to release/ on main
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
run: |
tag="$GITHUB_REF_NAME"
# stage tags only (v0.1, v0.2, v1.0); a pre-release such as v0.3-rc.1 leaves release/ alone
newest=$(git tag -l 'v*' --sort=-v:refname | grep -E '^v[0-9]+(\.[0-9]+)+$' | head -1 || true)
if [ "$tag" != "$newest" ]; then
echo "$tag is not the newest stage (${newest:-none}): release/ is left as it is."
exit 0
fi
git config user.name "Release CI"
git config user.email "ci@noreply.git.b4l.co.th"
REPO_URL=$(git config --get remote.origin.url)
AUTHED_URL=${REPO_URL/https:\/\//https:\/\/${GITEA_TOKEN}@}
# main may move while this runs: start again from the newest main
for i in 1 2 3; do
git fetch -q "$AUTHED_URL" main
git checkout -q -f -B main FETCH_HEAD
rm -rf release
mkdir release
cp -r /tmp/release/. release/
git add -A -- release
if git diff --cached --quiet; then echo "release/ already holds $tag."; exit 0; fi
git commit -q -m "Release $tag: manufacturing files and documentation [skip ci]"
if git push -q "$AUTHED_URL" HEAD:main; then
echo "Pushed $(git rev-parse --short HEAD): release/ holds $tag"
exit 0
fi
sleep 5
done
echo "::error::Could not push release/ to main"
exit 1