FediSuite development fork; upstream https://github.com/vanzhiganov/redmine-forgejo-webhook
  • Ruby 92%
  • HTML 8%
Find a file
2026-10-03 11:12:34 +02:00
app Scope signed webhooks and gate atomic issue transitions by branch and merge 2026-10-03 11:12:34 +02:00
config init 2026-02-08 14:23:58 +03:00
db/migrate Scope signed webhooks and gate atomic issue transitions by branch and merge 2026-10-03 11:12:34 +02:00
test Scope signed webhooks and gate atomic issue transitions by branch and merge 2026-10-03 11:12:34 +02:00
.gitignore init 2026-02-08 14:23:58 +03:00
CHANGELOG.md Scope signed webhooks and gate atomic issue transitions by branch and merge 2026-10-03 11:12:34 +02:00
init.rb Scope signed webhooks and gate atomic issue transitions by branch and merge 2026-10-03 11:12:34 +02:00
LICENSE init 2026-02-08 14:23:58 +03:00
README.md Scope signed webhooks and gate atomic issue transitions by branch and merge 2026-10-03 11:12:34 +02:00

Redmine Forgejo webhook integration

FediSuite maintains this fork of vanzhiganov/redmine-forgejo-webhook. Version 0.3.0 is tested with Redmine 7.0.2, Rails 8.1 and PostgreSQL 17.

Installation and upgrade

Install as plugins/redmine_forgejo_webhook, back up the Redmine database and settings, then run RAILS_ENV=production bundle exec rake redmine:plugins:migrate NAME=redmine_forgejo_webhook and restart Redmine. The migration adds only a receipt table, with unique delivery identities. Upgrading from 0.2 requires reconfiguration: the global secret is deliberately no longer accepted.

Configuration

  1. Enable the Forgejo webhook module in each Redmine project.
  2. In Administration → Plugins → Configure, select a dedicated active, non-administrator integration user. Make this user a member of each target project. Grant only view issues, add notes and edit issues. Configure that role's tracker workflows to permit the desired closed and open statuses.
  3. Explicitly select the closed/open statuses and enable the desired automatic actions.
  4. For each project set the exact HTTPS repository URL, a separate random secret and allowed status branches, e.g. main. Branch names are exact matches; an empty list disables all automatic status changes.
  5. Create a Forgejo webhook pointing to https://REDMINE/forgejo/webhook/PROJECT_IDENTIFIER. Use POST, JSON, the matching project secret, HTTPS certificate verification and events push, pull_request_only, pull_request_sync (Forgejo API names). The unscoped /forgejo/webhook route is rejected. Existing unrelated hooks can remain intact.

Ticket references and status rules

  • #123, refs #123 and references #123 add a ticket reference.
  • fixes #123, fixed #123, closes #123, closed #123 request closing that ticket.
  • reopen #123 / reopens #123 request reopening that ticket.
  • Each numbered clause is independent: fixes #123, refs #456 closes only #123. Contradictory actions for the same ticket produce a reference only. Explicitly repeat keywords for lists.
  • Pushes to development/test branches add references, even for fixes; only allowed heads change status. Tag pushes never change status; branch deletions are ignored.
  • Opened, edited, synchronized, reopened and unmerged closed pull requests only add references. A closed PR must have merged: true and an allowed base branch to change status. References are read from the PR title/body; merged PRs require a valid merge commit SHA.
  • The integration user must have permission and an allowed Redmine workflow transition. Redmine's blocking subtasks/dependencies are honored. Already open/closed tickets retain their current status. Ticket authors, including Anonymous, remain unchanged; the integration user authors the new journals.

Authentication, consistency and limits

HMAC-SHA256 signatures are verified over the original body in constant time, before JSON processing. A blank secret always rejects the request. Both Forgejo and Gitea signature/event headers are supported. Repository html_url and full_name must match the endpoint's configured repository. References may affect only tickets in that endpoint's project. Journal links are constructed from the configured URL. Bodies above 2 MiB are rejected. No Forgejo API token is needed by Redmine.

One project transaction covers the whole request. A missing ticket, forbidden transition or failed save rolls back all journals, status changes and receipts for that request; the sender receives a failure response. Project/issue locks and a unique receipt index prevent duplicate processing. Commit SHA identifies references and each requested action independently. A dev reference can later change status on main without duplicating its comment. Merge and push deliveries with the same SHA share receipts, regardless of arrival order. Replaying a handled close does not close a subsequently human-reopened ticket. Different commits remain distinct; receipts are retained indefinitely. This is not delivery ordering by timestamp. Nonmerged PR references are deduplicated by PR number, action and title/body digest.

Tests

Run unit tests with bundle exec ruby plugins/redmine_forgejo_webhook/test/unit/run.rb. Integration tests require a separately migrated database with Redmine default data: FORGEJO_WEBHOOK_TEST=1 RAILS_ENV=production bundle exec rails runner plugins/redmine_forgejo_webhook/test/integration/run.rb. Each test rolls back its fixture transaction. Never run them on production; the test runner also rejects Setting.host_name == support.fedisuite.com.

Rollback

Disable the newly configured Forgejo hooks before rolling back to the previous image. Restore the saved plugin settings if using an older plugin (which expects its old global secret). The receipt table may remain; older versions do not use it. Avoid restoring the whole database after new tickets have been created. Keep the database backup for recovery under an explicit recovery plan.