Skip to content
Closed
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
5 changes: 5 additions & 0 deletions docs/agents/release.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ via `uv version`; no `pyproject.toml` bump) to PyPI, then creates the GitHub Rel
so a failed publish creates no Release. Pre-releases use the PEP 440 form (`2.0.0rc1`, not
`2.0.0-alpha.5`). PyPI is irreversible; there is no CI gate (a tag is the commitment point).

Before tagging, run `just test-integrations` on that `main`. It runs every integration's own tests
and `ty check` against the checkout, so a change that breaks an integration shows up before PyPI
has it. CI does not run it. A failure there either goes into the release notes as a breaking
change or gets fixed in the integration first.

The Release body is GitHub's generated notes, built from the squashed PR titles since the previous
tag. A conventional-commit PR title is therefore the changelog entry a reader gets, and that is
where the care goes. A release wanting prose gets it after the fact with
Expand Down
30 changes: 30 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,36 @@ test-docs-integrations *args:
--editable . pytest pytest-asyncio sybil {{ docs_integration_extras }} $packages
"$dir/venv/bin/python" -m pytest docs/integrations --docs-integrations {{ args }}

# Run each integration's own test suite and ty check against this checkout: clone its main, run its
# `just install`, then swap in this modern-di. Defaults to every page under docs/integrations/;
# pass page names (`just test-integrations grpc flask`) to pick some. Run before tagging a release.
test-integrations *names:
#!/usr/bin/env sh
set -u
root="$PWD"
dir="$(mktemp -d)"
trap 'rm -rf "$dir"' EXIT
echo "modern-di @ file://$root" > "$dir/overrides.txt"
names="{{ names }}"
[ -n "$names" ] || names="$(ls docs/integrations/*.md | sed -e 's#.*/##' -e 's#[.]md$##' | grep -vx writing-integrations)"
failed=""
for name in $names; do
repo="modern-di-$name"
log="$dir/$repo.log"
if git clone --quiet --depth 1 "https://github.com/modern-python/$repo.git" "$dir/$repo" >"$log" 2>&1 \
&& (cd "$dir/$repo" && just install \
&& uv pip install --python .venv --overrides "$dir/overrides.txt" --editable "$root" \
&& uv run --no-sync pytest -p no:cacheprovider \
&& uv run --no-sync ty check) >>"$log" 2>&1; then
echo "ok $repo"
else
echo "FAIL $repo"
tail -n 30 "$log" | sed 's#^# #'
failed="$failed $repo"
fi
done
[ -z "$failed" ] || { echo "failed:$failed"; exit 1; }

# The gated full run: 100% line and branch coverage of modern_di required. CI runs this.
test-ci:
uv run --no-sync pytest --cov --cov-report term-missing --cov-report xml
Expand Down
Loading