Sync markdown files from a git repo to Confluence as a page hierarchy
Project description
gitfluence
Sync markdown files from any git repo working tree to Confluence as a page hierarchy.
Uses mdfluence for markdown → Confluence conversion and upload. All mdfluence CLI options can be passed through gitfluence.
Installation
pip install gitfluence
Usage
gitfluence <repo-path> # auto-detect prod vs int
gitfluence --dry-run <repo-path> # preview, no API calls
gitfluence --space MYSPACE . # override space
gitfluence --prefix "DEV" . # override auto-prefix
gitfluence --beautify-folders . # pass mdfluence options
Environment Variables
| Variable | Required | Description |
|---|---|---|
CONFLUENCE_HOST |
Yes | Confluence REST API base URL |
CONFLUENCE_TOKEN |
Yes* | PAT for Confluence (token > username/password) |
CONFLUENCE_USERNAME |
No | Username for basic auth |
CONFLUENCE_PASSWORD |
No | Password for basic auth |
CONFLUENCE_INT_HOST |
No | Integration Confluence REST API base URL (defaults to prod) |
CONFLUENCE_INT_TOKEN |
No* | PAT for integration writes |
CONFLUENCE_INT_USERNAME |
No | Username for integration basic auth |
CONFLUENCE_INT_PASSWORD |
No | Password for integration basic auth |
CONFLUENCE_SPACE |
Yes* | Confluence space key |
* On --dry-run, missing host defaults to https://dummy.example.com/api, missing tokens default to dummy and missing space defaults to DRY_RUN. In interactive mode, missing values are prompted.
Auth decision (per target): token > username+password > prompt > dry-run dummy.
macOS / Linux
Copy setenv.example.sh to setenv.sh and fill in your values:
cp setenv.example.sh setenv.sh
Edit setenv.sh with your Confluence details.
source setenv.sh
Windows (PowerShell)
Copy setenv.example.ps1 to setenv.ps1 and fill in your values:
Copy-Item setenv.example.ps1 setenv.ps1
Edit setenv.ps1 with your Confluence details.
. .\setenv.ps1
Prod vs Integration Logic
| Condition | Write target | Prefix |
|---|---|---|
| On default branch, clean, up-to-date with remote | Prod | (none) |
| Feature branch / dirty tree / behind remote | Integration | (none) |
Page Hierarchy
All root-level pages from the repo are created as children of the Confluence space's home page. Subdirectories become nested child pages.
In integration mode (feature branches), the following hierarchy is created:
Space Homepage
└── {repo-name} (integration root)
└── Branch: {branch} (branch grouping page)
└── Page Title (content pages)
└── Sub Page
- Integration root — an empty page named after the repository directory, created under the space homepage. Deleting it removes all integration artifacts.
- Branch page — an empty page titled
Branch: {branch-name}under the integration root. Groups all content pages for that branch. Each branch gets its own grouping page. - Content pages — the actual documentation pages, created as children of the branch page with clean titles (no branch prefix).
GitHub Action
Consumer repos can integrate using the composite action:
name: Sync to Confluence
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
sync:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: geopanther/gitfluence@main
with:
repo_path: "."
extra_args: "--beautify-folders"
confluence_host: ${{ secrets.CONFLUENCE_HOST }}
confluence_token: ${{ secrets.CONFLUENCE_TOKEN }}
confluence_space: ${{ secrets.CONFLUENCE_SPACE }}
Action inputs
| Input | Default | Description |
|---|---|---|
repo_path |
"." |
Root directory to sync |
dry_run |
"false" |
Preview mode |
gitfluence_version |
"latest" |
Version to install |
python_version |
"3.12" |
Python version |
extra_args |
"" |
Additional CLI args |
confluence_host |
— | Confluence host URL |
confluence_token |
— | Confluence API token |
confluence_int_host |
"" |
Confluence integration host URL |
confluence_int_token |
"" |
Confluence integration API token |
confluence_space |
— | Confluence space key |
CLI Options
gitfluence-specific options
These options are not available in mdfluence:
| Option | Description |
|---|---|
repo_path |
Root directory of the git working tree to sync (positional) |
--space |
Override Confluence space key |
--prefix |
Override auto-detected page title prefix |
-v / --verbose / --debug |
Enable debug logging |
-n (alias for --dry-run) |
Print what would be done without calling API |
--no-preface |
Disable the default preface (DO-NOT-EDIT banner) |
--no-postface |
Disable the default postface (metadata footer) |
--host-int |
Integration Confluence host (env: CONFLUENCE_INT_HOST) |
--token-int |
Integration Confluence token (env: CONFLUENCE_INT_TOKEN) |
--username-int |
Integration Confluence username |
--password-int |
Integration Confluence password |
Note:
--page-idis not supported. Pages are managed by directory hierarchy. Use--parent-idto anchor pages under a specific parent.
Differences from mdfluence defaults
gitfluence changes the following mdfluence defaults to be enabled by default:
| Option | mdfluence default | gitfluence default |
|---|---|---|
--strip-top-header |
off | on |
--only-changed |
off | on |
--collapse-single-pages |
off | on |
--skip-empty |
off | on |
--skip-subtrees-wo-markdown |
off | on |
--enable-relative-links |
off | on |
Preface and postface behave differently from mdfluence:
- mdfluence:
--preface-markdown/--postface-markdownaccept an optional value; when given without a value they default to a static "Contents are auto-generated, do not edit." message. No template placeholders. - gitfluence: Both always require a value. All preface/postface sources (CLI string, file, and bundled defaults) support
{branch_name},{repo_origin},{username},{hostname},{timestamp}template placeholders. Bundled defaults are richer (repo origin, branch, author, timestamp).
mdfluence pass-through options
All remaining mdfluence options are passed through unchanged:
Login: --host / -o, --token, --username / -u, --password / -p, --insecure
Page information: --title, --content-type (choices: page/blogpost), --message, --minor-edit, --strip-top-header, --remove-text-newlines, --replace-all-labels
Parent selection (mutually exclusive): --parent-title / --parent-id / --top-level
Preface (mutually exclusive): --preface-markdown / --preface-file / --no-preface
By default a "DO NOT EDIT" banner with repo origin and branch name is prepended. All preface sources support
{branch_name},{repo_origin},{username},{hostname},{timestamp}placeholders.
Postface (mutually exclusive): --postface-markdown / --postface-file / --no-postface
By default a metadata footer with repo origin, branch, author and timestamp is appended. All postface sources support the same placeholders as preface.
Directory: --collapse-single-pages, --no-gitignore, --skip-subtrees-wo-markdown
Directory titles (mutually exclusive): --beautify-folders / --use-pages-file
Empty dirs (mutually exclusive): --collapse-empty / --skip-empty
Relative links: --enable-relative-links, --ignore-relative-link-errors
Anchors: --convert-anchors / --no-convert-anchors
General: --only-changed, --max-retries
Development
See CONTRIBUTING.md for development setup and guidelines.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gitfluence-0.2.0.tar.gz.
File metadata
- Download URL: gitfluence-0.2.0.tar.gz
- Upload date:
- Size: 73.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6a7dd34410e8fb0414db2213c0e00d017bc8a4d31a974bc8b9884bf0fb4ebbf1
|
|
| MD5 |
8d817f53c15bca82256e025ea7ac11a4
|
|
| BLAKE2b-256 |
b67416ace7763c3ddcd9063822480796807ee1d0ba8878c1f1f64cf5671da485
|
Provenance
The following attestation bundles were made for gitfluence-0.2.0.tar.gz:
Publisher:
deploy-prod.yml on geopanther/gitfluence
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gitfluence-0.2.0.tar.gz -
Subject digest:
6a7dd34410e8fb0414db2213c0e00d017bc8a4d31a974bc8b9884bf0fb4ebbf1 - Sigstore transparency entry: 1524898542
- Sigstore integration time:
-
Permalink:
geopanther/gitfluence@2aef8beee2266eca7446c1b7bddcecfb6109fc5f -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/geopanther
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
deploy-prod.yml@2aef8beee2266eca7446c1b7bddcecfb6109fc5f -
Trigger Event:
push
-
Statement type:
File details
Details for the file gitfluence-0.2.0-py3-none-any.whl.
File metadata
- Download URL: gitfluence-0.2.0-py3-none-any.whl
- Upload date:
- Size: 15.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e71959885f77d5afe83a45c75ff0bff3538256bc075a18727668add18d38adb6
|
|
| MD5 |
55ff8e51f1d913e0012fdc2ad83b5236
|
|
| BLAKE2b-256 |
735df3c4e0a1776270d4ffd6ebfca09f8b2f057a5a872b0c67ce9792fad100cf
|
Provenance
The following attestation bundles were made for gitfluence-0.2.0-py3-none-any.whl:
Publisher:
deploy-prod.yml on geopanther/gitfluence
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gitfluence-0.2.0-py3-none-any.whl -
Subject digest:
e71959885f77d5afe83a45c75ff0bff3538256bc075a18727668add18d38adb6 - Sigstore transparency entry: 1524898548
- Sigstore integration time:
-
Permalink:
geopanther/gitfluence@2aef8beee2266eca7446c1b7bddcecfb6109fc5f -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/geopanther
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
deploy-prod.yml@2aef8beee2266eca7446c1b7bddcecfb6109fc5f -
Trigger Event:
push
-
Statement type: