Changelog¶
All notable changes to CCFM are documented here. Format follows Keep a Changelog. Versioning follows Semantic Versioning.
2.1.1 - 2026-03-27¶
Fixed¶
- Deprecated
parentfrontmatter option now emits a warning and is ignored; previously it silently attempted a parent override lookup (#63) deploy_treenow preserves caller-provided dependency ordering instead of re-sorting alphabetically, fixing out-of-order deploys when pages have internal link dependencies (#64)
2.1.0 - 2026-03-27¶
Added¶
ci_banner_textglobal config option inccfm.yaml— set the CI banner message without needing--git-repo-urlon every invocation (#57)
Fixed¶
- Smart links to container pages (directories with
.page_content.md) now resolve correctly for dependency-ordered deployment (#60) - Planner detects content changes in
.page_content.mdfiles and generates change actions instead of silently skipping them (#58) ci_banner_textfrom global config now forwarded to standalone.page_content.mddeploys viaensure_page_hierarchy
2.0.0 - 2026-03-25¶
Breaking Changes¶
- Removed
--file,--directory, and--docs-rootflags fromplanandapply— all deployments now target the fulldocs_rootdirectory, set exclusively viaccfm.yaml. This ensures consistent page hierarchy, reliable orphan detection, and complete dependency resolution. - Removed
dumpsubcommand — replaced byplan --debug-file <path>which prints ADF JSON to stdout (no file I/O, pipeable). - Removed
--auto-deploy-depsflag — no longer needed since all deployments cover the full docs_root, making dependency resolution automatic. - Removed
directoryandfileinputs from the GitHub Action (action.yml). All deployments now usedocs_rootfromccfm.yaml.
Added¶
--debug-fileflag onplansubcommand for ADF JSON inspection of a single file (prints to stdout, no API calls or credentials required).
1.2.0 - 2026-03-24¶
Added¶
- Dependency-ordered deployment: directory deploys now topologically sort pages by internal page links so linked pages exist before pages that reference them (#42)
--auto-deploy-depsCLI flag forplanandapply: automatically discover and deploy transitive dependency pages when using--filemode- ADF spec audit:
inlineExtensionnodes (@anchor,@jira,@macro(params)),rule(horizontal rule), heading anchor IDs,tippanel alias, and external URL smart links via[text](<https://...>)syntax (#40)
Fixed¶
TestConfigFileLoadingtests no longer fail whenCONFLUENCE_*env vars are set in the shellTestTokenHandling.test_missing_token_exits_with_errornow correctly exercises the token validation code path- CLI help text for
--domainand--emailnow shows env var fallback hints (#37)
1.1.3 - 2026-03-20¶
Fixed¶
- CLI
--domainand--emailnow fall back toCONFLUENCE_DOMAINandCONFLUENCE_EMAILenv vars, matching existingCONFLUENCE_TOKENbehaviour (#36) - Removed stale
spacefrom frontmatter references in CCFM.md and complete_example.md —spaceis a config-level field, not per-page frontmatter - Example code in complete_example.md updated to use actual
ccfmCLI commands and real environment variables - Manual testing runbook page counts corrected (8 md files, 16 tracked pages)
1.1.2 - 2026-03-19¶
Removed¶
:::expandfenced directive syntax — use> [!expand Title]blockquote syntax instead (#16)
1.1.1 - 2026-03-19¶
Fixes listed in v1.1.0 were merged after that tag was cut; v1.1.1 is the first published version that actually includes them.
Fixed¶
- Page lookup in
deploy_pagenow scoped to parent, preventing false matches across sibling subtrees (#34) - Config loader raises
ConfigValidationErrorfor non-dict YAML configs (#31) - CI smoke-test workflow uses changes detection job instead of
pathsfilters to avoid skipped runs on non-source changes
Changed¶
- Documentation updated for
docs_rootfallback,ccfmcommand name, and--fileorphan-skip behaviour
1.1.0 - 2026-03-19¶
Added¶
docs_rootconfig fallback for--directory— when no--directoryflag is provided,plan,apply, anddumpnow usedocs_rootfromccfm.yaml(#23)- Bandit SAST security scan GitHub Actions workflow with SARIF upload
Fixed¶
- Orphan detection no longer runs when targeting a single file with
--file(#14) - Page lookup in
ensure_page_hierarchynow scoped to parent page, preventing false matches across sibling subtrees (#15) - Domain with
https://prefix no longer causes connection errors — protocol prefix is stripped automatically (#20) :::expandfenced directive syntax now supported alongside> [!expand]blockquote syntax (#21)- Config loader validates top-level keys and rejects unrecognised config format (#22)
Changed¶
- Documentation URLs updated to custom domain ccfm.io
1.0.0 - 2026-03-13¶
Added¶
- MkDocs Material documentation site deployed to GitHub Pages
- CCFM logo in site navigation and favicon
- GitHub Actions workflow for automatic docs deployment on push to
main
Fixed¶
- GitHub Action argument ordering for v0.4.0 subcommand CLI (#12)
Changed¶
- README slimmed to quickstart; full documentation now lives at ccfm.io
- First stable release
0.5.0 - 2026-03-11¶
Added¶
deploy_page: falsein frontmatter now generates a destroy action for previously deployed pages, removing them from Confluence on nextapply(#8)- Container pages are also destroyed when all their children have
deploy_page: false - Manual test steps (5.7–5.12) for
deploy_page: falsedestroy workflow
0.4.0 - 2026-03-11¶
Added¶
ccfm dumptop-level subcommand replacing the oldapply --dumpflag- Converts markdown to ADF JSON locally without API calls
- Supports
--file,--directory, and--output-diroptions - Default output goes to
.ccfm/dumps/<timestamp>_<hash>/(no more scattered.ccfm-dump-*directories at project root) ccfm plantop-level subcommand (split out fromapply)- Supports
--file,--directory,--plan-exit-code, and--force - File and directory existence validation with clear error messages for
plan,apply, anddumpsubcommands - Interactive manual test script (
tests/smoke/manual_test.sh) for walking through all CLI test phases MANUAL_TESTING.mdrunbook documenting 8 phases of manual smoke tests- CLI help smoke tests validating all subcommand help output
Changed¶
planandapplyrefactored into separate subcommands sharing a common planner module (previouslyapply --planwas the only way to preview changes)- Dump output directory default changed from
.ccfm-dump-<hash>at project root to.ccfm/dumps/<timestamp>_<hash>/for cleaner workspace organisation
0.3.0 - 2026-03-10¶
Added¶
- Remote state backend: state stored as a versioned JSON attachment on the CCFM
management page in Confluence, replacing the local
.ccfm-state.jsonfile - Distributed locking:
ccfm lock acquire/status/releaseand automatic lock acquire/release around all state-writing operations (deploy,state rm,state push) to prevent concurrent torn-state scenarios ccfm init: idempotent bootstrap command that creates the_ccfmcontainer page andCCFM State Managementchild page in a Confluence spaceccfm state pull: print remote state JSON to stdout (pipe-friendly)ccfm state push <file>: overwrite remote state from a local JSON file (validates schema andpage_idformat before acquiring lock)ccfm state show <path>: display the state entry for a specific tracked path- Hierarchy container pages tracked in state so they are not falsely flagged as orphans on subsequent deploys
- HTTP retry adapter on all API calls (GET/PUT/DELETE only — POST excluded to prevent duplicate page creation on transient 5xx errors)
- Symlink escape guard in
ensure_page_hierarchyrejects paths that resolve outside the docs root - README Initial Setup section and full CLI reference for all subcommands
Changed¶
all_pagesandraw_statenow return deep copies, preventing callers from accidentally mutating internal state through the returned dicts- Orphan archive loop batches the single
state.save()call after all removals instead of saving once per deleted page - Smoke test teardown resets the state attachment to empty rather than deleting management infrastructure, making test runs idempotent
0.2.1 - 2026-03-06¶
Re-release of 0.2.0 — PyPI rejected the re-uploaded artifacts after a tag fix; no code changes.
0.2.0 - 2026-03-05 [YANKED]¶
Changed¶
--plannow exits 0 by default, even when changes are pending (CI-friendly)- New
--plan-exit-codeflag opts in to Terraform-style exit codes (0 = no changes, 2 = changes pending) for CI gating workflows
0.1.2 - 2026-03-05¶
Fixed¶
- Docker image now works correctly with GitLab CI and other CI runners that
inject shell scripts, and tolerates
docker run ... image ccfm --flags(previously doubled theccfmcommand)
0.1.1 - 2026-03-05¶
Fixed¶
--changed-onlywith zero changes no longer traverses the full directory tree or runs orphan archiving — it exits immediately withNo changes to deploy.(#3)--archive-orphanscombined with--changed-onlyno longer archives pages that were simply unchanged on disk; orphan detection now uses the full set of current files rather than the changed-files-only subset (#3)- Broken GHCR badge URL in README replaced with static shields.io badge
0.1.0 - 2026-03-05¶
Added¶
- Markdown to Atlassian Document Format (ADF) conversion engine
- CCFM syntax extensions: status badges, panels, expand blocks, date tokens, smart Confluence page links, underline/superscript/subscript, emoji, image width control
- Confluence Cloud REST API deployment (single file and directory tree)
- Automatic Confluence page hierarchy from directory structure
.page_content.mdfor controlling container page titles and content- Attachment upload with Confluence Media Services integration
- CI banner injection with source file links (
--git-repo-url) --dumpmode: write ADF JSON locally without deploying- State management (
.ccfm-state.json) with SHA-256 content hashing --planmode: Terraform-style diff; exits 2 (changes pending) or 0 (up to date)--changed-only: skip files with unchanged content--archive-orphans: delete Confluence pages for removed markdown filesccfm.yamlproject config file with${ENV_VAR}interpolation- 100% unit test coverage; end-to-end smoke tests against real Confluence