Files
yellowjacket/.releaserc.yml
T
logan 087eb77875 ci(release): cut a release from main with semantic-release
The config has been sitting in .releaserc.yml complete and uninvoked;
this is the workflow that runs it, and the one Gitea-shaped adaptation
it needs.

@semantic-release/github speaks GitHub's API, not Gitea's /api/v1, so
@semantic-release/exec calls scripts/gitea-release.sh instead. That
script reads the notes out of CHANGELOG.md rather than taking them as an
argument: release notes are rendered commit messages, so interpolating
the notes into a shell command would be an injection whose input is the
commit log.

The tag is pushed with a user PAT because Gitea does not start a
workflow from a ref pushed by a workflow's own token, and the three
publishing workflows are keyed on it.
2026-08-17 18:38:55 -04:00

109 lines
3.7 KiB
YAML

# semantic-release configuration.
#
# Runs on pushes to main from .gitea/workflows/release.yml: determine the
# version from the Conventional Commits since the last tag, write the
# changelog, commit it, push the tag, and create the Gitea release.
#
# **There is no `@semantic-release/github` plugin here and there must not
# be.** Gitea's API is `/api/v1` and is not GitHub's surface. The Gitea
# community plugin (@saithodev/semantic-release-gitea) was considered and
# rejected: last published 2022, depends on got@10, and declares no peer
# dependency on semantic-release at all — i.e. untested against anything
# since v19, against a core now at v25. `exec` is first-party, current,
# and the Gitea-shaped part is one curl.
#
# The type list below is the one scripts/commit-check.sh enforces the
# grammar for — keep the two in step, or semantic-release will silently
# decline to release something the commit hook accepted.
branches:
- main
plugins:
# Analyze commits using conventional-commits preset.
- - "@semantic-release/commit-analyzer"
- preset: conventionalcommits
releaseRules:
- type: feat
release: minor
- type: fix
release: patch
- type: perf
release: patch
- type: refactor
release: patch
- type: revert
release: patch
- type: docs
release: false
- type: style
release: false
- type: chore
release: false
- type: ci
release: false
- type: test
release: false
- type: build
release: false
# Generate release notes from conventional commits.
- - "@semantic-release/release-notes-generator"
- preset: conventionalcommits
presetConfig:
types:
- type: feat
section: Features
- type: fix
section: Bug Fixes
- type: perf
section: Performance
- type: refactor
section: Refactoring
- type: revert
section: Reverts
- type: docs
section: Documentation
hidden: true
- type: chore
section: Miscellaneous
hidden: true
- type: ci
section: CI/CD
hidden: true
- type: test
section: Tests
hidden: true
- type: build
section: Build
hidden: true
# Write CHANGELOG.md.
#
# This plugin is load-bearing for more than the changelog: it is how the
# release notes reach the Gitea API *without being interpolated into a
# shell command*. Release notes are rendered commit messages — arbitrary
# text carrying backticks, quotes and `$` — so templating
# ${nextRelease.notes} into `publishCmd` would be a shell injection with
# the commit log as its input. scripts/gitea-release.sh reads the top
# section of this file instead, and the only thing interpolated below is
# a semver string.
- - "@semantic-release/changelog"
- changelogFile: CHANGELOG.md
changelogTitle: "# Changelog"
# Create the Gitea release, whose body is that changelog section.
# `publish` runs after `prepare`, so the tag already exists by here.
- - "@semantic-release/exec"
- publishCmd: "./scripts/gitea-release.sh ${nextRelease.version}"
# Commit the changelog back to main.
#
# This is the push that would otherwise re-enter release.yml; the
# workflow guards on this subject rather than trusting [skip ci], whose
# handling in Gitea is one more thing that would have to be verified.
# The subject must also satisfy scripts/commit-check.sh.
- - "@semantic-release/git"
- assets:
- CHANGELOG.md
message: "chore(release): ${nextRelease.version} [skip ci]"