Signs the commit that bump-version makes after a stable release, so the automated bump PR can be merged into main now that it requires signed commits.
What changed
.gitea/workflows/release.yml — new Configure signing as Release Bot step in the bump-version job. It materialises secrets.RELEASE_BOT_SIGNING_KEY into $RUNNER_TEMP at 0600, derives the .pub beside it, and switches git to SSH signing (gpg.format ssh). The push step then re-reads the commit and refuses to push if no gpgsig header is present.
docs/ci.md — new "Signing the version bump commit" section covering the one-time instance setup and its trade-offs.
Setup required before the next release
This is inert — and the job will fail loudly — until both are in place:
[repository.signing] TRUSTED_SSH_KEYS in app.ini lists the release-bot public key, and Gitea has been restarted.
The organisation Actions secret RELEASE_BOT_SIGNING_KEY holds the matching OpenSSH private key.
No release-bot Gitea account is involved: an account key is only used for signature checking after the web Verify flow, which has no API, so TRUSTED_SSH_KEYS is what makes the signature verify without an account lookup.
Tests
composer test — 966 tests, 2795 assertions, all passing.
The signing step was extracted and run against five secret shapes with GIT_CONFIG_GLOBAL/GIT_CONFIG_SYSTEM pinned to /dev/null: a valid OpenSSH key, the same key with CRLF endings, the same key with the trailing newline stripped (all three produce a signed commit), and passphrase-protected and truncated keys (both fail the step with the intended message).
No CHANGELOG.md entry: nothing here is visible to a WordPress site.
Signs the commit that `bump-version` makes after a stable release, so the automated bump PR can be merged into `main` now that it requires signed commits.
## What changed
- `.gitea/workflows/release.yml` — new `Configure signing as Release Bot` step in the `bump-version` job. It materialises `secrets.RELEASE_BOT_SIGNING_KEY` into `$RUNNER_TEMP` at 0600, derives the `.pub` beside it, and switches git to SSH signing (`gpg.format ssh`). The push step then re-reads the commit and refuses to push if no `gpgsig` header is present.
- `docs/ci.md` — new "Signing the version bump commit" section covering the one-time instance setup and its trade-offs.
## Setup required before the next release
This is inert — and the job will fail loudly — until both are in place:
1. `[repository.signing] TRUSTED_SSH_KEYS` in `app.ini` lists the release-bot public key, and Gitea has been restarted.
2. The organisation Actions secret `RELEASE_BOT_SIGNING_KEY` holds the matching OpenSSH private key.
No `release-bot` Gitea account is involved: an account key is only used for signature checking after the web *Verify* flow, which has no API, so `TRUSTED_SSH_KEYS` is what makes the signature verify without an account lookup.
## Tests
- `composer test` — 966 tests, 2795 assertions, all passing.
- The signing step was extracted and run against five secret shapes with `GIT_CONFIG_GLOBAL`/`GIT_CONFIG_SYSTEM` pinned to `/dev/null`: a valid OpenSSH key, the same key with CRLF endings, the same key with the trailing newline stripped (all three produce a signed commit), and passphrase-protected and truncated keys (both fail the step with the intended message).
No `CHANGELOG.md` entry: nothing here is visible to a WordPress site.
main now requires signed commits, and Gitea refuses to merge a pull request
carrying an unsigned one, so the post-release bump PR could not be merged
without disabling the protection first.
The runner now signs that commit with a dedicated release-bot SSH key held as
an organisation Actions secret, trusted by the instance through
[repository.signing] TRUSTED_SSH_KEYS. The key Gitea signs merge commits with
lives on the server and no runner can reach it.
The step fails fast when the secret is missing, unparseable or passphrase
protected, and the commit is re-read before pushing so an unsigned one is
caught here rather than days later at merge time.
Co-Authored-By: Claude Opus 5 <[email protected]>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Signs the commit that
bump-versionmakes after a stable release, so the automated bump PR can be merged intomainnow that it requires signed commits.What changed
.gitea/workflows/release.yml— newConfigure signing as Release Botstep in thebump-versionjob. It materialisessecrets.RELEASE_BOT_SIGNING_KEYinto$RUNNER_TEMPat 0600, derives the.pubbeside it, and switches git to SSH signing (gpg.format ssh). The push step then re-reads the commit and refuses to push if nogpgsigheader is present.docs/ci.md— new "Signing the version bump commit" section covering the one-time instance setup and its trade-offs.Setup required before the next release
This is inert — and the job will fail loudly — until both are in place:
[repository.signing] TRUSTED_SSH_KEYSinapp.inilists the release-bot public key, and Gitea has been restarted.RELEASE_BOT_SIGNING_KEYholds the matching OpenSSH private key.No
release-botGitea account is involved: an account key is only used for signature checking after the web Verify flow, which has no API, soTRUSTED_SSH_KEYSis what makes the signature verify without an account lookup.Tests
composer test— 966 tests, 2795 assertions, all passing.GIT_CONFIG_GLOBAL/GIT_CONFIG_SYSTEMpinned to/dev/null: a valid OpenSSH key, the same key with CRLF endings, the same key with the trailing newline stripped (all three produce a signed commit), and passphrase-protected and truncated keys (both fail the step with the intended message).No
CHANGELOG.mdentry: nothing here is visible to a WordPress site.9c6b4415cdtoc4b2b5ccff