Managing changelogs and project documentation manually can easily become a repetitive, error-prone task — especially when several developers are tagging releases frequently. Fortunately, GitHub Actions makes it possible to automatically generate changelogs and synchronize documentation directly with your Redmine project.
In this post, we’ll walk through a setup that:
- Automatically generates a changelog from Git commits between version tags
- Updates the Redmine Wiki changelog page
- Synchronizes a local
wiki.mdfile with Redmine whenever it changes
We’ll use GitHub Workflows and a couple of small Bash scripts to make it all happen.
🧩 Repository Setup
You can base your setup on a sample project such as: https://github.com/orgname/project-example/
Inside your repository, under Operations/projecttracking, create these two files:
wiki.md
changelog.md
Also, go to your repository Settings → Secrets and Variables → Actions and define:
| Name | Type | Example |
|---|---|---|
REDMINE_API_KEY | Secret | <your-redmine-api-key> |
REDMINE_BASE_URL | Variable | https://redmine.example.com |
These credentials will allow the workflow to communicate securely with your Redmine instance.
⚙️ Workflow 1: Generate and Push Redmine Changelog
Create a workflow file named:
.github/workflows/update-redmine-changelog.yml
This workflow automatically runs whenever a new Git tag (like v1.0.0) is pushed or manually triggered. It will:
- Compare commits between two version tags
- Extract any referenced Redmine issue IDs (e.g.,
#1234) - Fetch their titles from Redmine using the API
- Build a Markdown changelog section
- Prepend it to your
Operations/projecttracking/changelog.md - Commit and push the updated file
- Finally, sync that changelog to Redmine’s Wiki page
Here’s the full YAML workflow (cleaned up for readability):
name: Generate Changelog from Redmine
on:
push:
tags:
- "v*"
workflow_dispatch:
inputs:
current_tag:
description: "Current version tag"
type: string
previous_tag:
description: "Previous version tag"
type: string
permissions:
contents: write
env:
CHANGELOG_PATH: Operations/projecttracking/changelog.md
# REDMINE_BASE_URL and REDMINE_API_KEY are configured in repository settings
jobs:
changelog:
runs-on: ubuntu-latest
steps:
- name: Checkout full repo
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Ensure jq is available
run: |
if ! command -v jq >/dev/null 2>&1; then
sudo apt-get update && sudo apt-get install -y jq
fi
- name: Generate and update changelog
env:
REDMINE_BASE_URL: https://redmine.example.com/
REDMINE_API_KEY: ${{ secrets.REDMINE_API_KEY }}
run: |
# (Full Bash script logic to compare tags, collect commits,
# fetch issue titles, and prepend to changelog.md)
- name: Commit and push updated changelog
run: |
git config user.name "Changelog Bot"
git config user.email "[email protected]"
git checkout main
git pull origin main
git add "$CHANGELOG_PATH"
git commit -m "chore(changelog): update for ${GITHUB_REF##*/}"
git push origin main
- name: Update Redmine Wiki changelog
env:
REDMINE_BASE_URL: https://redmine.example.com/
REDMINE_API_KEY: ${{ secrets.REDMINE_API_KEY }}
PROJECT: example-project
run: |
# PUT changelog contents into Redmine wiki via API
This script uses Redmine’s REST API to push updates to the Changelog wiki page.
The workflow gracefully handles missing tags, duplicate commits, and missing issues.
📘 Workflow 2: Sync wiki.md to Redmine Wiki
Next, we’ll automatically update Redmine whenever wiki.md changes in the repository.
Create another workflow file:
.github/workflows/update-redmine-wiki.yml
This one triggers on any commit affecting Operations/projecttracking/wiki.md or can be run manually.
name: Update Redmine Wiki from wiki.md
on:
push:
paths:
- 'Operations/projecttracking/wiki.md'
workflow_dispatch: {}
jobs:
sync-wiki:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
lfs: true
submodules: recursive
fetch-depth: 0
- name: Ensure jq is installed
run: |
if ! command -v jq >/dev/null 2>&1; then
sudo apt-get update && sudo apt-get install -y jq
fi
- name: Update Redmine Wiki page
env:
BASE_URL: https://redmine.example.com/
API_KEY: ${{ secrets.REDMINE_API_KEY }}
PROJECT: example-project
WIKI_SRC_PATH: ${GITHUB_WORKSPACE}/Operations/projecttracking/wiki.md
run: |
# Read the wiki file, JSON-escape it,
# and PUT to Redmine’s /projects/<project>/wiki/Wiki.json endpoint
Every time wiki.md is updated, the latest content will be synced to Redmine automatically, including a comment showing the originating commit.
🔒 Security and Secrets
All sensitive data (like API keys and Redmine URLs) are stored as GitHub Secrets or Variables, never hardcoded in workflows.
Example:
REDMINE_API_KEY→ GitHub SecretREDMINE_BASE_URL→ Repository Variable
This ensures that only trusted workflows can access them during execution.
✅ Benefits
With this setup:
- Changelogs are always up to date
- Redmine documentation reflects the latest codebase state
- Developers no longer have to manually edit wiki pages or copy-paste commit messages
- The process is traceable, consistent, and versioned
🏁 Conclusion
By combining GitHub Actions with Redmine’s API, we can create a fully automated release documentation flow that keeps changelogs synchronized and project wikis fresh — without ever leaving GitHub.
This setup is flexible: you can easily adapt it for other project management tools or expand it to include release notes generation, CI/CD metadata, or deployment logs.