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": {