feat(release): release versioning & changelog automation — research and options #25

Merged
gabogg merged 3 commits from feat/release-versioning into dev 2026-08-25 14:34:31 +00:00
Owner

Summary — research & decision PR (no implementation yet)

This PR establishes the release-versioning + changelog automation track, replacing the GitHub-bound release-please that no longer runs on Forgejo.

Important: this is a planning PR. Per the project's convention for architectural changes, I'm presenting options and alternatives here for discussion before writing implementation code. Nothing here should merge as-is; the code lands only after a decision is made.

Why this is needed

  • The repo migrated from GitHub to Forgejo (git.gaboggamer.online).
  • release-please (googleapis/release-please-action) is a GitHub Actions action — it does not run on Forgejo's native runner, and Forgejo has no built-in equivalent.
  • The .github/workflows/release.yml still references release-please but is dead weight here (see PR #24 for the split-brain between .github/ and .forgejo/).
  • Currently there are two version tracks drifting apart (backend 1.13.0 vs desktop 0.1.0), and we want them kept as separate version tracks going forward (backend Java/Maven vs desktop Tauri/Cargo/npm) — not a single unified bump.

Requirement: separate version tracks

The goal is explicit: backend (Java/Maven) and desktop (Tauri) maintain independent versions, each bumped by its own changelog/commits. A single-tool release-please replacement that forces one monorepo version is not what we want.

Options to evaluate (no decision yet)

A. git-cliff (recommended to investigate first)

  • Standalone changelog generator from conventional-commit history; works purely off git, no host dependency.
  • Has first-class Gitea/Forgejo integration (contributor lists, PR links) — git-cliff.org/docs/integration/gitea/.
  • Can be run as a container job in .forgejo/workflows/; two separate configs can produce two changelogs (one per track).
  • Trade-off: it generates changelogs but doesn't bump versions itself — pair with a small script or conventional-recommended-bump.

B. semantic-release + semantic-release-gitea

  • Full automation (version determination + changelog + release publishing).
  • @saithodev/semantic-release-gitea exists specifically to publish a Gitea release; likely Forgejo-compatible via the API.
  • Trade-off: heavier, opinionated, multi-package config is more involved; the Gitea plugin is community-maintained.

C. release-plz (Rust crates)

  • Native for Cargo workspaces — ideal for the desktop track (Tauri/Cargo).
  • Doesn't cover the Java/Maven side, so we'd still need a second tool for the backend — two tools, but two tracks anyway.

D. Minimal in-house script (extend scripts/release.sh)

  • Already partially exists; extend it to bump each track independently and hand-write/render changelog entries.
  • Trade-off: least "automated," but proportionate for a one-team project and zero new dependencies.

What needs researching before coding

  • Does Forgejo's API support everything release-please used (create release, attach assets, close changelog PR)? Confirm semantic-release-gitea / forgejo-release action coverage.
  • Which runner will execute this — .forgejo/workflows/ with a docker runner (what actually runs today), not ubuntu-latest/windows-latest (see PR #24).
  • How to keep the two version tracks cleanly separate (two configs? two changelogs? two tags? prefix tags backend-v* / desktop-v*?).
  • Changelog format: keep conventional-commits style? (the existing CHANGELOG.md is release-please-flavored with full URLs).
  • Interaction with PR #22 (version alignment) and PR #24 (release workflow) — this PR should own the version-bump policy so those don't conflict.

Out of scope for this PR (for now)

  • Actual implementation of the chosen tool.
  • Any version bump itself.

Decision requested

Please weigh in on A–D (or propose another) in a comment. Once the approach is agreed, I'll scope a follow-up implementation branch that keeps the backend and desktop tracks independent.

Merge ordering (blocking dependency)

This PR owns the version-bump policy, so it should merge before the version/release PRs that depend on it. Recommended sequence:

  1. #25 (this PR) — decide the release-versioning approach.
  2. #22 — version alignment (extra-files wiring must match the #25 decision).
  3. #23 — README/cleanup (independent, but keep it after so it doesn't mask the version decision).
  4. #24 — release workflow (bump mechanism must align with #25).

#22 and #24 are marked as blocked by this PR via Forgejo's native issue dependencies.

## Summary — research & decision PR (no implementation yet) This PR establishes the **release-versioning + changelog automation** track, replacing the GitHub-bound `release-please` that no longer runs on Forgejo. > **Important:** this is a planning PR. Per the project's convention for architectural changes, I'm presenting **options and alternatives here for discussion *before* writing implementation code.** Nothing here should merge as-is; the code lands only after a decision is made. ### Why this is needed - The repo migrated from GitHub to Forgejo (`git.gaboggamer.online`). - `release-please` (`googleapis/release-please-action`) is a **GitHub Actions action** — it does not run on Forgejo's native runner, and Forgejo has **no built-in equivalent**. - The `.github/workflows/release.yml` still references release-please but is dead weight here (see PR #24 for the split-brain between `.github/` and `.forgejo/`). - Currently there are **two version tracks drifting apart** (backend `1.13.0` vs desktop `0.1.0`), and we want them kept as **separate version tracks** going forward (backend Java/Maven vs desktop Tauri/Cargo/npm) — not a single unified bump. ### Requirement: separate version tracks The goal is explicit: **backend (Java/Maven) and desktop (Tauri) maintain independent versions**, each bumped by its own changelog/commits. A single-tool release-please replacement that forces one monorepo version is *not* what we want. ### Options to evaluate (no decision yet) **A. `git-cliff` (recommended to investigate first)** - Standalone changelog generator from conventional-commit history; works purely off git, no host dependency. - Has **first-class Gitea/Forgejo integration** (contributor lists, PR links) — `git-cliff.org/docs/integration/gitea/`. - Can be run as a container job in `.forgejo/workflows/`; two separate configs can produce two changelogs (one per track). - Trade-off: it generates changelogs but doesn't *bump versions* itself — pair with a small script or `conventional-recommended-bump`. **B. `semantic-release` + `semantic-release-gitea`** - Full automation (version determination + changelog + release publishing). - `@saithodev/semantic-release-gitea` exists specifically to publish a Gitea release; likely Forgejo-compatible via the API. - Trade-off: heavier, opinionated, multi-package config is more involved; the Gitea plugin is community-maintained. **C. `release-plz` (Rust crates)** - Native for Cargo workspaces — ideal for the **desktop** track (Tauri/Cargo). - Doesn't cover the Java/Maven side, so we'd still need a second tool for the backend — two tools, but two tracks anyway. **D. Minimal in-house script (extend `scripts/release.sh`)** - Already partially exists; extend it to bump each track independently and hand-write/render changelog entries. - Trade-off: least "automated," but proportionate for a one-team project and zero new dependencies. ### What needs researching before coding - [ ] Does Forgejo's API support everything release-please used (create release, attach assets, close changelog PR)? Confirm `semantic-release-gitea` / `forgejo-release` action coverage. - [ ] Which runner will execute this — `.forgejo/workflows/` with a `docker` runner (what actually runs today), not `ubuntu-latest`/`windows-latest` (see PR #24). - [ ] How to keep the **two version tracks** cleanly separate (two configs? two changelogs? two tags? prefix tags `backend-v*` / `desktop-v*`?). - [ ] Changelog format: keep conventional-commits style? (the existing `CHANGELOG.md` is release-please-flavored with full URLs). - [ ] Interaction with PR #22 (version alignment) and PR #24 (release workflow) — this PR should *own* the version-bump policy so those don't conflict. ### Out of scope for this PR (for now) - Actual implementation of the chosen tool. - Any version bump itself. ### Decision requested Please weigh in on A–D (or propose another) in a comment. Once the approach is agreed, I'll scope a follow-up implementation branch that keeps the backend and desktop tracks independent. ### Merge ordering (blocking dependency) This PR owns the version-bump policy, so it should merge **before** the version/release PRs that depend on it. Recommended sequence: 1. **#25 (this PR)** — decide the release-versioning approach. 2. **#22** — version alignment (`extra-files` wiring must match the #25 decision). 3. **#23** — README/cleanup (independent, but keep it after so it doesn't mask the version decision). 4. **#24** — release workflow (bump mechanism must align with #25). #22 and #24 are marked as *blocked by* this PR via Forgejo's native issue dependencies.
Proposed decision record capturing the release-please replacement options
and the separate backend/desktop version-track requirement. No
implementation code yet — awaiting discussion in PR #25.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
chore: remove stray PR body file
All checks were successful
CI / backend-test (pull_request) Successful in 2m24s
CI / frontend-test (pull_request) Successful in 19s
CI / rust-test (pull_request) Successful in 30s
a9d02222bc
Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
docs(adr): accept ADR 0001 for git-cliff dual-track release versioning on Forgejo
All checks were successful
CI / backend-test (pull_request) Successful in 2m17s
CI / frontend-test (pull_request) Successful in 19s
CI / rust-test (pull_request) Successful in 25s
e72150c979
Author
Owner

Architectural Decision: Option A (git-cliff) with Dual-Track Automation

Following thorough research across all 4 options, Option A (git-cliff) is accepted for release versioning and changelog automation on Forgejo.

Research Findings & Answers to Open Questions

  1. Forgejo API & Automation Capabilities:

    • Forgejo API (/api/v1/repos/{owner}/{repo}/releases) supports full release lifecycle management and asset uploads via https://code.forgejo.org/actions/forgejo-release@v2.
    • No GitHub Actions-specific dependencies required.
  2. Execution Environment:

    • Native execution inside .forgejo/workflows/ using runs-on: docker container images (maven:3.9-eclipse-temurin-21, node:22, rust:latest, and orhunp/git-cliff:latest).
  3. Independent Version Tracks:

    • Backend Track: Tags backend-v<semver> (or canonical v<semver>), driven by cliff-backend.toml scoped to backend/**.
    • Desktop Track: Tags desktop-v<semver>, driven by cliff-desktop.toml scoped to desktop/**.
  4. Changelog Format:

    • Standard Conventional Commits rendered with native Forgejo links (https://git.gaboggamer.online/PCivil/inventory-system/commit/${COMMIT_HASH}).
  5. Alignment with PR #22 and PR #24:

    • Decommissions release-please configuration.
    • Updates scripts/release.sh to support track arguments: bash scripts/release.sh [backend|desktop|all] [major|minor|patch].

ADR 0001 has been updated to Accepted status in commit e72150c.

## Architectural Decision: Option A (`git-cliff`) with Dual-Track Automation Following thorough research across all 4 options, **Option A (`git-cliff`)** is accepted for release versioning and changelog automation on Forgejo. ### Research Findings & Answers to Open Questions 1. **Forgejo API & Automation Capabilities**: - Forgejo API (`/api/v1/repos/{owner}/{repo}/releases`) supports full release lifecycle management and asset uploads via `https://code.forgejo.org/actions/forgejo-release@v2`. - No GitHub Actions-specific dependencies required. 2. **Execution Environment**: - Native execution inside `.forgejo/workflows/` using `runs-on: docker` container images (`maven:3.9-eclipse-temurin-21`, `node:22`, `rust:latest`, and `orhunp/git-cliff:latest`). 3. **Independent Version Tracks**: - **Backend Track**: Tags `backend-v<semver>` (or canonical `v<semver>`), driven by `cliff-backend.toml` scoped to `backend/**`. - **Desktop Track**: Tags `desktop-v<semver>`, driven by `cliff-desktop.toml` scoped to `desktop/**`. 4. **Changelog Format**: - Standard Conventional Commits rendered with native Forgejo links (`https://git.gaboggamer.online/PCivil/inventory-system/commit/${COMMIT_HASH}`). 5. **Alignment with PR #22 and PR #24**: - Decommissions `release-please` configuration. - Updates `scripts/release.sh` to support track arguments: `bash scripts/release.sh [backend|desktop|all] [major|minor|patch]`. ADR 0001 has been updated to **Accepted** status in commit `e72150c`.
Author
Owner

Findings — direction is confirmed: git-cliff, not the in-house script

Confirmed with the maintainer: the release-versioning approach is Option A — git-cliff with dual-track configs (as recorded in ADR 0001). The in-house scripts/release.sh full-bump approach is not the target — at most, git-cliff needs a thin orchestrator to handle its one real drawback (it doesn't rewrite version files itself).

This PR is currently not aligned with that decision, and it's blocking #22 and #24. Here's the specific disconnect:

What ADR 0001 (this PR) decides

  • Tool: git-cliff
  • Configs: cliff-backend.toml + cliff-desktop.toml
  • Tags: backend-v* / desktop-v*
  • "release-please-config.json and .release-please-manifest.json are decommissioned"

What the implementation PRs actually do right now

  • #24 still runs release-please in .github/workflows/release.yml (googleapis/release-please-action@v4, release-please-config.json, gh release upload) and has no git-cliff integration (no cliff-*.toml, no --bumped-version).
  • #22 still hardens release-please-config.json extra-files — the exact file this ADR says to remove.

So the decision and the code currently point in opposite directions. This ADR is the correct north star; the other two need to follow it, not the reverse.

No change needed here

This PR is just the accepted ADR — it can merge as-is. But it should stay unmerged-and-blocking (it already blocks #22/#24 via the dependency link) until #22 and #24 are brought in line with it, so we don't merge a decision and then immediately merge code that contradicts it.

For #22 and #24 (to resolve the conflict)

  • #24: replace the release-please job with git-cliff — add cliff-backend.toml / cliff-desktop.toml, trigger the Forgejo workflow per-track (backend-v* → backend build, desktop-v* → desktop build), and render changelogs via git-cliff. Keep scripts/release.sh only as a thin version-file orchestrator (bump pom.xml/Cargo.toml/package.json), not as the changelog engine.
  • #22: drop the release-please-config.json extra-files change (and the .release-please-manifest.json if it's only there to serve release-please). Keep just the version alignment + Cargo.lock sync.
## Findings — direction is confirmed: git-cliff, not the in-house script Confirmed with the maintainer: the release-versioning approach is **Option A — `git-cliff` with dual-track configs** (as recorded in ADR 0001). The in-house `scripts/release.sh` full-bump approach is *not* the target — at most, git-cliff needs a thin orchestrator to handle its one real drawback (it doesn't rewrite version files itself). This PR is currently **not aligned** with that decision, and it's blocking #22 and #24. Here's the specific disconnect: ### What ADR 0001 (this PR) decides - Tool: `git-cliff` - Configs: `cliff-backend.toml` + `cliff-desktop.toml` - Tags: `backend-v*` / `desktop-v*` - **"`release-please-config.json` and `.release-please-manifest.json` are decommissioned"** ### What the implementation PRs actually do right now - **#24** still runs `release-please` in `.github/workflows/release.yml` (`googleapis/release-please-action@v4`, `release-please-config.json`, `gh release upload`) and has **no `git-cliff` integration** (no `cliff-*.toml`, no `--bumped-version`). - **#22** still hardens `release-please-config.json` `extra-files` — the exact file this ADR says to remove. So the decision and the code currently point in opposite directions. This ADR is the correct north star; the other two need to follow it, not the reverse. ### No change needed here This PR is just the accepted ADR — it can merge as-is. But it should stay **unmerged-and-blocking** (it already blocks #22/#24 via the dependency link) until #22 and #24 are brought in line with it, so we don't merge a decision and then immediately merge code that contradicts it. ### For #22 and #24 (to resolve the conflict) - **#24**: replace the release-please job with git-cliff — add `cliff-backend.toml` / `cliff-desktop.toml`, trigger the Forgejo workflow per-track (`backend-v*` → backend build, `desktop-v*` → desktop build), and render changelogs via git-cliff. Keep `scripts/release.sh` only as a thin *version-file* orchestrator (bump `pom.xml`/`Cargo.toml`/`package.json`), not as the changelog engine. - **#22**: drop the `release-please-config.json` `extra-files` change (and the `.release-please-manifest.json` if it's only there to serve release-please). Keep just the version alignment + Cargo.lock sync.
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference
PCivil/inventory-system!25
No description provided.