Development¶
ElasticMigrate uses uv and supports Python 3.11 and newer.
git clone https://github.com/zobayer1/elastic-migrate.git
cd elastic-migrate
uv sync
uv run pre-commit install
Checks¶
Command |
Purpose |
|---|---|
|
Unit tests with branch coverage; 100% is required. |
|
Lint and format (line length 120). |
|
Type checking: strict for |
|
All of the above hooks. |
Integration tests¶
Integration tests run the real CLI against Elasticsearch 8 (plain, HTTPS and mutual TLS), PostgreSQL 17 and MySQL 8.4 in Docker. They are excluded from the default test run and fail, rather than skip, when a service is down.
docker compose up -d --wait
uv run pytest -m integration
docker compose down
The compose stack generates a throwaway CA and certificates into .certs/ on first start.
Documentation¶
uv run --group docs sphinx-build -W --keep-going -b html -d docs/_build/doctrees docs docs/_build/html
Pages are MyST Markdown in docs/. Every config.json example in a json code block is loaded by the test suite, so
examples must stay valid. The site is deployed to GitHub Pages from main.
Releases¶
Releases are built by GitHub Actions and signed locally by the maintainer; the signing key never leaves the
maintainer’s machine. Builds are reproducible: the build backend is pinned with hashes in build-constraints.txt,
SOURCE_DATE_EPOCH is set to the tagged commit’s time, and build-toolchain.env pins the uv version and the
uv-managed CPython that build the archives. The interpreter matters because archive compression comes from its zlib:
a system Python linked against zlib-ng, as on Fedora, packs the same files into different bytes.
Update
docs/changelog.mdwith the version and date, merge tomainand wait for CI to pass.Create a signed tag on
mainand push it:git tag -s v2.0.0 -m "ElasticMigrate 2.0.0" git push origin v2.0.0
The Release workflow runs the tests, builds the wheel and source archive, writes
SHA256SUMS, attests build provenance and creates a draft release.Verify, reproduce and sign the draft, first as a dry run:
scripts/sign-release.sh --dry-run v2.0.0 scripts/sign-release.sh v2.0.0
The script checks that the release is a draft, that the tag is signed by a trusted release key, the checksums and attestations, and that a local rebuild from the tag is byte-identical. The rebuild runs the uv version pinned in the tag’s
build-toolchain.envthroughuvxand installs the pinned CPython into a temporary directory, so the local uv and Python installations are not involved. It then signs every file, uploads the signatures, publishes the release and starts the docs deployment frommain, which refreshes the Downloads page. The site is always built frommain, never from a tag.
To update the pinned build backend:
printf 'hatchling\nhatch-vcs\n' | uv pip compile - --universal --generate-hashes --python-version 3.11 --no-header -o build-constraints.txt
To update the pinned toolchain, set UV_VERSION to a uv release and BUILD_PYTHON to a CPython version that this uv
release can download:
uvx uv@0.13.6 python list --only-downloads --all-versions 3.11
Continuous integration¶
GitHub Actions runs linting, type checking, unit and integration tests on Python 3.11 and 3.14, a package build check and a documentation build on every push. Coverage is reported to Codecov.