- Shell 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
coreutils `fold` counts bytes, not characters, so wrapping at 78 could cut a multibyte character in half whenever a break landed mid-character, corrupting Chinese/Japanese/accented text. Replace it with an awk word-wrap that breaks only at spaces and never splits a token: a space-less run (e.g. a line of Chinese) is emitted whole instead of mangled. ASCII prose wraps as before. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
| hack | ||
| action.yaml | ||
| README.md | ||
changelog-action
A reusable Forgejo composite action that writes CHANGELOG.md entries from a
release's commit range. It asks an OpenAI-compatible inference service to turn
the commits since the previous v* tag into a short, plain-language summary,
splices a dated ## [x.y.z] section into the changelog, refreshes the compare
links, and commits the result back to the branch.
It is composite (shell only) — it needs git, curl, and jq in the job,
but no Node runtime — so it runs on any of our Forgejo runner pools, including
the ones without a DinD sidecar.
One release can produce several changelog files in different languages (for
example CHANGELOG.md in English and CHANGELOG.es.md in Spanish) in a single
commit.
Using it
Add a step after your tag is pushed:
- name: Update changelog for the new release
uses: https://git.brooktrails.org/brooktrails/changelog-action@v1
with:
tag: v${{ steps.tags.outputs.version }}
token: ${{ secrets.FORGEJO_TOKEN }}
inference-url: ${{ vars.INFERENCE_URL }} # optional; omit for the default
and commit a .changelog.env at your repo root stating what your software is:
PRODUCT_NAME="SLP (Simple LLM Proxy)"
PRODUCT_DESCRIPTION="an OpenAI-compatible HTTP router that forwards requests to upstream inference backends based on the model ID in the request body."
# optional per-repo defaults:
# INFERENCE_MODEL=mistral-small-4
Those two strings become the first sentence of the prompt: "You write release notes for SLP (Simple LLM Proxy), an OpenAI-compatible HTTP router that…". Everything else in the prompt (voice, what to leave out, no attribution, output-only) is fixed in the action so every project's entries read the same way.
Multiple languages
- uses: https://git.brooktrails.org/brooktrails/changelog-action@v1
with:
tag: v${{ steps.tags.outputs.version }}
token: ${{ secrets.FORGEJO_TOKEN }}
targets: |
CHANGELOG.md:US English
CHANGELOG.es.md:Spanish
Each path:language pair gets its own inference call and its own file; all
changed files land in one docs(changelog): update for <tag> [skip ci] commit.
The target files must already exist (create CHANGELOG.es.md with the same
heading/link-block scaffold your CHANGELOG.md uses).
Why it never fails your release
The release has already happened by the time this step runs, so a changelog
problem must not fail the job. Every failure path logs a ::warning:: and exits
0. A failed summary leaves that file untouched — recoverable by re-running
update-changelog.sh against the tag later — rather than committing a wrong or
placeholder entry that would silently become the historical record.
Inputs
| Input | Required | Default | Purpose |
|---|---|---|---|
tag |
yes | — | Release tag to write an entry for, e.g. v1.2.3. |
token |
yes | — | Forgejo token for clone + push (secrets.FORGEJO_TOKEN). |
targets |
no | (from changelog-path/language) |
path:language pairs, one per line. |
changelog-path |
no | CHANGELOG.md |
File for the single-target case. |
language |
no | US English |
Language for the single-target case (free text). |
product-name |
no | (from .changelog.env) |
Override the product name in the prompt. |
product-description |
no | (from .changelog.env) |
Override the product description in the prompt. |
inference-url |
no | script default | OpenAI-compatible endpoint base URL. |
inference-model |
no | script default | Model id to route to. |
config-file |
no | .changelog.env |
Per-repo config file the scripts source. |
branch |
no | main |
Branch to update. |
server-url |
no | workflow server | Forgejo base URL. |
repository |
no | current repo | owner/name. |
git-user-name |
no | forgejo-actions |
Commit author/committer name. |
git-user-email |
no | forgejo-actions@localhost |
Commit author/committer email. |
Precedence for identity/inference values is: action input > .changelog.env >
built-in default. For a fully custom prompt, set SYSTEM_PROMPT in
.changelog.env; that bypasses product-name/product-description.
Local maintenance
The hack/ scripts also run by hand, against a repo that adopts the action, to
fix up history. Run them from inside the target repo (so git ranges and
.changelog.env resolve there), pointing at this checkout:
# rewrite one release's entry: excise to a stub, then regenerate
/path/to/changelog-action/hack/enstubbify.sh 0.6.0
/path/to/changelog-action/hack/backfill-changelog.sh 0.6.0
git diff CHANGELOG.md # review; git checkout to discard
# a different language / file:
CHANGELOG=CHANGELOG.es.md LANGUAGE=Spanish \
/path/to/changelog-action/hack/backfill-changelog.sh 0.6.0
hack/update-changelog.sh <tag>— write the entry for one release.hack/backfill-changelog.sh [version…]— rewriteSTUB:entries into real summaries (no-op on real prose, so safe to re-run).hack/enstubbify.sh [--create] <version…>— replace an entry with aSTUB:line to be regenerated;--createadds a missing section in sorted position.hack/changelog-lib.sh— shared plumbing; not run directly.
Identity comes from the target repo's .changelog.env; override anything via
environment (PRODUCT_NAME, PRODUCT_DESCRIPTION, LANGUAGE, CHANGELOG,
INFERENCE_URL, INFERENCE_MODEL).
Requirements
The job needs git, curl, and jq on PATH, and network access to the
inference endpoint. Install them in a prior step if your job image lacks them,
e.g. apt-get install -y --no-install-recommends git curl jq ca-certificates.