Automating Redmine Changelogs and Wiki Updates with GitHub Actions

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.md file 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:

NameTypeExample
REDMINE_API_KEYSecret<your-redmine-api-key>
REDMINE_BASE_URLVariablehttps://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:

  1. Compare commits between two version tags
  2. Extract any referenced Redmine issue IDs (e.g., #1234)
  3. Fetch their titles from Redmine using the API
  4. Build a Markdown changelog section
  5. Prepend it to your Operations/projecttracking/changelog.md
  6. Commit and push the updated file
  7. 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 Secret
  • REDMINE_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.