Developer deployment guide#
This guide describes how maintainers promote a validated RESource commit into a Python package release and public documentation. Deployment is a maintainer action; ordinary contributors should stop after opening a reviewed pull request.
Deployment targets#
RESource has two independent artifacts:
The
deltae-resourcedistribution published to PyPI. It provides theRESourceimport package and theresourceandresource-multiyearcommands.The Sphinx HTML site published at https://deltae.github.io/RESource/.
Both artifacts must originate from the same reviewed commit and identify the same release version. Data products, credentials, caches, notebooks, and generated research results are not deployment artifacts.
1. Prepare the release commit#
Start from a clean, reviewed development branch and synchronize the locked environment:
uv sync --locked --all-extras
uv lock --check
uv run pre-commit run --all-files
uv run pre-commit run --all-files --hook-stage pre-push
Set the same PEP 440 version in pyproject.toml and
src/RESource/__init__.py. Update release notes, compatibility guidance, and
citations. Confirm that credentials/coders_api.yaml, downloaded data, results,
and local caches are absent from git status and release artifacts.
2. Validate package and documentation#
uv run --locked pytest
uv run --locked ruff check src tests run.py
uv run --locked ruff format --check src tests run.py
uv run sphinx-build -E -a -W --keep-going \
-b html docs/source docs/_build/html
uv build
uvx twine check dist/*
Inspect the rendered documentation locally:
uv run python -m http.server 8000 --directory docs/_build/html
Open http://localhost:8000 and check installation commands, navigation, API pages, DOI links, and the release version.
3. Test the built wheel#
Install the wheel into a clean environment outside the repository:
uv venv /tmp/deltae-resource-release-test
uv pip install --python /tmp/deltae-resource-release-test/bin/python \
dist/deltae_resource-*.whl
/tmp/deltae-resource-release-test/bin/python -c \
"import RESource; print(RESource.__version__)"
/tmp/deltae-resource-release-test/bin/resource --help
/tmp/deltae-resource-release-test/bin/resource-multiyear --help
Do not run a complete regional assessment as a release smoke test because it may download large datasets and require personal credentials. Use deterministic test fixtures for automated validation.
4. Publish the Python package#
Prefer PyPI Trusted Publishing from a protected GitHub release workflow. Validate the first release candidate on TestPyPI, then publish the exact same commit to PyPI. For the documented manual-token fallback, see the PyPI publishing guide. Never place a PyPI token in the repository, shell history, logs, or workflow YAML.
After publishing, verify from a clean context:
uvx --from deltae-resource resource --help
python -m pip index versions deltae-resource
5. Deploy the documentation#
RESource historically deploys the generated site to the gh-pages branch with
ghp-import. The former Make target ran:
ghp-import -n -p -f docs/_build/html
The maintained uv equivalent is:
# Build and validate first.
uv run sphinx-build -E -a -W --keep-going \
-b html docs/source docs/_build/html
# Publish only after reviewing the rendered site and current commit.
uvx ghp-import --no-jekyll --push --force \
--branch gh-pages --remote origin docs/_build/html
--push changes the remote repository and --force replaces the generated branch
contents, so this command is for authorized maintainers only. Before running it:
git status --short
git remote get-url origin
git rev-parse HEAD
Deploy only a reviewed, committed source state and record that commit SHA in the
release. In the GitHub repository settings, Pages must publish from the gh-pages
branch (root), or an existing action must be configured to react to that branch.
The generated branch contains the site; docs/_build/ remains ignored on the
development branch.
The repository currently contains no checked-in GitHub Actions workflow that builds or deploys Pages. A future protected Pages workflow could replace the direct push by:
checks out the tagged commit;
installs uv;
runs
uv sync --locked --extra docs;builds Sphinx with warnings treated as errors;
uploads only
docs/_build/html; anddeploys that artifact to GitHub Pages after required checks pass.
Until such a workflow is added and reviewed, use the established ghp-import
branch deployment above. Never commit docs/_build/ to the development branch.
6. Tag and verify#
Create the release tag only after validation, following the repository's chosen tag format. The GitHub release, PyPI version, documentation, DOI citation, and artifact checksums should all point to the same commit.
Final verification includes:
PyPI installation and both CLI help commands;
public documentation availability and navigation;
correct project and DOI links;
absence of credentials and local paths in artifacts;
wheel and source-distribution license files; and
a rollback note describing how to yank a broken PyPI release and redeploy the previous documentation artifact without reusing a published version number.
Rollback principles#
PyPI releases are immutable: publish a corrected version rather than overwriting a file. A seriously broken release may be yanked while preserving its history. Documentation may be redeployed from the last known-good tag. Never delete tags or rewrite release history merely to make artifacts appear consistent.