Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
80955de
Releng: move release preparation to scripts/release
fressi-elastic Mar 23, 2026
a5f58db
Apply suggestion from @Copilot
fressi-elastic Mar 23, 2026
696dd22
Apply suggestion from @Copilot
fressi-elastic Mar 23, 2026
65eb6b5
Use scripts/githooks/pre-commit and scripts/githooks/post-commit as G…
fressi-elastic Mar 23, 2026
f99b746
Remove sentence from contributing guide.
fressi-elastic Mar 23, 2026
6fbe035
Call `make pre-commit` in pre-commit hook.
fressi-elastic Mar 23, 2026
b7f8c18
Address pending comments from PR
fressi-elastic Mar 23, 2026
e1e0b64
docs: point release prep at Codex runbook, drop duplicated steps
fressi-elastic Mar 23, 2026
cef8a3c
Remove updated procudures from public documentation.
fressi-elastic Mar 23, 2026
b24e379
Remove references to Java 17 from changed documents.
fressi-elastic Mar 23, 2026
ca3f756
Rename RALLY_CHANGELOG_TOKEN to RALLY_CHANGELOG_TOKEN_FILE
fressi-elastic Mar 23, 2026
d348682
Remove stale Preparing a release doc references
fressi-elastic Mar 23, 2026
8fdedc4
Remove internal Codex links; restore public maintainer and doc pointers
fressi-elastic Mar 24, 2026
082057e
Remove docker based script and git hooks changes as being unrelated. …
fressi-elastic Mar 26, 2026
fa83363
Fix follow-ups from release tooling cleanup
fressi-elastic Mar 26, 2026
ad669f6
Fix makefile after prepare-docker.sh has been removed.
fressi-elastic Mar 26, 2026
56e27a8
Bump version to 2.14.0
fressi-elastic Mar 26, 2026
056be98
Workaround connection errors downloading licences from GitHub
fressi-elastic Mar 26, 2026
1cf1c6f
Fix regressions of Makefile
fressi-elastic Mar 27, 2026
aad1035
Merge branch 'master' of github.com:elastic/rally into chore/release-…
fressi-elastic Mar 27, 2026
e5cbac4
Revert esrally/_version.py
fressi-elastic Mar 27, 2026
34fd5e6
Fix broken script.
fressi-elastic Mar 27, 2026
4b6bf33
Release dry-run, drop tracked NOTICE.txt, fix tar on Python 3.10/3.11
fressi-elastic Mar 27, 2026
0d13a40
Harden release changelog: stderr messages, prepare.sh propagates fail…
fressi-elastic Mar 27, 2026
0ad1602
Merge branch 'master' of github.com:elastic/rally into chore/release-…
fressi-elastic Mar 28, 2026
56da168
Use pylint on changelog.py
fressi-elastic Mar 28, 2026
0a5e196
Merge branch 'master' of github.com:elastic/rally into chore/release-…
fressi-elastic Mar 30, 2026
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
85 changes: 85 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Patterns aligned with .gitignore — reduces Docker build context size.
# See .gitignore for original references and rationale.

# OS
.DS_Store
.AppleDouble
.LSOverride
._*
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.AppleDB
.AppleDesktop
.apdisk

# IDE / editors
*.iml
.idea/
*~
/.project
/.pydevproject
/.vscode

# Virtualenv / local env
.venv*/
env/
.envrc
.python-version

# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg

# Test / coverage
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
.hypothesis/
junit-*.xml
.pytest_cache/

# Translations / logs
*.mo
*.pot
*.log

# Docs build
docs/_build/

# PyBuilder
target/

# Pickles
*.pk

# Rally-specific
.rally_it/
NOTICE.txt
recipes/ccr/ccr-target-hosts.json
tracks/
12 changes: 11 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,15 @@ repos:
"-j0",
"--rcfile=.pylintrc",
]
exclude: ^(docs/|changelog.py)
exclude: ^(docs/|scripts/release/changelog\.py)
require_serial: true

