Multi-persona workflow for releasing TTA.dev packages to PyPI with full quality validation
Orchestrates Backend Engineer → Testing Specialist → DevOps Engineer for safe, validated
releases of the active root ttadev package.
[!WARNING] Current release automation targets the root
ttadevpackage and thepackages/ttadev/v{semver}tag format.Older
tta-dev-primitives,platform/primitives, and token-based release steps belonged to an earlier package layout. Use the workflow-basedrelease.yml+publish.ymlflow below instead.
Before starting:
main or a release branch.github/workflows/publish.ymlVerify:
git status
.github/copilot-hooks/post-generation.sh
git branch --show-current
gh workflow view release.yml
gh workflow view publish.yml
Goal: bump the root package version, update release notes, and prepare the repo.
LAST_TAG=$(git tag --list 'packages/ttadev/v*' --sort=-version:refname | head -1)
if [ -n "$LAST_TAG" ]; then
git log "$LAST_TAG"..HEAD --oneline
else
git log --oneline
fi
Choose:
OLD_VERSION=$(grep '^version =' pyproject.toml | cut -d'"' -f2)
NEW_VERSION="0.1.1"
sed -i "s/^version = \"$OLD_VERSION\"/version = \"$NEW_VERSION\"/" pyproject.toml
grep '^version =' pyproject.toml
Add the new section to CHANGELOG.md and review any pinned version references in active docs:
grep -n "0\\.1\\.0\\|0\\.1\\.1" README.md GETTING_STARTED.md PUBLISHING.md || true
git add pyproject.toml CHANGELOG.md README.md GETTING_STARTED.md PUBLISHING.md
git commit -m "chore(release): prepare ttadev v$NEW_VERSION"
git push origin main
Handoff: @testing-specialist Release prep is pushed; validate the gates.
Goal: confirm the repo is green before any tag is pushed.
.github/copilot-hooks/post-generation.sh
uv run pytest -v --tb=short -m "not integration and not slow and not external"
uv build --out-dir dist
ls -lh dist/
rm -rf dist
COMMIT_SHA=$(git rev-parse HEAD)
gh run watch "$(gh run list --commit "$COMMIT_SHA" --json databaseId -q '.[0].databaseId')"
gh run list --commit "$COMMIT_SHA" --json conclusion -q '.[0].conclusion'
Handoff: @devops-engineer Quality gates passed; proceed with release workflows.
Goal: create the release tag, let GitHub create the release, and optionally publish to PyPI.
git tag "packages/ttadev/v$NEW_VERSION"
git push origin "packages/ttadev/v$NEW_VERSION"
git tag --list "packages/ttadev/v$NEW_VERSION"
release.yml triggers automatically from the pushed tag.
gh run watch "$(gh run list --workflow=release.yml --json databaseId -q '.[0].databaseId')"
gh release view "packages/ttadev/v$NEW_VERSION"
publish.yml is manual and uses GitHub OIDC trusted publishing.
gh workflow run publish.yml -f tag="packages/ttadev/v$NEW_VERSION"
gh run watch "$(gh run list --workflow=publish.yml --json databaseId -q '.[0].databaseId')"
uv pip index versions ttadev | head -5
docker run --rm -t python:3.11 bash -lc "
pip install ttadev==$NEW_VERSION &&
python -c 'import ttadev; print(ttadev.__file__)'
"
Release is successful when:
pyproject.toml version is updatedCHANGELOG.md reflects the releasepackages/ttadev/vX.Y.Zrelease.yml created the GitHub Releasepublish.yml published ttadev to PyPIIf a release goes bad:
Use the PyPI web UI for the ttadev project to yank the bad release if necessary.
git tag -d "packages/ttadev/v$NEW_VERSION"
git push origin :"refs/tags/packages/ttadev/v$NEW_VERSION"
git checkout -b hotfix/ttadev-v$NEW_VERSION-fix
# apply fix
git commit -am "fix: critical issue in ttadev v$NEW_VERSION"
Solution: fix the failing lint, type, or test checks before tagging.
publish.yml failsSolution: verify the pypi environment and trusted publisher configuration, then rerun the
workflow.
Solution: wait a few minutes for PyPI indexing/CDN propagation, then retry verification.