diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1c24e48..cf80a66 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,10 +1,11 @@ # AgentOps Toolkit — CI/CD Pipelines # # Workflows: -# 1. ci.yml — Lint + test on every push/PR +# 1. ci.yml — Lint + test on every push/PR; publish dev builds to TestPyPI on develop # 2. _build.yml — Reusable build (test + package), called by staging and release # 3. staging.yml — Staging: release/* branch → TestPyPI → verify # 4. release.yml — Production: v* tag → TestPyPI → verify → PyPI → GitHub Release +# 5. cut-release.yml — Manual dispatch: create release branch + PR from develop name: CI @@ -97,3 +98,91 @@ jobs: with: name: coverage-report path: coverage.xml + + # Publish dev build to TestPyPI on every push to develop (not PRs) + publish-dev: + if: github.event_name == 'push' && github.ref == 'refs/heads/develop' + needs: [lint, test] + runs-on: ubuntu-latest + environment: staging + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # Full history for setuptools-scm + + - name: Install uv + uses: astral-sh/setup-uv@v6 + with: + version: ">=0.9.0" + + - name: Set up Python + run: uv python install 3.12 + + - name: Install dependencies + run: uv sync --group dev + + - name: Build package + run: uv build + + - name: Show version + run: | + ls -la dist/ + uv run python -c "from importlib.metadata import version; print(f'Dev version: {version(\"agentops-toolkit\")}')" + + - name: Publish to TestPyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + repository-url: https://test.pypi.org/legacy/ + password: ${{ secrets.TEST_PYPI_TOKEN }} + verbose: true + skip-existing: true + + # Verify the dev build installs correctly + verify-dev: + if: github.event_name == 'push' && github.ref == 'refs/heads/develop' + needs: publish-dev + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Determine expected version + id: version + run: | + pip install setuptools-scm + VERSION=$(python -m setuptools_scm) + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + echo "Expected dev version: $VERSION" + + - name: Install from TestPyPI + run: | + for i in 1 2 3 4 5; do + echo "Attempt $i: installing agentops-toolkit==${{ steps.version.outputs.version }}" + pip install \ + "agentops-toolkit==${{ steps.version.outputs.version }}" \ + --index-url https://test.pypi.org/simple/ \ + --extra-index-url https://pypi.org/simple/ \ + && break + echo "Not available yet, waiting 30s..." + sleep 30 + done + + - name: Smoke test + run: | + agentops --version + agentops --help + + - name: Summary + run: | + echo "## ✅ Dev build published and verified" >> "$GITHUB_STEP_SUMMARY" + echo "" >> "$GITHUB_STEP_SUMMARY" + echo "- Version: \`${{ steps.version.outputs.version }}\`" >> "$GITHUB_STEP_SUMMARY" + echo "- TestPyPI: https://test.pypi.org/project/agentops-toolkit/${{ steps.version.outputs.version }}/" >> "$GITHUB_STEP_SUMMARY" + echo "" >> "$GITHUB_STEP_SUMMARY" + echo "Install: \`pip install agentops-toolkit==${{ steps.version.outputs.version }} --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/\`" >> "$GITHUB_STEP_SUMMARY" diff --git a/docs/release-process.md b/docs/release-process.md index 5168ee7..196a0cc 100644 --- a/docs/release-process.md +++ b/docs/release-process.md @@ -199,8 +199,12 @@ The CI pipeline runs on **every push and PR** to `main` or `develop`. | Job | What it does | Runs on | | --- | --- | --- | | **lint** | `ruff check` (linting) + `mypy` (type checking, soft-fail) | Ubuntu, Python 3.11 | -| **test** | `pytest tests/` with JUnit XML output | Matrix: 3 OS × 3 Python versions | +| **test** | `pytest tests/` with JUnit XML output | Matrix: 2 OS × 3 Python versions | | **coverage** | `pytest --cov` with XML coverage report | Ubuntu, Python 3.13 (after tests pass) | +| **publish-dev** | Build package + publish to TestPyPI (develop pushes only) | Ubuntu, Python 3.12 (after lint + test pass) | +| **verify-dev** | Install from TestPyPI + smoke test (develop pushes only) | Ubuntu, Python 3.12 (after publish-dev) | + +The `publish-dev` and `verify-dev` jobs only run on pushes to `develop` (not on PRs). Every merged PR automatically produces an installable dev build on TestPyPI with a version like `0.1.3.dev12`. ### Test Matrix @@ -730,11 +734,14 @@ All workflow files are in `.github/workflows/`: ### `ci.yml` — Continuous Integration ``` -Trigger: push/PR to main or develop +Trigger: push to develop, PR to main or develop Flow: lint → test (matrix) → coverage -Purpose: Quality gate for all code changes + + on develop push: publish-dev → verify-dev (TestPyPI) +Purpose: Quality gate for all code changes; auto-publish dev builds ``` +Key detail: `publish-dev` and `verify-dev` only run on pushes to `develop` (not PRs). Every merge to develop produces a dev version on TestPyPI (e.g. `0.1.3.dev12`) via setuptools-scm. + ### `_build.yml` — Reusable Build ``` @@ -878,6 +885,7 @@ Use this checklist when cutting a release: │ ├──→ CI (ci.yml) │ lint + test + coverage + │ + publish-dev → TestPyPI (dev version) │ └──→ Cut Release (cut-release.yml) manual dispatch → enter version