CCFM — Confluence Cloud Flavoured Markdown
A CLI tool that converts Markdown to Atlassian Document Format (ADF) and deploys pages to Confluence Cloud. Write documentation as Markdown, deploy it as native Confluence pages — no legacy conversions, no storage format hacks, full editor compatibility.
- Native ADF output — Pages open in the Confluence editor without any legacy conversion
- Automatic page hierarchy — Directory structure maps directly to Confluence page hierarchy
- CCFM extensions — Status badges, panels, expands, dates, smart page links, emoji, anchors, image width control
- Dependency-ordered deployment — Pages deploy in topological order so linked pages exist before pages that reference them
- Idempotent — Safe to run multiple times; creates or updates pages automatically
- Remote state — Deployment state stored in Confluence itself, no local files to commit
- Concurrent deploy protection — Terraform-style locking prevents conflicting deploys
- CI/CD ready — Deploy documentation on every commit to your main branch
Full documentation | Syntax reference
Quick Start
1. Get an API token
Go to Atlassian API Tokens, create a token, and note your Atlassian email address.
2. Install
pip install ccfm-convert
Note: The pip package is
ccfm-convert, but the CLI command isccfm.
3. Initialise your space
ccfm \
--domain your-domain.atlassian.net \
--email your.email@example.com \
--token YOUR_API_TOKEN \
--space YOUR_SPACE_KEY \
init
This is idempotent — safe to run multiple times. It creates the _ccfm management
infrastructure that stores deployment state and lock information.
4. Write a page
---
page_meta:
title: My First Page
labels:
- docs
deploy_config:
ci_banner: false
---
# My First Page
This is **bold** text, this is *italic*.
> [!info]
> This is an info panel.
::In Progress::blue:: ::Stable::green::
5. Preview and apply
ccfm plan
ccfm apply --auto-approve
For the full CLI reference, configuration options, and deployment patterns, see the documentation site.
Page Hierarchy
Directories map directly to Confluence pages. A file at docs/Team/Engineering/api.md creates:
Team
└── Engineering
└── api
To control a container page's title and content, add a .page_content.md file inside the directory.
Docker
docker pull ghcr.io/stevesimpson418/ccfm-convert:latest
docker run --rm \
-e CONFLUENCE_DOMAIN=company.atlassian.net \
-e CONFLUENCE_EMAIL=user@example.com \
-e CONFLUENCE_TOKEN=your-token \
-v $(pwd)/docs:/docs \
ghcr.io/stevesimpson418/ccfm-convert:latest \
apply --auto-approve
For GitHub Action usage and CI/CD pipeline examples, see Docker & CI/CD.
Development
Setup
python -m venv .env
source .env/bin/activate # Windows: .env\Scripts\activate
# Install the package and dev/test dependencies
pip install -e .
pip install -r requirements-test.txt
# Install pre-commit hooks
pre-commit install
Running tests
pytest # All unit tests with coverage report
pytest tests/test_converter.py # Single file
pytest -k "test_heading" # Single test by name
Coverage runs automatically via pyproject.toml. The target is 100% line coverage on src/.
Smoke tests
End-to-end tests that deploy real pages to a Confluence space:
cp .env.smoke.example .env.smoke
# Edit .env.smoke with your values, then:
source .env.smoke
pytest tests/smoke/ --no-cov -v
Code style
- Formatter: Black (line length 100)
- Linter: Ruff
- Python: 3.12
black src/ # Format
ruff check src/ # Lint
pre-commit run --all-files # All hooks
Contributing
- Fork the repository and create a feature branch
- Run
pre-commit installto set up hooks - Make your changes
- Run
pytest— all tests must pass, coverage must be maintained - Run
pre-commit run --all-files - Submit a pull request
Credits
Built on:
Metadata
Release files for ccfm-convert 2.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| ccfm_convert-2.3.0.tar.gz | 115.2 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ccfm_convert-2.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 170.5 kB
Release files / ccfm_convert-2.3.0.tar.gz
| Download URL | ccfm_convert-2.3.0.tar.gz |
|---|---|
| Size | 115.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6003469600a677a1db700a70e20025239b7676db7c04e6170b9ce20afc098ab8
|
|
BLAKE2b-256 checksum How to use checksums |
065919ec592153d4be9a55ef6ba3d564755a3f87abafbbe6628c37ab0ebdf349
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 13, 2026.
Transparency logRelease files / ccfm_convert-2.3.0-py3-none-any.whl
| Download URL | ccfm_convert-2.3.0-py3-none-any.whl |
|---|---|
| Size | 55.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
eae276624085336118c955605e6d1cbe3c81657b8c69be70639ea61ebcdea8e2
|
|
BLAKE2b-256 checksum How to use checksums |
1a1e80ee7aed09e1f06dceac9fca0031313a7a671f54e311ec0ef02f51176616
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 13, 2026.
Transparency logSecurity for ccfm-convert 2.3.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for ccfm_convert-2.3.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 13, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.