diff --git a/.agents/skills/changelog-fragment/SKILL.md b/.agents/skills/changelog-fragment/SKILL.md new file mode 100644 index 00000000..52ec2d58 --- /dev/null +++ b/.agents/skills/changelog-fragment/SKILL.md @@ -0,0 +1,40 @@ +--- +name: changelog-fragment +description: Draft the changelog fragment (changelog.d/..md) for the changes on the current branch. Use when a PR is ready and has no fragment yet, or when a reviewer asks for one. +--- + +# Changelog fragment + +Format, types and attribution rules are in `changelog.d/README.md`; read it first. + +## Steps + +1. Find the `apache/solr-orbit` remote with `git remote -v`; it is often `upstream`, not + `origin`. Fetch it. Without such a remote, use the PR's base from + `gh pr view --json baseRefName` or ask. +2. Read `git log /main..HEAD --oneline` and the diff of the files that change + behaviour. Skip tests and CI unless they are the whole change. +3. If the change is not user-visible (refactoring, tests, CI), say so and stop. +4. Pick the type. Anything that makes users adapt a workload, flag or config file is + `breaking`, however small. +5. PR number: `gh pr view --json number -q .number`. Without a PR, use `+..md` + and tell the author to rename it. +6. Write one or two sentences for a user, naming the command, flag or feature they would + recognise, in backticks. +7. Append the author: `(@login)` from `gh pr view --json author -q .author.login` unless the + author prefers a nick or full name. +8. Show the rendered line from `make changelog-draft`. + +## Examples + +`changelog.d/124.fixed.md` + +```markdown +`solr-orbit stop` works again; it failed with a missing `metrics_store_class` attribute. (@jdoe) +``` + +`changelog.d/115.changed.md` + +```markdown +The `optimize` operation follows Solr's merge policy by default instead of forcing a single segment. Set `max-segments` to `1` to restore the old behaviour. (@jdoe) +``` diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 1105b18a..d4b09378 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -14,6 +14,7 @@ on: - '.fossa.yml' - 'LICENSE' - 'NOTICE' + - 'changelog.d/**' # The docs site is validated by docs-lint.yml instead. - 'docs/**' diff --git a/AGENTS.md b/AGENTS.md index cb50df18..8fedd173 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -25,8 +25,14 @@ make it312 # Integration tests for Python 3.12 only make benchmark # Run performance benchmarks (pytest benchmarks/) make build # Build distribution wheel make clean # Remove build artifacts, caches, tox environments +make changelog-draft # Preview release notes from the fragments in changelog.d/ ``` +## Changelog + +User-visible changes need a fragment in `changelog.d/` (see its README); draft it with the +`changelog-fragment` skill in `.agents/skills/`. Never edit `CHANGELOG.md` directly. + ## Code Style - **Linter**: [ruff](https://docs.astral.sh/ruff/) (configured in `pyproject.toml` under `[tool.ruff]`) diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..ec952f99 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,16 @@ +# Changelog + +All notable changes to Apache Solr Orbit are listed here. The format follows +[Keep a Changelog](https://keepachangelog.com/en/1.1.0/). + + + + + +## Unreleased + +No release yet. The first release notes appear here when `make changelog` runs for the first +release; remove this section then. Preview the pending entries with `make changelog-draft`. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 66affbf5..c37adcb2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -42,6 +42,7 @@ By submitting a contribution, you agree to license it under the same license. We aim to review contributions promptly. To smooth the process: - Reference the related issue in your PR description. +- Add a changelog fragment under `changelog.d/` for user-visible changes (see its README). - Keep PRs focused; a narrow PR is easier to review than a large one. - Respond to review comments in a timely manner. - If you stop working on a PR, let us know so we can close or reassign it. diff --git a/DEVELOPER_GUIDE.md b/DEVELOPER_GUIDE.md index 7109a421..48e1c4e9 100644 --- a/DEVELOPER_GUIDE.md +++ b/DEVELOPER_GUIDE.md @@ -114,7 +114,22 @@ make it 1. **Run tests**: `make test` (and `make it` if applicable). 2. **Rebase** onto the latest `main` before opening a PR. 3. Open the PR, referencing the related issue (`Closes #123`). -4. Respond to review comments; squash commits if asked. +4. **Add a changelog fragment** for user-visible changes (see [Changelog](#changelog)). +5. Respond to review comments; squash commits if asked. + +## Changelog + +`CHANGELOG.md` is generated by [towncrier](https://towncrier.readthedocs.io/) from one fragment per +PR in [`changelog.d/`](./changelog.d/), so concurrent PRs never conflict. The fragment format and +types are described in [`changelog.d/README.md`](./changelog.d/README.md); AI coding agents draft +one with the `changelog-fragment` skill in [`.agents/skills/`](./.agents/skills/changelog-fragment/SKILL.md). + +```bash +make changelog-draft # preview the pending release notes +make changelog # at release, after bumping version.txt: fold fragments into CHANGELOG.md +``` + +Commit the generated `CHANGELOG.md` together with the deleted fragments. ## Developing Breaking Changes diff --git a/Makefile b/Makefile index 9aab2fd7..19bf99cd 100644 --- a/Makefile +++ b/Makefile @@ -87,3 +87,14 @@ release: release-checks clean it ./release.sh $(release_version) $(next_version) .PHONY: install clean python-caches-clean tox-env-clean test it it312 it313 benchmark coverage licenses release release-checks check-uv + +# Changelog fragments in changelog.d/ are folded into CHANGELOG.md by towncrier, see changelog.d/README.md. +VERSION := $(shell cat version.txt) + +# Preview the pending release notes without writing anything. +changelog-draft: develop + uv run towncrier build --draft --version $(VERSION) + +# Fold the pending fragments into CHANGELOG.md for version.txt and delete them. Run at release. +changelog: develop + uv run towncrier build --yes --version $(VERSION) diff --git a/changelog.d/100.fixed.md b/changelog.d/100.fixed.md new file mode 100644 index 00000000..b770da1d --- /dev/null +++ b/changelog.d/100.fixed.md @@ -0,0 +1 @@ +A wheel install of `solr-orbit` ships the cluster configs, Jinja templates and other resources it needs, so an installed package can run a benchmark. (@janhoy) diff --git a/changelog.d/102.fixed.md b/changelog.d/102.fixed.md new file mode 100644 index 00000000..96b9f7d3 --- /dev/null +++ b/changelog.d/102.fixed.md @@ -0,0 +1 @@ +`--test-iterations=1` runs the benchmark. It used to run nothing, print a success message and exit 0. (@janhoy) diff --git a/changelog.d/112.fixed.md b/changelog.d/112.fixed.md new file mode 100644 index 00000000..ace8d842 --- /dev/null +++ b/changelog.d/112.fixed.md @@ -0,0 +1 @@ +Collection creation works with both shapes of Solr's V2 create-collection API. Solr Orbit retries with the command envelope when Solr asks for it, so no version table is needed. (@janhoy) diff --git a/changelog.d/113.fixed.md b/changelog.d/113.fixed.md new file mode 100644 index 00000000..3e74b714 --- /dev/null +++ b/changelog.d/113.fixed.md @@ -0,0 +1 @@ +An interrupted Solr download no longer leaves a partial archive in the cache that later runs treat as valid. Archives are downloaded to a temporary file and published atomically. (@med9110) diff --git a/changelog.d/115.changed.md b/changelog.d/115.changed.md new file mode 100644 index 00000000..d5d74a6e --- /dev/null +++ b/changelog.d/115.changed.md @@ -0,0 +1 @@ +The `optimize` operation follows Solr's merge policy by default. `max-segments` is only sent to Solr when the workload sets it, instead of always forcing a merge to a single segment. (@janhoy) diff --git a/changelog.d/117.fixed.md b/changelog.d/117.fixed.md new file mode 100644 index 00000000..df203457 --- /dev/null +++ b/changelog.d/117.fixed.md @@ -0,0 +1 @@ +`--client-options=timeout:N` is passed to the data client. It was dropped, so every data operation ran with the 30 second library default, which is too short for `optimize` on a large index. (@janhoy) diff --git a/changelog.d/120.fixed.md b/changelog.d/120.fixed.md new file mode 100644 index 00000000..da6d3ae1 --- /dev/null +++ b/changelog.d/120.fixed.md @@ -0,0 +1 @@ +Docker Compose is found under either of its names, `docker compose` or `docker-compose`, and a clear error is raised when neither is installed. (@janhoy) diff --git a/changelog.d/124.fixed.md b/changelog.d/124.fixed.md new file mode 100644 index 00000000..6602cd3f --- /dev/null +++ b/changelog.d/124.fixed.md @@ -0,0 +1 @@ +`solr-orbit stop` works again. It failed with a missing `metrics_store_class` attribute. (@syahra712) diff --git a/changelog.d/125.fixed.md b/changelog.d/125.fixed.md new file mode 100644 index 00000000..3ec305dc --- /dev/null +++ b/changelog.d/125.fixed.md @@ -0,0 +1 @@ +`create-workload` pages through the collection with the data client's `search()` and `cursorMark`, so it picks up the client's host, auth, TLS and timeout. It previously failed before reading any documents. (@syahra712) diff --git a/changelog.d/126.changed.md b/changelog.d/126.changed.md new file mode 100644 index 00000000..e0fac310 --- /dev/null +++ b/changelog.d/126.changed.md @@ -0,0 +1 @@ +The Docker image is built on Python 3.13, the newest interpreter the project supports, instead of the unsupported 3.14. (@syahra712) diff --git a/changelog.d/133.docs.md b/changelog.d/133.docs.md new file mode 100644 index 00000000..ef6973aa --- /dev/null +++ b/changelog.d/133.docs.md @@ -0,0 +1 @@ +`THIRD_PARTY.md` lists the runtime dependencies with their licenses, authors and URLs, regenerated with `make licenses`. (@syahra712) diff --git a/changelog.d/135.fixed.md b/changelog.d/135.fixed.md new file mode 100644 index 00000000..192352e2 --- /dev/null +++ b/changelog.d/135.fixed.md @@ -0,0 +1 @@ +`--telemetry cluster-environment-info` records the cluster environment. The device was listed and documented but never created. (@syahra712) diff --git a/changelog.d/151.fixed.md b/changelog.d/151.fixed.md new file mode 100644 index 00000000..7a620a39 --- /dev/null +++ b/changelog.d/151.fixed.md @@ -0,0 +1 @@ +Bulk indexing reports the correct `weight` when a batch fails. Failed documents were subtracted twice, which could make the reported weight negative and skewed indexing throughput. (@syahra712) diff --git a/changelog.d/152.fixed.md b/changelog.d/152.fixed.md new file mode 100644 index 00000000..1524bfa4 --- /dev/null +++ b/changelog.d/152.fixed.md @@ -0,0 +1 @@ +`raw-request` operations that Solr answers with an HTTP error are reported as failed requests. They were counted as successful whatever the status, so the error rate stayed at 0. (@syahra712) diff --git a/changelog.d/154.added.md b/changelog.d/154.added.md new file mode 100644 index 00000000..1798a2ba --- /dev/null +++ b/changelog.d/154.added.md @@ -0,0 +1 @@ +Release notes are now assembled from per-PR fragments in `changelog.d/` with towncrier, each entry credited to its author. See the "Changelog" section of the Developer Guide. (@janhoy) diff --git a/changelog.d/18.changed.md b/changelog.d/18.changed.md new file mode 100644 index 00000000..85bbed4b --- /dev/null +++ b/changelog.d/18.changed.md @@ -0,0 +1 @@ +Python 3.12 or newer is required. Python 3.10 and 3.11 hang during corpus downloads on macOS 15 because of a CPython bug in `os.stat()`. (@janhoy) diff --git a/changelog.d/22.changed.md b/changelog.d/22.changed.md new file mode 100644 index 00000000..eae9e79f --- /dev/null +++ b/changelog.d/22.changed.md @@ -0,0 +1 @@ +Packaging moved from `setup.py` to `pyproject.toml`, and dependencies are managed with [uv](https://docs.astral.sh/uv/); `make develop` creates the environment and `make install` installs the wheel as a uv tool. (@janhoy, @epugh) diff --git a/changelog.d/23.docs.md b/changelog.d/23.docs.md new file mode 100644 index 00000000..2ee43887 --- /dev/null +++ b/changelog.d/23.docs.md @@ -0,0 +1 @@ +A documentation site at https://apache.github.io/solr-orbit/ with a quickstart, user guide, cluster-config catalogue and converter reference, built with a Solr-branded Jekyll theme. (@janhoy) diff --git a/changelog.d/25.docs.md b/changelog.d/25.docs.md new file mode 100644 index 00000000..2ee43887 --- /dev/null +++ b/changelog.d/25.docs.md @@ -0,0 +1 @@ +A documentation site at https://apache.github.io/solr-orbit/ with a quickstart, user guide, cluster-config catalogue and converter reference, built with a Solr-branded Jekyll theme. (@janhoy) diff --git a/changelog.d/26.removed.md b/changelog.d/26.removed.md new file mode 100644 index 00000000..99c7b66c --- /dev/null +++ b/changelog.d/26.removed.md @@ -0,0 +1 @@ +The OpenSearch-specific `cloud_provider` module for Amazon Elasticsearch Service and Amazon OpenSearch Serverless is removed. Streaming corpus data from S3 remains available. (@janhoy) diff --git a/changelog.d/3.added.md b/changelog.d/3.added.md new file mode 100644 index 00000000..f9aca6e8 --- /dev/null +++ b/changelog.d/3.added.md @@ -0,0 +1 @@ +Initial port of [OpenSearch Benchmark](https://github.com/opensearch-project/opensearch-benchmark) to Apache Solr. Solr Orbit provisions SolrCloud clusters from a distribution, from sources or in Docker, runs workloads against Solr through the Collections API, `/update` and `/select`, collects JVM, node, collection, query, indexing and cache telemetry, and keeps metrics on the local filesystem. The `convert-workload` command translates an OpenSearch Benchmark workload, including its query DSL and index mappings, to the Solr format. (@janhoy) diff --git a/changelog.d/39.fixed.md b/changelog.d/39.fixed.md new file mode 100644 index 00000000..02b5b4b3 --- /dev/null +++ b/changelog.d/39.fixed.md @@ -0,0 +1 @@ +Operation-level parameters such as `num-shards` take precedence over the built-in collection defaults, so values from `--workload-params` and operation templates are honoured. (@epugh) diff --git a/changelog.d/4.changed.md b/changelog.d/4.changed.md new file mode 100644 index 00000000..00e045a2 --- /dev/null +++ b/changelog.d/4.changed.md @@ -0,0 +1 @@ +The project is named Apache Solr Orbit. The CLI entry points are `solr-orbit` and `solr-orbitd`, the PyPI package is `solr-orbit`, the Python package is `solrorbit`, the user configuration directory is `~/.solr-orbit`, and the default workload repository points at the Solr Orbit workloads. (@janhoy) diff --git a/changelog.d/40.docs.md b/changelog.d/40.docs.md new file mode 100644 index 00000000..32ba8c45 --- /dev/null +++ b/changelog.d/40.docs.md @@ -0,0 +1 @@ +The documentation describes only the workloads and features Solr Orbit has, explains `--test-procedures`, and site search works. (@janhoy) diff --git a/changelog.d/41.docs.md b/changelog.d/41.docs.md new file mode 100644 index 00000000..32ba8c45 --- /dev/null +++ b/changelog.d/41.docs.md @@ -0,0 +1 @@ +The documentation describes only the workloads and features Solr Orbit has, explains `--test-procedures`, and site search works. (@janhoy) diff --git a/changelog.d/42.changed.md b/changelog.d/42.changed.md new file mode 100644 index 00000000..00e045a2 --- /dev/null +++ b/changelog.d/42.changed.md @@ -0,0 +1 @@ +The project is named Apache Solr Orbit. The CLI entry points are `solr-orbit` and `solr-orbitd`, the PyPI package is `solr-orbit`, the Python package is `solrorbit`, the user configuration directory is `~/.solr-orbit`, and the default workload repository points at the Solr Orbit workloads. (@janhoy) diff --git a/changelog.d/43.added.md b/changelog.d/43.added.md new file mode 100644 index 00000000..b3a2fce4 --- /dev/null +++ b/changelog.d/43.added.md @@ -0,0 +1 @@ +Solr Orbit checks at startup that the target cluster runs in SolrCloud mode and fails with a clear error otherwise, because collection management needs the Collections API. Pass `--allow-unsupported-user-managed` together with a suitable `--include-tasks` to run a benchmark-only pipeline against a standalone Solr anyway, with caveats. (@janhoy, @epugh) diff --git a/changelog.d/49.added.md b/changelog.d/49.added.md new file mode 100644 index 00000000..b3a2fce4 --- /dev/null +++ b/changelog.d/49.added.md @@ -0,0 +1 @@ +Solr Orbit checks at startup that the target cluster runs in SolrCloud mode and fails with a clear error otherwise, because collection management needs the Collections API. Pass `--allow-unsupported-user-managed` together with a suitable `--include-tasks` to run a benchmark-only pipeline against a standalone Solr anyway, with caveats. (@janhoy, @epugh) diff --git a/changelog.d/50.changed.md b/changelog.d/50.changed.md new file mode 100644 index 00000000..eae9e79f --- /dev/null +++ b/changelog.d/50.changed.md @@ -0,0 +1 @@ +Packaging moved from `setup.py` to `pyproject.toml`, and dependencies are managed with [uv](https://docs.astral.sh/uv/); `make develop` creates the environment and `make install` installs the wheel as a uv tool. (@janhoy, @epugh) diff --git a/changelog.d/52.added.md b/changelog.d/52.added.md new file mode 100644 index 00000000..b3a2fce4 --- /dev/null +++ b/changelog.d/52.added.md @@ -0,0 +1 @@ +Solr Orbit checks at startup that the target cluster runs in SolrCloud mode and fails with a clear error otherwise, because collection management needs the Collections API. Pass `--allow-unsupported-user-managed` together with a suitable `--include-tasks` to run a benchmark-only pipeline against a standalone Solr anyway, with caveats. (@janhoy, @epugh) diff --git a/changelog.d/58.fixed.md b/changelog.d/58.fixed.md new file mode 100644 index 00000000..12f84bb6 --- /dev/null +++ b/changelog.d/58.fixed.md @@ -0,0 +1 @@ +`solr-orbit aggregate` works again. It read a test run attribute that no longer exists, and it crashed when an operation reported null metrics. (@serhiy-bzhezytskyy) diff --git a/changelog.d/59.fixed.md b/changelog.d/59.fixed.md new file mode 100644 index 00000000..12f84bb6 --- /dev/null +++ b/changelog.d/59.fixed.md @@ -0,0 +1 @@ +`solr-orbit aggregate` works again. It read a test run attribute that no longer exists, and it crashed when an operation reported null metrics. (@serhiy-bzhezytskyy) diff --git a/changelog.d/60.added.md b/changelog.d/60.added.md new file mode 100644 index 00000000..d7fa44fc --- /dev/null +++ b/changelog.d/60.added.md @@ -0,0 +1 @@ +`solr-orbit aggregate` accepts `--workload-path` and `--workload-revision`, like `run`, so a workload developed locally can be aggregated after it was benchmarked. (@serhiy-bzhezytskyy) diff --git a/changelog.d/62.docs.md b/changelog.d/62.docs.md new file mode 100644 index 00000000..32ba8c45 --- /dev/null +++ b/changelog.d/62.docs.md @@ -0,0 +1 @@ +The documentation describes only the workloads and features Solr Orbit has, explains `--test-procedures`, and site search works. (@janhoy) diff --git a/changelog.d/69.fixed.md b/changelog.d/69.fixed.md new file mode 100644 index 00000000..f865a02f --- /dev/null +++ b/changelog.d/69.fixed.md @@ -0,0 +1 @@ +`convert-workload` translates OpenSearch workloads more faithfully. Exclusive range bounds stay exclusive, date bounds with a space separator and whole-day `lte` bounds convert correctly, a `date_histogram` `fixed_interval` maps to the equivalent Solr gap instead of defaulting to `+1MONTH`, and the index-stats merge-wait idiom becomes Solr Orbit's `wait-for-merges` operation. (@serhiy-bzhezytskyy) diff --git a/changelog.d/72.fixed.md b/changelog.d/72.fixed.md new file mode 100644 index 00000000..6260d66b --- /dev/null +++ b/changelog.d/72.fixed.md @@ -0,0 +1 @@ +Benchmark-only runs that do not pass `--distribution-version` read the actual Solr version from the cluster instead of assuming 9.10.1, so the matching workload branch is selected. (@serhiy-bzhezytskyy) diff --git a/changelog.d/74.fixed.md b/changelog.d/74.fixed.md new file mode 100644 index 00000000..f865a02f --- /dev/null +++ b/changelog.d/74.fixed.md @@ -0,0 +1 @@ +`convert-workload` translates OpenSearch workloads more faithfully. Exclusive range bounds stay exclusive, date bounds with a space separator and whole-day `lte` bounds convert correctly, a `date_histogram` `fixed_interval` maps to the equivalent Solr gap instead of defaulting to `+1MONTH`, and the index-stats merge-wait idiom becomes Solr Orbit's `wait-for-merges` operation. (@serhiy-bzhezytskyy) diff --git a/changelog.d/76.fixed.md b/changelog.d/76.fixed.md new file mode 100644 index 00000000..4207245f --- /dev/null +++ b/changelog.d/76.fixed.md @@ -0,0 +1 @@ +`--randomization-enabled` randomizes range bounds in Solr's string queries. It previously had no effect on Solr workloads because only the OpenSearch query DSL was inspected. (@serhiy-bzhezytskyy) diff --git a/changelog.d/77.fixed.md b/changelog.d/77.fixed.md new file mode 100644 index 00000000..f865a02f --- /dev/null +++ b/changelog.d/77.fixed.md @@ -0,0 +1 @@ +`convert-workload` translates OpenSearch workloads more faithfully. Exclusive range bounds stay exclusive, date bounds with a space separator and whole-day `lte` bounds convert correctly, a `date_histogram` `fixed_interval` maps to the equivalent Solr gap instead of defaulting to `+1MONTH`, and the index-stats merge-wait idiom becomes Solr Orbit's `wait-for-merges` operation. (@serhiy-bzhezytskyy) diff --git a/changelog.d/80.fixed.md b/changelog.d/80.fixed.md new file mode 100644 index 00000000..f865a02f --- /dev/null +++ b/changelog.d/80.fixed.md @@ -0,0 +1 @@ +`convert-workload` translates OpenSearch workloads more faithfully. Exclusive range bounds stay exclusive, date bounds with a space separator and whole-day `lte` bounds convert correctly, a `date_histogram` `fixed_interval` maps to the equivalent Solr gap instead of defaulting to `+1MONTH`, and the index-stats merge-wait idiom becomes Solr Orbit's `wait-for-merges` operation. (@serhiy-bzhezytskyy) diff --git a/changelog.d/README.md b/changelog.d/README.md new file mode 100644 index 00000000..858387ca --- /dev/null +++ b/changelog.d/README.md @@ -0,0 +1,30 @@ +# Changelog fragments + +One Markdown file per PR, named `..md`. `make changelog` folds them into +[CHANGELOG.md](../CHANGELOG.md) at release time and deletes them. + +Write one or two sentences for a user of Solr Orbit, no leading bullet or PR number, ending with +the author in parentheses. `@jdoe` is a GitHub handle, `jdoe` a nick or Apache id, `John Doe` +a full name. Several authors: `(@jdoe, @asmith)`. + +```markdown +`solr-orbit stop` no longer fails with a missing `metrics_store_class` attribute. (@jdoe) +``` + +| type | use for | +|--------------|--------------------------------------------------------| +| `breaking` | changes that require users to adapt workloads or flags | +| `added` | new features, commands, flags, telemetry devices | +| `changed` | changes to existing behaviour that are not breaking | +| `deprecated` | features that still work but will be removed | +| `removed` | features that are gone | +| `fixed` | bug fixes | +| `security` | security fixes | +| `docs` | documentation changes worth announcing | + +Refactoring, test-only and CI changes need no fragment. A fragment without a PR is named +`+..md` and renders without a link. + +```bash +make changelog-draft # preview the pending release notes +``` diff --git a/pyproject.toml b/pyproject.toml index ea18ad24..73736aeb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -150,6 +150,7 @@ develop = [ "wheel>=0.38.4", "github3.py==4.0.1", "ruff==0.17.3", + "towncrier>=24.8", ] # --------------------------------------------------------------------------- @@ -177,6 +178,63 @@ ignore = [ # workload/__init__.py re-exports the complete workload API via a star import "solrorbit/workload/__init__.py" = ["F403"] +# --------------------------------------------------------------------------- +# towncrier – changelog fragments +# --------------------------------------------------------------------------- +# One fragment per PR in changelog.d/, folded into CHANGELOG.md by `make changelog`. +# See changelog.d/README.md. + +[tool.towncrier] +name = "Apache Solr Orbit" +directory = "changelog.d" +filename = "CHANGELOG.md" +start_string = "\n" +title_format = "## [{version}] - {project_date}" +issue_format = "[#{issue}](https://github.com/apache/solr-orbit/pull/{issue})" +underlines = ["", "", ""] +# Fragments that are not tied to a PR start with "+" and render without a link. +orphan_prefix = "+" + +[[tool.towncrier.type]] +directory = "breaking" +name = "Breaking Changes" +showcontent = true + +[[tool.towncrier.type]] +directory = "added" +name = "Added" +showcontent = true + +[[tool.towncrier.type]] +directory = "changed" +name = "Changed" +showcontent = true + +[[tool.towncrier.type]] +directory = "deprecated" +name = "Deprecated" +showcontent = true + +[[tool.towncrier.type]] +directory = "removed" +name = "Removed" +showcontent = true + +[[tool.towncrier.type]] +directory = "fixed" +name = "Fixed" +showcontent = true + +[[tool.towncrier.type]] +directory = "security" +name = "Security" +showcontent = true + +[[tool.towncrier.type]] +directory = "docs" +name = "Documentation" +showcontent = true + # --------------------------------------------------------------------------- # Setuptools configuration # --------------------------------------------------------------------------- diff --git a/uv.lock b/uv.lock index 4a96dfe1..b4a1ac93 100644 --- a/uv.lock +++ b/uv.lock @@ -1441,6 +1441,7 @@ develop = [ { name = "pytest-asyncio" }, { name = "pytest-benchmark" }, { name = "ruff" }, + { name = "towncrier" }, { name = "tox" }, { name = "tox-uv" }, { name = "twine" }, @@ -1490,6 +1491,7 @@ requires-dist = [ { name = "ruff", marker = "extra == 'develop'", specifier = "==0.17.3" }, { name = "tabulate", specifier = ">=0.9.0" }, { name = "thespian", specifier = ">=3.10.1,<4.0.2" }, + { name = "towncrier", marker = "extra == 'develop'", specifier = ">=24.8" }, { name = "tox", marker = "extra == 'develop'", specifier = ">=4.0" }, { name = "tox-uv", marker = "extra == 'develop'", specifier = ">=1.11" }, { name = "tqdm" }, @@ -1571,6 +1573,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/39/70/f1024364bf78fa921c63ef2883d36a3b3b705750c98ae174593afaab7a65/tornado-6.5.9-cp39-abi3-win_arm64.whl", hash = "sha256:b5f4d92798337260c6d9f9f0e400c7539dd5e55cf93479a3f8508c9aa09c2b3b", size = 466211, upload-time = "2026-09-14T18:08:35.18Z" }, ] +[[package]] +name = "towncrier" +version = "26.9.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "jinja2" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/92/d4/e85ce614bf45b1a7fe13b82cc687819c2eaac5a1dd94b84834322095fd98/towncrier-26.9.0.tar.gz", hash = "sha256:ace9031631c718cc0709107b8755e6e31350eb8acdc877af43df3177addb9a55", size = 79338, upload-time = "2026-09-04T12:57:25.341Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/88/f9340b545dafa64de053798e760515a2736fbb60092cf9aa6b146ccf3ede/towncrier-26.9.0-py3-none-any.whl", hash = "sha256:ae4d223e6aadaff98d29b7f09e58d9c9ccf4cd3b455a2d2e0486d432cd8bf660", size = 67030, upload-time = "2026-09-04T12:57:23.986Z" }, +] + [[package]] name = "tox" version = "4.67.4"