From 67443e0132082950bf56661e102d0f5703a0bdf6 Mon Sep 17 00:00:00 2001 From: Logan Lindquist Land Date: Sun, 26 Jul 2026 06:44:52 -0500 Subject: [PATCH] docs: add changelog generation via git-cliff Add CHANGELOG.md with a 0.1.0 entry covering the package scaffold, the deterministic Pandoc conversion core, the three transports (local file, SharePoint, Google Drive), and docx-to-markdown reverse conversion. Entries are generated with git-cliff from cliff.toml, exposed as `changelog` (full regeneration), `changelog:preview` (show unreleased without writing), and `changelog:release` (prepend unreleased, leaving published entries intact) package scripts. cliff.toml filters merge commits out of the changelog, and includes a commit preprocessor that normalizes the squash-merge subject of PR #16 back to a conventional `feat:` prefix -- GitHub uses the PR title as the squash commit subject, and #16's title lacked the prefix, so without this preprocessor that work is silently dropped from generated output. Dependency and API-shape notes that no commit subject can convey -- `fflate` now being a runtime dependency, `google-auth-library` as an optional peer, and `PandocErrorCode`/`TransportErrorCode` being open unions -- are hand-added to the 0.1.0 release entry. That's why `changelog:release` (prepend) is preferred over a full regeneration once a version has shipped: regenerating from history would discard those hand-written notes. Closes #19 --- CHANGELOG.md | 47 +++++++++++++++++++++++++++++++++ README.md | 23 ++++++++++++++++ cliff.toml | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 3 +++ 4 files changed, 147 insertions(+) create mode 100644 CHANGELOG.md create mode 100644 cliff.toml diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..917b334 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,47 @@ +# Changelog + +All notable changes to this project are documented in this file. + +Entries are generated from [Conventional Commits](https://www.conventionalcommits.org/) +by [git-cliff](https://git-cliff.org/). Changes that a commit subject cannot +convey — dependency moves, notes about the shape of the public API — are added +to the release entry by hand. This project follows +[Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [0.1.0] - 2026-07-26 + +### Features + +- Add deterministic Pandoc conversion +- Add local file transport and CI +- Add SharePoint transport +- Add GoogleDriveTransport for uploading docx as Google Docs +- Add docx-to-markdown reverse conversion (Tier-2) ([#16](https://github.com/agentic-tooling/polydoc-core/pull/16)) + +### Miscellaneous + +- Scaffold TypeScript library package + +### Dependencies + +- `fflate` is a runtime dependency (previously a dev dependency). DOCX archive + inspection runs at conversion time, so consumers now install it. +- `google-auth-library` is an **optional** peer dependency (`^10`). It is only + needed when passing an `auth` client to `GoogleDriveTransport`; the package + imports it for types alone and never at runtime. +- `@googleapis/drive` is a runtime dependency, loaded lazily on the first Drive + upload so consumers who never publish to Drive do not pay for the SDK. +- `@azure/msal-node` is a runtime dependency, used for SharePoint client-secret + auth. + +### Notes + +- A Pandoc 3.x binary must be on `PATH`. It is not bundled. `doctor()` probes + for it and reports actionable failures. +- `PandocErrorCode` and `TransportErrorCode` are open unions that grow as + features land. Narrowing on them with an exhaustive `switch` and a `never` + assertion may need updating between releases. +- Reverse conversion is lossy and Word-only by design; Google Docs is + publish-only. An empty `report.unmappable` is not proof of a lossless + round trip — see the reverse-conversion section of the README. + diff --git a/README.md b/README.md index f62bd61..e33b515 100644 --- a/README.md +++ b/README.md @@ -593,6 +593,29 @@ Build output is emitted to `dist/` with JavaScript, source maps, TypeScript declarations, and declaration maps. Published package contents are constrained by the `files` allowlist in `package.json`. +## Changelog + +Release history is in [CHANGELOG.md](CHANGELOG.md). + +Commits follow [Conventional Commits](https://www.conventionalcommits.org/) +(`feat:`, `fix:`, `docs:`, `refactor:`, `perf:`, `test:`, `chore:`, `ci:`, with +`!` or a `BREAKING CHANGE:` footer for breaking changes), and entries are +generated with [git-cliff](https://git-cliff.org/) from `cliff.toml`: + +```sh +pnpm changelog:preview # show unreleased entries without writing +pnpm changelog:release # prepend unreleased entries, leaving published ones intact +pnpm changelog # regenerate the whole file from history +``` + +Prefer `changelog:release` once a version is published. Dependency moves and +API-shape notes are added to a release entry by hand and a full regeneration +discards them. + +When squash-merging, keep the conventional prefix in the pull request title — +GitHub uses that title as the commit subject, and a subject without a prefix is +filtered out of the changelog. + ## License MIT (c) 2026 Logan Lindquist Land diff --git a/cliff.toml b/cliff.toml new file mode 100644 index 0000000..018e240 --- /dev/null +++ b/cliff.toml @@ -0,0 +1,74 @@ +# Changelog generation. See https://git-cliff.org +# +# Regenerating: `pnpm changelog` rewrites the file from git history. Anything +# that cannot be derived from a commit subject — dependency moves, API-shape +# notes — lives in the release entry and would be lost. Once 0.1.0 is tagged, +# prefer `pnpm changelog:release` (`--unreleased --prepend`), which adds the new +# entry and leaves published ones untouched. + +[changelog] +header = """ +# Changelog + +All notable changes to this project are documented in this file. + +Entries are generated from [Conventional Commits](https://www.conventionalcommits.org/) +by [git-cliff](https://git-cliff.org/). Changes that a commit subject cannot +convey — dependency moves, notes about the shape of the public API — are added +to the release entry by hand. This project follows +[Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +""" +body = """ +{% if version %}\ + ## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }} +{% else %}\ + ## [Unreleased] +{% endif %}\ +{% for group, commits in commits | group_by(attribute="group") %} + ### {{ group | striptags | trim | upper_first }} + {% for commit in commits %} + - {% if commit.scope %}**{{ commit.scope }}:** {% endif %}\ + {{ commit.message | upper_first }}{% if commit.remote.pr_number %} \ + ([#{{ commit.remote.pr_number }}](https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }}/pull/{{ commit.remote.pr_number }})){% endif %}\ + {% endfor %} +{% endfor %} +""" +footer = "" +trim = true + +[git] +conventional_commits = true +filter_unconventional = true +split_commits = false + +# GitHub's squash-merge takes the PR title, which drops the conventional prefix +# when the title lacks one. Normalizing here keeps the commit in the changelog +# instead of silently filtering it out as unconventional. +commit_preprocessors = [ + { pattern = "^Add docx-to-markdown reverse conversion \\(Tier-2\\)", replace = "feat: add docx-to-markdown reverse conversion (Tier-2)" }, + # Squash subjects carry a trailing "(#N)"; the body template already renders + # the PR link, so strip it to avoid printing the number twice. + { pattern = "(?m) \\(#[0-9]+\\)$", replace = "" }, +] + +commit_parsers = [ + { message = "^Merge (pull request|branch|remote-tracking)", skip = true }, + { message = "^feat", group = "Features" }, + { message = "^fix", group = "Bug Fixes" }, + { message = "^doc", group = "Documentation" }, + { message = "^perf", group = "Performance" }, + { message = "^refactor", group = "Refactoring" }, + { message = "^style", group = "Styling" }, + { message = "^test", group = "Testing" }, + { message = "^chore\\(release\\)", skip = true }, + { message = "^chore\\(deps\\)", skip = true }, + { message = "^chore|^ci", group = "Miscellaneous" }, + { body = ".*security", group = "Security" }, +] + +protect_breaking_commits = false +filter_commits = false +tag_pattern = "v[0-9].*" +topo_order = false +sort_commits = "oldest" diff --git a/package.json b/package.json index 15fdc1e..9959f91 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,9 @@ "format": "biome format --write .", "format:check": "biome format .", "check": "biome check . && tsc -p tsconfig.json --noEmit && vitest run && tsc -p tsconfig.build.json", + "changelog": "git cliff -o CHANGELOG.md", + "changelog:preview": "git cliff --unreleased", + "changelog:release": "git cliff --unreleased --prepend CHANGELOG.md", "prepack": "pnpm build" }, "devDependencies": {