Metadata-Version: 2.4
Name: gitfluence
Version: 0.2.0
Summary: Sync markdown files from a git repo to Confluence as a page hierarchy
Project-URL: Homepage, https://github.com/geopanther/gitfluence
Project-URL: Repository, https://github.com/geopanther/gitfluence
Project-URL: Changelog, https://github.com/geopanther/gitfluence/blob/main/CHANGELOG.md
Author-email: geopanther <geopanther@mail.de>
License-Expression: MIT
Keywords: confluence,git,markdown,md2cf,mdfluence,sync
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.12
Requires-Dist: gitpython>=3.1.50
Requires-Dist: identify>=2.6.19
Requires-Dist: mdfluence>=0.4.0
Requires-Dist: pydantic-settings>=2.0
Requires-Dist: pydantic>=2.0
Requires-Dist: urllib3>=2.7.0
Description-Content-Type: text/markdown

# gitfluence

Sync markdown files from any git repo working tree to Confluence as a page hierarchy.

Uses [mdfluence](https://github.com/geopanther/mdfluence) for markdown → Confluence conversion and upload. All mdfluence CLI options can be passed through gitfluence.

## Installation

```bash
pip install gitfluence
```

## Usage

```bash
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.

<details open>
<summary><b>macOS / Linux</b></summary>

Copy `setenv.example.sh` to `setenv.sh` and fill in your values:

```bash
cp setenv.example.sh setenv.sh
```

Edit `setenv.sh` with your Confluence details.

```bash
source setenv.sh
```

</details>

<details>
<summary><b>Windows (PowerShell)</b></summary>

Copy `setenv.example.ps1` to `setenv.ps1` and fill in your values:

```powershell
Copy-Item setenv.example.ps1 setenv.ps1
```

Edit setenv.ps1 with your Confluence details.

```powershell
. .\setenv.ps1
```

</details>

## 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:

```yaml
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-id` is not supported. Pages are managed by directory hierarchy. Use `--parent-id` to 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-markdown` accept 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](CONTRIBUTING.md) for development setup and guidelines.

## License

MIT
