Publish to GitHub wiki
July 11, 2026 ยท View on GitHub
๐ GitHub Action to sync a folder to the GitHub wiki

๐ Keep your dev docs in sync with your code
๐ก Inspired by Decathlon/wiki-page-creator-action#11
๐ Able to open PRs with docs updates
โจ Use the fancy GitHub wiki reader UI for docs
๐ Works across repositories (with a PAT)
๐ป Supports runs-on: windows-*
Usage
Add a GitHub Actions workflow file to your .github/workflows/ folder similar
to the example shown below.
name: Publish wiki
on:
push:
branches: [main]
paths:
- wiki/**
- .github/workflows/publish-wiki.yml
concurrency:
group: publish-wiki
cancel-in-progress: true
permissions:
contents: write
jobs:
publish-wiki:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: Andrew-Chen-Wang/github-wiki-action@v5
โ This workflow will mirror the wiki/ folder in your GitHub repository to the
user/repo.wiki.git Git repo that houses the wiki documentation! You can use
any of the supported markup languages like MediaWiki, Markdown, or AsciiDoc.
๐ In order to successfully push to the .wiki.git Git repository that backs
the wiki tab, we need the contents: write permission! Make sure you have
something like shown above either for your entire workflow, or just for one
particular job. This will give the auto-generated ${{ github.token }} that we
use by default permission to push to the .wiki.git repo of the repository that
the action runs on.
โ ๏ธ You must create a dummy page manually! This is what initially creates the GitHub wiki Git-based storage backend that we then push to in this Action.
After creating your workflow file, now all you need is to put your Markdown
files in a wiki/ folder (or whatever you set the path option to) and commit
them to your default branch to trigger the workflow (or whatever other trigger
you set up).
๐ก Each page has an auto-generated title. It is derived from the filename by
replacing every - (dash) character with a space. Name your files accordingly.
The Home.md file will automatically become the homepage, not README.md. This
is specific to GitHub wikis.
Inputs
-
direction: Select frompushorpull.push(the default) syncs thepathfolder to the GitHub wiki.pulldoes the reverse: it clones the wiki, converts the pages back into source-friendly form (Home.mdbecomesREADME.mdand bare wiki page links get the extension of the page they target back), and mirrors them into thepathfolder of your workspace. Theignoreinput is not applied in pull mode. Nothing is committed or pushed to your repository in pull mode; pair it with a PR-creating action like create-pull-request. See Pulling wiki edits back below. -
strategy: Select fromcloneorinitto determine which method to use to push changes to the GitHub wiki.clonewill clone the.wiki.gitrepo and add an additional commit.initwill create a new repo with a single commit and force push to the.wiki.git.initinvolves a force-push! The default isclone. -
repository: The repository housing the wiki. Use this if you're publishing to a wiki that's not the current repository. You can change the GitHub server with thegithub-server-urlinput. Default is${{ github.repository }}. -
github-server-url: An alternatehttps://github.comURL, usually for GitHub Enterprise deployments under your own domain. Default is${{ github.server_url }}(usuallyhttps://github.com). -
token:${{ github.token }}is the default. This token is used when cloning and pushing wiki changes. -
path: The directory to use for your wiki contents. Defaultwiki/. -
commit-message: The message to use when committing new content. Default isUpdate wiki ${{ github.sha }}. You probably don't need to change this, since this only applies if you look really closely in your wiki. -
ignore: A multiline list of files that should be ignored when committing and pushing to the remote wiki. Each line is a pattern like.gitignore. Make sure these paths are relative to the path option! The default is none. -
dry-run: Whether or not to actually attempt to push changes back to the wiki itself. If this is set totrue, we instead print the remote URL and do not push to the remote wiki. The default isfalse. This is useful for testing. -
preprocess: If this option is true, we will preprocess the wiki to move theREADME.mdtoHome.mdas well as rewriting links to wiki pages to be bare links. Link targets in any markup format GitHub renders (.md,.rst,.adoc, ...) are recognized, though only Markdown files are parsed for links. Relative links that point at other files in your repository (a script, a source file, a Markdown file outside the wiki folder) are rewritten to fullblob/view URLs (raw/URLs for images) pinned to the pushed commit, the same way GitHub resolves them when rendering in-repo Markdown. This helps ensure that the Markdown works in source control as well as the wiki. The default is true. Seepreprocess:notes. -
disable-empty-commits: By default, any triggering of this action will result in a commit to the Wiki, even if that commit is empty. If this option is true, a workflow run which would result in no changes to the Wiki files, will no longer create an empty commit. The default is false.
preprocess: notes
- Only Markdown pages are parsed for links; pages in other formats (
.rst,.adoc, ...) are synced verbatim but still recognized as link targets. - GitHub serves wiki pages flat by basename, so cross-directory page links
are rewritten to bare page names, while same-directory links keep their
form. Reference-style definitions (
[label]: ./page.md) are rewritten like the links or images that use them. - Images pointing at repository files become
raw/URLs (ablob/page would not render inside an image); images shipped inside the wiki folder stay relative. - A page whose name itself ends in a renderable extension (say a page called
example.org) is treated as a file link rather than a page link.
strategy: input
There are some specific usecases where using strategy: init might be better
than the default strategy: clone.
-
Your wiki is enormous. And I don't mean in terms of text. Text is nothing compared with images. If your wiki has a lot of included images, then you probably don't want to store the complete history of those large binary files. Instead, you can use
strategy: initto create a single commit each time. -
You prefer the "deploy" semantics. If you just like the feel of having your GitHub wiki act more like GitHub Pages, that's great! You can
--forcepush usingstrategy: initon each wiki deployment and none of that pesky history will be saved.
Outputs
wiki_url: The HTTP URL that points to the deployed repository's wiki tab. This is essentially the concatenation of${{ github.server_url }},${{ github.repository }}, and the/wikipage.
Pulling wiki edits back
If someone edits a page in the wiki UI, those edits normally get overwritten by
the next push from your wiki/ folder. direction: pull lets you sync them
back into your source tree instead. It clones the wiki, applies the inverse of
the preprocess transformations (Home.md โก README.md, ./page โก
./page.md), and updates the path folder in your workspace. It never
commits or pushes to your repository, so combine it with something like
create-pull-request to open a docs PR:
name: Pull wiki
on:
gollum: # Runs whenever a wiki page is created or edited
workflow_dispatch:
permissions:
contents: write
pull-requests: write
jobs:
pull-wiki:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: Andrew-Chen-Wang/github-wiki-action@v5
with:
direction: pull
- uses: peter-evans/create-pull-request@v8
with:
branch: sync-wiki
title: Sync wiki edits back into wiki/
commit-message: Sync wiki edits back into wiki/
Cross-repo wikis
You can use this action to deploy your octocat/mega-docs repository to the octocat/mega-project repository's wiki tab! You just need to:
- Create a custom GitHub Personal Access Token with the permissions to push to
the octocat/mega-project repository. That's the target repo where your wiki
pages will be pushed to the
.wiki.git. - In the octocat/mega-docs repo (the source code for the wiki), you need to set
the
repository:option torepository: octocat/mega-projectto tell the action to push there. - You need to set the
token:option to the Personal Access Token that you created with the ability to push to the wiki Git repo. You can use repository secrets for this! Something liketoken: ${{ secrets.MY_TOKEN }}is good!
Here's an example of the octocat/mega-docs repo that will push the contents of
the root folder (./) to the octocat/mega-project repo's wiki tab!
on:
push:
branches: [main]
jobs:
publish-wiki:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: Andrew-Chen-Wang/github-wiki-action@v5
with:
token: ${{ secrets.MEGA_PROJECT_GITHUB_TOKEN }}
repository: octocat/mega-project
path: .
Development
This GitHub Action uses a self-downloaded version of Deno. See cliw for the
cli.ts wrapper script that downloads the Deno binary and runs the TypeScript
code. The main script itself is ~100 lines of code, so it's not too bad.
โน Because the version of Deno is pinned, it's recommended to every-so-often bump it to the latest version.
To test the action, open a PR! The test-action.yml workflow will run the code
with dry-run: true as well as a real run! Yes, this does get tedious swapping
between your IDE and the PR, but it's the easiest way to test the action.