Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions .agents/skills/changelog-fragment/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
name: changelog-fragment
description: Draft the changelog fragment (changelog.d/<PR>.<type>.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 <remote>/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 `+<slug>.<type>.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)
```
1 change: 1 addition & 0 deletions .github/workflows/unit-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ on:
- '.fossa.yml'
- 'LICENSE'
- 'NOTICE'
- 'changelog.d/**'
# The docs site is validated by docs-lint.yml instead.
- 'docs/**'

Expand Down
6 changes: 6 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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]`)
Expand Down
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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/).

<!--
Generated by `make changelog` from the fragments in changelog.d/, see changelog.d/README.md.
Do not edit by hand. AI agents: draft a fragment with the changelog-fragment skill in .agents/skills/.
-->

<!-- towncrier release notes start -->

## 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`.
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
17 changes: 16 additions & 1 deletion DEVELOPER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
11 changes: 11 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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)
1 change: 1 addition & 0 deletions changelog.d/100.fixed.md
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions changelog.d/102.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
`--test-iterations=1` runs the benchmark. It used to run nothing, print a success message and exit 0. (@janhoy)
1 change: 1 addition & 0 deletions changelog.d/112.fixed.md
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions changelog.d/113.fixed.md
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions changelog.d/115.changed.md
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions changelog.d/117.fixed.md
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions changelog.d/120.fixed.md
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions changelog.d/124.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
`solr-orbit stop` works again. It failed with a missing `metrics_store_class` attribute. (@syahra712)
1 change: 1 addition & 0 deletions changelog.d/125.fixed.md
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions changelog.d/126.changed.md
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions changelog.d/133.docs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
`THIRD_PARTY.md` lists the runtime dependencies with their licenses, authors and URLs, regenerated with `make licenses`. (@syahra712)
1 change: 1 addition & 0 deletions changelog.d/135.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
`--telemetry cluster-environment-info` records the cluster environment. The device was listed and documented but never created. (@syahra712)
1 change: 1 addition & 0 deletions changelog.d/151.fixed.md
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions changelog.d/152.fixed.md
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions changelog.d/154.added.md
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions changelog.d/18.changed.md
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions changelog.d/22.changed.md
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions changelog.d/23.docs.md
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions changelog.d/25.docs.md
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions changelog.d/26.removed.md
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions changelog.d/3.added.md
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions changelog.d/39.fixed.md
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions changelog.d/4.changed.md
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions changelog.d/40.docs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The documentation describes only the workloads and features Solr Orbit has, explains `--test-procedures`, and site search works. (@janhoy)
1 change: 1 addition & 0 deletions changelog.d/41.docs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The documentation describes only the workloads and features Solr Orbit has, explains `--test-procedures`, and site search works. (@janhoy)
1 change: 1 addition & 0 deletions changelog.d/42.changed.md
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions changelog.d/43.added.md
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions changelog.d/49.added.md
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions changelog.d/50.changed.md
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions changelog.d/52.added.md
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions changelog.d/58.fixed.md
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions changelog.d/59.fixed.md
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions changelog.d/60.added.md
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions changelog.d/62.docs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The documentation describes only the workloads and features Solr Orbit has, explains `--test-procedures`, and site search works. (@janhoy)
1 change: 1 addition & 0 deletions changelog.d/69.fixed.md
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions changelog.d/72.fixed.md
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions changelog.d/74.fixed.md
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions changelog.d/76.fixed.md
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions changelog.d/77.fixed.md
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions changelog.d/80.fixed.md
Original file line number Diff line number Diff line change
@@ -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)
30 changes: 30 additions & 0 deletions changelog.d/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Changelog fragments

One Markdown file per PR, named `<PR number>.<type>.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
`+<slug>.<type>.md` and renders without a link.

```bash
make changelog-draft # preview the pending release notes
```
58 changes: 58 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ develop = [
"wheel>=0.38.4",
"github3.py==4.0.1",
"ruff==0.17.3",
"towncrier>=24.8",
]

# ---------------------------------------------------------------------------
Expand Down Expand Up @@ -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 = "<!-- towncrier release notes start -->\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
# ---------------------------------------------------------------------------
Expand Down
Loading
Loading