Skip to content

Wiki Operations with gh cli

martyy-code edited this page Aug 4, 2026 · 4 revisions

This page shows how to read and write the deessejs/fp wiki directly from the command line using the gh CLI.

Mental model: a GitHub wiki is just a separate Git repository that lives at https://github.com/deessejs/fp.wiki.git. The gh CLI treats it as a normal repo, so every wiki operation is really a Git operation.

Outline

  1. Prerequisites
  2. Clone the wiki
  3. Inspect the wiki without cloning
  4. Read pages
  5. Create or update a page
  6. Pull before you push
  7. Configure a committer identity
  8. Automate: sync the wiki from apps/web content
  9. Limits and gotchas
  10. Quick reference

1. Prerequisites

  • gh CLI installed and authenticated.
  • A GitHub account with at least write access to the deessejs/fp repository (which grants push access to its wiki).

Authenticate interactively:

gh auth login

Verify the active account has the right scope:

gh auth status
# → should list a token with the "repo" scope

Set the default repository so subsequent commands can omit it:

gh repo set-default deessejs/fp

Make sure Git uses the gh credential helper for HTTPS pushes:

gh auth setup-git

2. Clone the wiki

Because the wiki is a real Git repository, gh repo clone works on it exactly like on the main code repository:

gh repo clone deessejs/fp.wiki ./fp.wiki
cd ./fp.wiki

The default branch of deessejs/fp.wiki is master. Pages are plain Markdown files at the root of the repository; the filename (minus extension) becomes the page title.

fp.wiki/
├── Home.md
├── _Sidebar.md
└── Wiki-Operations-with-gh-cli.md

3. Inspect the wiki without cloning

A git ls-remote is enough to confirm the wiki exists and to see its refs:

git ls-remote https://github.com/deessejs/fp.wiki.git
# cfdd35635cc213cfbc482b2faefd4375e1b23868  HEAD
# cfdd35635cc213cfbc482b2faefd4375e1b23868  refs/heads/master

You can also use the gh CLI to inspect the parent repository's wiki status:

gh api repos/deessejs/fp --jq '{has_wiki: .has_wiki, default_branch: .default_branch}'

This is the only wiki-related field exposed by the REST API — there are no /repos/.../wiki endpoints to list, create, or edit pages.

4. Read pages

List pages

gh repo clone deessejs/fp.wiki /tmp/fp.wiki -- --depth 1
ls /tmp/fp.wiki
# Home.md  _Sidebar.md  some-page.md

Read a single page

After cloning, treat the file like any other Markdown document:

cat /tmp/fp.wiki/Home.md

If you don't want a full clone, the GitHub Contents API does not expose wiki files. Use git show on the wiki repo instead:

git clone --depth 1 https://github.com/deessejs/fp.wiki.git /tmp/fp.wiki
git -C /tmp/fp.wiki show master:Home.md

View history

Each save in the web UI is a Git commit:

git -C /tmp/fp.wiki log --oneline
git -C /tmp/fp.wiki log --oneline -- Home.md

5. Create or update a page

Pages are files, so the workflow is: edit, commit, push.

Create a new page

gh repo clone deessejs/fp.wiki ./fp.wiki
cd ./fp.wiki

cat > Wiki-Operations-with-gh-cli.md <<'MD'
# Wiki Operations with `gh` CLI
...your content...
MD

git add Wiki-Operations-with-gh-cli.md
git commit -m "docs(wiki): add gh CLI operations guide"
git push

Update an existing page

cd ./fp.wiki
$EDITOR Home.md
git add Home.md
git commit -m "docs(wiki): clarify installation steps on Home"
git push

Delete a page

cd ./fp.wiki
git rm some-page.md
git commit -m "docs(wiki): remove obsolete page"
git push

Filename rules

  • The filename (without extension) becomes the page title.
  • Use only [A-Za-z0-9._-] in filenames. The web UI also rejects: \ / : * ? " < > |.
  • For multi-word titles, hyphens are conventional (Wiki-Operations-with-gh-cli.md).
  • Reserved filenames: _Sidebar.md (sidebar shared across pages) and _Footer.md (footer).
  • File extension controls the renderer (Markdown by default; also AsciiDoc, Textile, etc.).