# Shell scripts: release tooling and repo githooks. Widen to all *.sh once legacy
# scripts under .buildkite/, recipes/, repo root, etc. pass shellcheck.
- repo: https://github.com/shellcheck-py/shellcheck-py
rev: v0.11.0.1
hooks:
- id: shellcheck
name: shellcheck
args: [-x]
files: (^scripts/release/.*\.sh$)|(^scripts/githooks/(pre-commit|post-commit)$)
17 changes: 16 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,17 @@ If you want to get started in the project, a good idea is to check issues labele
You will need to fork the Rally repository and clone it to your local machine. See
the [Github help page](https://help.github.com/articles/fork-a-repo) for help.

Optional: use this repository’s hooks under `scripts/githooks` (instead of `.git/hooks`):

```bash
git config core.hooksPath scripts/githooks
```

* **`pre-commit`** — runs `uv run -- pre-commit run` (same as `make pre-commit`) on staged files before the commit is created. Requires [uv](https://docs.astral.sh/uv/) and a dev environment (`make install` or `make venv`). You do not need `make install-pre-commit` when using this path.
* **`post-commit`** — strips `Co-authored-by` / `Made-with: Cursor` trailers Cursor may add; it runs `git commit --amend` when the message changes, so the latest commit’s hash can change.

To stop using these hooks in this clone, run `git config --unset core.hooksPath`. The post-commit hook sets `GIT_CURSOR_HOOK_AMENDING` internally to avoid re-running while amending; you normally do not need to set that variable yourself.

### Importing the project into IntelliJ IDEA

Rally builds using virtualenv. When importing into IntelliJ you will need to define an appropriate Python SDK, which is provided by virtualenv.
Expand All @@ -60,7 +71,7 @@ Once your changes and tests are ready to submit for review:

Ensure that all tests pass by running `make check-all`. This runs sequentially lint checks, unit tests and integration tests. These can be executed in isolation using `make lint`, `make test` and `make it` respectively, in case you need to iterate over a subset of tests.

Note: Integration tests are much slower than unit tests and require `docker-compose`.
Note: Integration tests are much slower than unit tests and require `docker-compose`. They also require **Java 17 or 21**; set `JAVA_HOME` (or `JAVA21_HOME`) to match.
Comment thread
fressi-elastic marked this conversation as resolved.
Outdated

3. Sign the Contributor License Agreement

Expand All @@ -79,6 +90,10 @@ Then sit back and wait. There will probably be discussion about the pull request

Note: Contributors belonging to the "Elastic" organization on Github can merge PRs themselves after getting a "LGTM" (Looks good to me); this workflow is similar to the established one in the Elasticsearch project.

## Release process (maintainers)

Version bumps and changelog updates are automated with `scripts/release/prepare.sh` (often via `make release RELEASE_VERSION=X.Y.Z`, which uses Docker). Put the GitHub token at `~/.github/rally_release_changelog.token`, or set `RALLY_CHANGELOG_TOKEN` to that file's path so `changelog.py`, `make release-checks`, and `prepare-docker.sh` use the same location on the host. See the **Preparing a release** section in the [development documentation](https://esrally.readthedocs.io/en/latest/developing.html#preparing-a-release) for milestones, tokens, the release container, and how that differs from the published `elastic/rally` benchmark image.

# Contributing to the Rally codebase

**Repository:** [https://github.com/elastic/rally](https://github.com/elastic/rally)
Expand Down
12 changes: 8 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -217,11 +217,15 @@ benchmark: venv
# --- Release goals ---

release-checks: venv
$(VENV_ACTIVATE); ./release-checks.sh $(release_version) $(next_version)
@if [ -z "$(RELEASE_VERSION)" ]; then echo "error: set RELEASE_VERSION (e.g. make release-checks RELEASE_VERSION=2.13.0)" >&2; exit 1; fi
$(VENV_ACTIVATE); ./scripts/release/checks.sh $(RELEASE_VERSION)

# usage: e.g. make release release_version=0.9.2 next_version=0.9.3
release: venv release-checks clean docs lint test it
$(VENV_ACTIVATE); ./release.sh $(release_version) $(next_version)
# usage: e.g. make release RELEASE_VERSION=2.13.0
release:
@if [ -z "$(RELEASE_VERSION)" ]; then echo "error: set RELEASE_VERSION (e.g. make release RELEASE_VERSION=2.13.0)" >&2; exit 1; fi
./scripts/release/prepare-docker.sh $(RELEASE_VERSION)

# --- Other goals ---

# This is a shortcut for creating a shell running inside the project virtual environment.
sh:
Expand Down
39 changes: 39 additions & 0 deletions docs/developing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Install the following software packages:

* `uv <https://docs.astral.sh/uv/getting-started/installation/>`_
* JDK version required to build Elasticsearch. Please refer to the `build setup requirements <https://github.com/elastic/elasticsearch/blob/main/CONTRIBUTING.md#contributing-to-the-elasticsearch-codebase>`_.
For running Rally's integration tests (e.g. ``make it`` or ``make it_tracks_compat``), ensure your environment uses **Java 17 or 21** (recent Rally versions use Java 21 in CI). Set ``JAVA_HOME`` or ``JAVA21_HOME`` accordingly.
Comment thread
fressi-elastic marked this conversation as resolved.
Outdated
* `Docker <https://docs.docker.com/install/>`_ and on Linux additionally `docker-compose <https://docs.docker.com/compose/install/>`_.
* `jq <https://stedolan.github.io/jq/download/>`_
* git
Expand Down Expand Up @@ -77,6 +78,44 @@ To get a rough understanding of Rally, it makes sense to get to know its key com

There is a dedicated :doc:`tutorial on how to add new tracks to Rally</adding_tracks>`.

.. _dev_preparing_a_release:

Preparing a release
-------------------

The script ``scripts/release/prepare.sh`` automates steps before opening a release pull request: it rebuilds ``NOTICE.txt``, refreshes ``AUTHORS``, prepends ``CHANGELOG.md`` from a GitHub milestone (via ``scripts/release/changelog.py``), writes ``esrally/_version.py``, creates a git commit, and runs ``pip install --editable .`` to assert the reported ``esrally`` version.

You need:

* A milestone on ``elastic/rally`` titled exactly like the version argument (e.g. ``2.13.0``). ``scripts/release/changelog.py`` uses an open milestone with that title if one exists; otherwise it reopens a closed milestone with the same title or creates a new open milestone. Assign merged PRs to the milestone so the generated changelog sections are populated.
* A GitHub API token stored as a single line in a file. By default ``scripts/release/changelog.py`` and ``make release-checks`` (via ``scripts/release/checks.sh``) use ``$HOME/.github/rally_release_changelog.token``. If ``RALLY_CHANGELOG_TOKEN`` is set to a **filesystem path** to that file, they use it instead (same variable as ``prepare-docker.sh`` on the host). The token must allow creating or updating milestones when none is open.

Creating a fine-grained personal access token
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

``scripts/release/changelog.py`` uses the GitHub API to list closed issues and pull requests on a milestone and to **create or reopen** milestones when needed (milestones are part of the Issues API).

Follow GitHub's `fine-grained personal access token documentation <https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-fine-grained-personal-access-token>`_ for the latest UI; the outline below matches the typical flow:

#. In GitHub: **Settings → Developer settings → Personal access tokens → Fine-grained tokens → Generate new token**.
#. Set a name and expiration (recommend a short lifetime such as 7 days for release-only tokens).
#. **Resource owner:** your GitHub user (the usual case).
#. **Repository access:** **Only select repositories** → choose **elastic/rally**. Your account must have a role on that repository that can manage milestones.
#. **Repository permissions:** under **Issues**, set **Read and write**. GitHub maps milestone create/update and milestone-scoped issue queries to the Issues permission on fine-grained tokens.
#. Generate the token and copy it when shown; it is displayed only once.

If the **elastic** organization enforces SAML SSO, open the token on GitHub after creation and use **Configure SSO** / **Authorize** for **elastic**. Without that step, the API can return 403 even when permissions are correct.
Comment thread
fressi-elastic marked this conversation as resolved.
Outdated

Store the token as a single line in ``~/.github/rally_release_changelog.token`` for host-side runs, or set ``RALLY_CHANGELOG_TOKEN`` to that file's path so ``changelog.py``, ``release-checks``, and ``prepare-docker.sh`` agree without copying the file. For Docker release prep, ``prepare-docker.sh`` bind-mounts the host file chosen by ``RALLY_CHANGELOG_TOKEN`` (default: the path above) into the container at ``$HOME/.github/rally_release_changelog.token`` (see the script header); inside the container the default path is used.

A **classic** personal access token with the **public_repo** scope (public repositories only) or the **repo** scope can also work, as noted in ``scripts/release/changelog.py``; fine-grained tokens with Issues **Read and write** are preferred for least privilege.

From a clean working tree (after staging intended changes), you can run ``prepare.sh`` on the host (with a suitable Python environment and ``github3-py`` available), or use Docker via ``make release RELEASE_VERSION=X.Y.Z``. That target runs ``scripts/release/prepare-docker.sh``, which builds ``scripts/release/Dockerfile``, bind-mounts the repository at ``/workspace``, and runs ``scripts/release/prepare.sh`` in the container. This maintainer flow is **not** the published ``elastic/rally`` benchmark image; see :doc:`docker`.

**Canonical details** that change when scripts do—bind mounts, optional environment variables (token path, image tag, skipping rebuild, ``DOCKER_USER``, named ``.venv`` volume and how to reset it), TTY behavior, and ``PREPARE_RELEASE_NO_VERIFY`` for the in-container commit—are documented in the **header comment** of ``scripts/release/prepare-docker.sh``. **Python base image** (``3.13``), **dependency pins**, and **why** the image differs from CI’s ``3.10``–``3.13`` matrix are in ``scripts/release/Dockerfile`` comments. Build context is the repository root; **``.dockerignore``** shrinks the context (see that file).

``make release`` does **not** run ``clean``, ``install``, ``docs``, ``lint``, or ``test``. Before opening the release pull request, run the validation your team expects (for example ``make check-all`` and ``make release-checks RELEASE_VERSION=X.Y.Z``). Platform differences for ``release-checks`` (GPG, ``origin``, skipped checks on macOS / in Docker) live in ``scripts/release/checks.sh``. Run ``make pre-commit`` on the host before releasing if you want hooks to run before the version bump; the bump commit inside the container skips hooks by design (see ``prepare-docker.sh`` header).

How to contribute code
----------------------

Expand Down
14 changes: 14 additions & 0 deletions docs/docker.rst
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,17 @@ You can then build and test the image with::

docker build --tag=custom-rally .
docker run -ti custom-rally list tracks

Release preparation image (maintainers)
Comment thread
fressi-elastic marked this conversation as resolved.
Outdated
---------------------------------------

The ``elastic/rally`` image above is for **running** benchmarks. Rally releases use a **separate** image and script path.

Maintainers run ``scripts/release/prepare-docker.sh``, which:

* Builds ``scripts/release/Dockerfile`` (Python 3.13 on Debian bookworm, plus ``jq``, ``git``, ``make``, ``uv``, compilers). The image installs ``github3.py`` and performs a minimal **editable** install of Rally (``pyproject.toml``, ``README.md``, and ``esrally/`` only) so unrelated tree changes do not constantly invalidate the image layers.
* Uses the **repository root** as the Docker build context. The root **``.dockerignore``** file excludes typical dev artifacts (virtualenvs, ``docs/_build``, tests metadata, etc.) so ``docker build`` stays fast and the context stays small.
* Bind-mounts your full checkout to ``/workspace`` and mounts a **named volume** at ``/workspace/.venv`` (``rally-prepare-release-venv``) so the container does not use the host virtualenv.
* Runs ``scripts/release/prepare.sh`` under your host UID/GID (via ``setpriv`` after a one-time ``chown`` on the venv volume) so ``NOTICE.txt``, ``CHANGELOG.md``, and other generated files are owned correctly on the bind mount.

Changelog generation and GitHub milestone behavior (including creating or reopening a milestone) live in ``scripts/release/changelog.py``; token setup is described under :ref:`dev_preparing_a_release` in :doc:`developing`.
64 changes: 0 additions & 64 deletions prepare-release.sh

This file was deleted.

5 changes: 4 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ classifiers = [
]
################################################################################################
#
# Adapt `create-notice.sh` whenever changing dependencies here.
# Adapt `scripts/release/create-notice.sh` whenever changing dependencies here.
#
# That script grabs all license files so we include them in the notice file.
#
Expand Down Expand Up @@ -92,6 +92,8 @@ dependencies = [
"hatch==1.3.1",
"hatchling==1.6.0",
"wheel==0.46.2",
# Release Docker image pins the same pip (scripts/release/Dockerfile).
"pip==26.0.1",
Comment thread
fressi-elastic marked this conversation as resolved.
Outdated
]

[project.optional-dependencies]
Expand All @@ -117,6 +119,7 @@ develop = [
"pytest-httpserver==1.1.3",
"sphinx==5.1.1",
"furo==2022.06.21",
# Release image + prepare-docker venv pin the same version (scripts/release/Dockerfile, prepare-docker.sh).
"github3.py==3.2.0",
"pre-commit==2.20.0",
"pylint==3.3.8",
Expand Down
70 changes: 0 additions & 70 deletions release-checks.sh

This file was deleted.

Loading
Loading