From d5c2f6232e1a35d8aa23adc56f8e31d78bd1b8f2 Mon Sep 17 00:00:00 2001 From: ColonistOne Date: Thu, 9 Apr 2026 11:48:32 +0100 Subject: [PATCH] Add OIDC release automation and grouped Dependabot MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ports the same release workflow we set up on colony-sdk-python: git tag vX.Y.Z && git push origin vX.Y.Z triggers .github/workflows/release.yml, which runs the test suite, builds wheel + sdist, publishes to PyPI via short-lived OIDC tokens (no API token stored anywhere), and creates a GitHub Release with the matching CHANGELOG section as release notes. Differences from the colony-sdk-python version: - Test job installs colony-sdk + crewai (not just the SDK's own deps) - Version-tag check verifies BOTH pyproject.toml AND src/crewai_colony/__init__.py:__version__ agree with the pushed tag — crewai-colony keeps the version in two places, so a mismatch is easy to introduce by hand. Also adds .github/dependabot.yml — pip + github-actions, weekly Monday, grouped into single PRs per ecosystem to minimise noise (same config as colony-sdk-python). Configuring the PyPI Trusted Publisher for crewai-colony is a separate one-time external step that happens before the first tag is pushed. The PR description tracks the steps. Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/dependabot.yml | 28 ++++++++ .github/workflows/release.yml | 126 ++++++++++++++++++++++++++++++++++ CHANGELOG.md | 5 ++ 3 files changed, 159 insertions(+) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/release.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..0f69316 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,28 @@ +version: 2 +updates: + - package-ecosystem: "pip" + directory: "/" + schedule: + interval: "weekly" + day: "monday" + open-pull-requests-limit: 5 + labels: + - "dependencies" + groups: + python-deps: + patterns: + - "*" + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + day: "monday" + open-pull-requests-limit: 5 + labels: + - "dependencies" + - "ci" + groups: + actions: + patterns: + - "*" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..4eddca4 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,126 @@ +name: Release + +# Publishes to PyPI via OIDC trusted publishing whenever a `v*` tag is pushed. +# No API tokens are stored anywhere — PyPI mints a short-lived token from +# the GitHub Actions OIDC identity at publish time. +# +# To cut a release: +# 1. Bump the version in pyproject.toml AND src/crewai_colony/__init__.py +# (the build job below verifies they agree with the tag) +# 2. Move the "## Unreleased" section in CHANGELOG.md under a new +# "## X.Y.Z — YYYY-MM-DD" heading +# 3. Merge to main +# 4. git tag vX.Y.Z && git push origin vX.Y.Z +# +# This workflow will then: run the test suite, build wheel + sdist, +# publish to PyPI via OIDC, and create a GitHub Release with the +# CHANGELOG section as the release notes. + +on: + push: + tags: + - "v*" + +jobs: + test: + name: Test before release + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-python@v6 + with: + python-version: "3.12" + - run: pip install colony-sdk crewai pytest pytest-asyncio pytest-cov ruff mypy + - run: ruff check src/ tests/ + - run: ruff format --check src/ tests/ + - run: mypy src/ + - run: pytest + + build: + name: Build distributions + needs: test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-python@v6 + with: + python-version: "3.12" + - run: pip install build + - run: python -m build + - name: Verify version matches tag + # crewai-colony keeps the version in two places (pyproject.toml and + # src/crewai_colony/__init__.py:__version__) — both must agree with + # the pushed tag, or we refuse to publish. + run: | + TAG_VERSION="${GITHUB_REF#refs/tags/v}" + PKG_VERSION=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])") + INIT_VERSION=$(python -c "import re,sys; m=re.search(r'__version__\s*=\s*[\x22\x27]([^\x22\x27]+)[\x22\x27]', open('src/crewai_colony/__init__.py').read()); print(m.group(1) if m else '')") + if [ "$TAG_VERSION" != "$PKG_VERSION" ]; then + echo "::error::Tag v$TAG_VERSION does not match pyproject.toml version $PKG_VERSION" + exit 1 + fi + if [ "$TAG_VERSION" != "$INIT_VERSION" ]; then + echo "::error::Tag v$TAG_VERSION does not match src/crewai_colony/__init__.py __version__ $INIT_VERSION" + exit 1 + fi + echo "Tag, pyproject.toml and __init__.py all agree on version $PKG_VERSION" + - uses: actions/upload-artifact@v4 + with: + name: dist + path: dist/ + + publish: + name: Publish to PyPI + needs: build + runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/p/crewai-colony + permissions: + id-token: write # required for OIDC trusted publishing + steps: + - uses: actions/download-artifact@v4 + with: + name: dist + path: dist/ + - name: Publish to PyPI via OIDC + uses: pypa/gh-action-pypi-publish@release/v1 + + github-release: + name: Create GitHub Release + needs: publish + runs-on: ubuntu-latest + permissions: + contents: write # required for gh release create + steps: + - uses: actions/checkout@v6 + - uses: actions/download-artifact@v4 + with: + name: dist + path: dist/ + - name: Extract changelog section for this version + run: | + VERSION="${GITHUB_REF#refs/tags/v}" + # Print everything under "## VERSION " up to (but not including) + # the next "## " heading. Strips the heading line itself. + awk -v ver="$VERSION" ' + /^## / { + if (in_section) exit + if ($0 ~ "^## " ver " ") { in_section = 1; next } + next + } + in_section { print } + ' CHANGELOG.md > release_notes.md + if [ ! -s release_notes.md ]; then + echo "::warning::No CHANGELOG entry found for $VERSION — release notes will be empty" + fi + echo "--- release_notes.md ---" + cat release_notes.md + - name: Create GitHub Release + env: + GH_TOKEN: ${{ github.token }} + run: | + gh release create "${GITHUB_REF_NAME}" \ + --title "${GITHUB_REF_NAME}" \ + --notes-file release_notes.md \ + dist/* diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e5babc..95acf39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +### Infrastructure + +- **OIDC release automation** — releases now ship via PyPI Trusted Publishing on tag push. `git tag vX.Y.Z && git push origin vX.Y.Z` triggers `.github/workflows/release.yml`, which runs the test suite, builds wheel + sdist, publishes to PyPI via short-lived OIDC tokens (no API token stored anywhere), and creates a GitHub Release with the changelog entry as release notes. The workflow refuses to publish if the tag version doesn't match **both** `pyproject.toml` and `src/crewai_colony/__init__.py:__version__`. +- **Dependabot** — `.github/dependabot.yml` watches `pip` and `github-actions` weekly, **grouped** into single PRs per ecosystem to minimise noise. + ### Added - **`verify_webhook`** — re-exported from `colony_sdk` so callers can do `from crewai_colony import verify_webhook`. HMAC-SHA256 verification with constant-time comparison and `sha256=` prefix tolerance — same security guarantees as the SDK function (we re-export rather than re-wrap, so callers automatically pick up SDK security fixes).