6. Pull before you push

If anyone else may have edited the wiki, rebase before pushing to avoid non-fast-forward errors:

cd ./fp.wiki
git pull --rebase
git push

A safer variant for automation is to abort on conflict rather than force-push:

cd ./fp.wiki
git pull --rebase || { echo "wiki conflict, manual merge required"; exit 1; }
git push

7. Configure a committer identity

Git requires a user.name and user.email for commits. For a one-off edit:

cd ./fp.wiki
git config user.name  "your-name"
git config user.email "you@example.com"

For automation, prefer a no-reply GitHub-provided email so contributions are linked to your account:

git config user.name  "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"

To find your own no-reply address, see the GitHub settings page.

8. Automate: sync the wiki from apps/web content

A common pattern is to regenerate wiki pages from a canonical source (here, MDX in apps/web). The following snippet can be dropped into a GitHub Actions workflow:

name: sync-wiki
on:
  push:
    branches: [main]
    paths: ['apps/web/content/docs/**']

jobs:
  sync:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          repository: deessejs/fp
          path: repo

      - name: Clone wiki
        run: |
          git clone "https://github.com/deessejs/fp.wiki.git" wiki
          git config --global user.name  "github-actions[bot]"
          git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"

      - name: Regenerate wiki pages
        run: |
          cp repo/apps/web/content/docs/index.mdx          wiki/Home.md
          cp repo/apps/web/content/docs/getting-started.mdx wiki/Getting-Started.md
          cp repo/apps/web/content/docs/result.mdx         wiki/Result.md
          cp repo/apps/web/content/docs/maybe.mdx          wiki/Maybe.md
          cp repo/apps/web/content/docs/unit.mdx           wiki/Unit.md

      - name: Publish
        working-directory: wiki
        run: |
          git add .
          git diff --cached --quiet && exit 0
          git commit -m "docs(wiki): sync from main"
          git pull --rebase
          git push

The default GITHUB_TOKEN is not allowed to push to the wiki repository. Either grant the workflow a GitHub App / PAT with repo scope on deessejs/fp, or expose secrets.WIKI_PUSH_TOKEN and pass it as a credential helper:

- name: Push wiki
  env:
    WIKI_PUSH_TOKEN: ${{ secrets.WIKI_PUSH_TOKEN }}
  run: |
    git -c "credential.helper=" \
        -c "credential.helper=!f() { echo username=x-access-token; echo password=$WIKI_PUSH_TOKEN; }; f" \
        push https://github.com/deessejs/fp.wiki.git master

9. Limits and gotchas

  • Soft cap of 5 000 files per wiki. Beyond that, some pages may become inaccessible — for larger documentation sets, prefer GitHub Pages.
  • Search-engine indexing is limited to wikis with 500+ stars that are configured to forbid public editing.
  • Branches can be created locally, but only pushes to the default branch are published.
  • Private repos propagate their visibility: the wiki is private too and follows the repository's collaborator list.
  • No REST/GraphQL wiki endpoints — there is no GET /repos/.../wiki/pages. The wiki is only manageable over Git. REST only exposes has_wiki on the parent repo.
  • First-page bootstrap — if the wiki was never opened in the web UI, the .wiki.git remote may not exist yet. Create the initial page from the web UI once before automating.

10. Quick reference

Goal Command
Check the parent repo's wiki flag gh api repos/deessejs/fp --jq .has_wiki
Clone the wiki gh repo clone deessejs/fp.wiki ./fp.wiki
List pages ls ./fp.wiki
Read a page git -C ./fp.wiki show master:Home.md
Create a page write the file, git add, git commit, git push
Update a page edit, git add, git commit, git push
Delete a page git rm <file>, git commit, git push
Page history git -C ./fp.wiki log -- <file>
Safe automation push git pull --rebase && git push

This page is maintained in the wiki repository itself. Edit it via the workflow above, or open the wiki in the web UI.

Clone this wiki locally