From fdead92510fa678124572763502046eea1c7bf7f Mon Sep 17 00:00:00 2001 From: Alain Prasquier Date: Mon, 13 Apr 2026 23:49:05 +0300 Subject: [PATCH 1/2] =?UTF-8?q?=E2=9C=A8=20chore(publish):=20improve=20PyP?= =?UTF-8?q?I=20workflow=20gating=20and=20bump=20logic=20Add=20a=20CI=20to?= =?UTF-8?q?=20gate=20the=20workflow=20and=20skip=20expensive=20steps=20for?= =?UTF-8?q?=20release=20commits,=20preventing=20double=20publishing=20and?= =?UTF-8?q?=20runs-=20publish=20workflow=20into=20two=20jobs=20(ci=20->=20?= =?UTF-8?q?publish)=20and=20publish=20depend=20on=20ci=20to=20early=20exit?= =?UTF-8?q?=20and=20clearer=20job.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Tighten repo-only conditionals and set fetch-depth:0 for full git history for version operations. - OIDC and contents permissions clearer. - Simplify and harden version bump step: - standardize step id bump and COMMIT_MESSAGE env. - detect [MAJOR]/[MINOR]/[PATCH] markers in commit (case- insensitive) and to minor. - emit part to GITHUB_OUTPUT downstream use. - Update bump/commit behavior - use-actionsbot] identity to make trace and avoid ambiguous author info. - call bump-my-version with the selected part and push follow-tags. - Remove local version extraction consolidate bump+push. - Rename step title and Hatch build unchanged. Motivation: make automated versioning and publishing robust, prevent accidental double on release commits, and simplifycommit-message-driven version bumps. --- .github/workflows/publish-pypi.yml | 65 ++++++++++++---------------- .github/workflows/python-package.yml | 5 ++- docs/CHANGELOG.md | 16 +++---- justfile | 24 +++++++--- pyproject.toml | 7 ++- 5 files changed, 63 insertions(+), 54 deletions(-) diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index 0b13012..f9ca8c1 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -10,19 +10,28 @@ concurrency: cancel-in-progress: true jobs: + # ─── Job 0: CI gate — skip the whole workflow on release commits ─── + ci: + if: | + github.repository == 'supervaize/supervaizer' && + !contains(github.event.head_commit.message, 'chore(release):') + uses: ./.github/workflows/python-package.yml + + # ─── Job 1: Version bump, tag, build, and publish ─── publish: + needs: ci runs-on: ubuntu-latest - if: github.repository == 'supervaize/supervaizer' # Only run on public remote environment: name: pypi url: https://pypi.org/p/supervaizer permissions: - id-token: write # required for trusted publishing if using PyPI's OIDC - contents: write # required for committing version bump + id-token: write # required for OIDC trusted publishing + contents: write # required for committing version bump steps: - uses: actions/checkout@v4 with: + fetch-depth: 0 token: ${{ secrets.GITHUB_TOKEN }} - name: Set up Python @@ -36,50 +45,32 @@ jobs: enable-cache: true - name: Install bump-my-version - run: | - uv tool install bump-my-version + run: uv tool install bump-my-version - name: Determine version bump type - id: version-bump-type + id: bump-type + env: + COMMIT_MESSAGE: ${{ github.event.head_commit.message }} run: | - # Get the commit message of the latest commit - COMMIT_MSG=$(git log -1 --pretty=%B) - echo "Commit message: $COMMIT_MSG" - - # Check if commit contains [MAJOR] or [MINOR] - VERSION_BUMP=patch - - # Determine the bump type based on commit message - if [[ "$COMMIT_MSG" == *"[MAJOR]"* ]]; then - VERSION_BUMP=major - elif [[ "$COMMIT_MSG" == *"[MINOR]"* ]]; then - VERSION_BUMP=minor + MSG="$COMMIT_MESSAGE" + if echo "$MSG" | grep -qi '\[MAJOR\]'; then PART="major" + elif echo "$MSG" | grep -qi '\[MINOR\]'; then PART="minor" + elif echo "$MSG" | grep -qi '\[PATCH\]'; then PART="patch" + else PART="minor" fi + echo "Bump type: $PART" + echo "part=$PART" >> "$GITHUB_OUTPUT" - echo "Determined version bump type: $VERSION_BUMP" - echo "VERSION_BUMP=$VERSION_BUMP" >> $GITHUB_OUTPUT - - - name: Bump version - id: bump-version - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - BUMPVERSION_CONFIG_FILE: pyproject.toml + - name: Bump version and rotate CHANGELOG run: | - git config --global user.name 'github-actions' - git config --global user.email 'github-actions@github.com' - # Detect current version from __version__.py (authoritative for search) - OLD_VERSION=$(grep '^VERSION =' src/supervaizer/__version__.py | cut -d '"' -f2) - export OLD_VERSION - # Expose for downstream steps - echo "OLD_VERSION=${OLD_VERSION}" >> $GITHUB_OUTPUT - bump-my-version bump ${{ steps.version-bump-type.outputs.VERSION_BUMP }} \ + git config --global user.name 'github-actions[bot]' + git config --global user.email '41898282+github-actions[bot]@users.noreply.github.com' + bump-my-version bump ${{ steps.bump-type.outputs.part }} \ --config-file pyproject.toml \ --verbose git fetch origin main git rebase origin/main git push --follow-tags - # Store the new version - echo "NEW_VERSION=$(grep '^VERSION =' src/supervaizer/__version__.py | cut -d '"' -f2)" >> $GITHUB_OUTPUT - name: Install Hatch run: pip install hatch @@ -87,7 +78,7 @@ jobs: - name: Build package run: hatch build - - name: Publish to PyPI on main + - name: Publish to PyPI uses: pypa/gh-action-pypi-publish@release/v1 with: packages-dir: dist/ diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 52cb50e..ca11f84 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -5,9 +5,10 @@ name: Python package on: push: - branches: ["develop"] + branches: ["develop", "main"] pull_request: - branches: ["develop"] + branches: ["develop", "main"] + workflow_call: jobs: build: diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 02c86f2..a3ee4af 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -17,7 +17,7 @@ All notable changes to this project will be documented in this file. - example: here the 'How many times to say hello' is supposed to be an 'int'. - agent_simple:job_start:74 - AGENT ExampleAgent: Received kwargs: {'action': 'start', 'fields': {'How many times to say hello': '3'}, 'context': JobContext(workspace_id='odm', job_id='01KGM75NQ76AWBAXHXERW8FKHW', started_by='alp', started_at=datetime.datetime(2026, 2, 4, 11, 39, 0, 712598, tzinfo=TzInfo(0)), mission_id='01KGG50ZMFYMHG9N5FGCACF0XA', mission_name='Operate Agent Hello World AI Agent', mission_context=None, job_instructions=JobInstructions(max_cases=None, max_duration=None, max_cost=None, stop_on_warning=False, stop_on_error=True, job_start_time=None)), 'agent_parameters': [{'name': 'SIMPLE AGENT PARAMETER', 'team_id': 2, 'description': 'Setup agent parameter in this workspace', 'is_environment': True, 'value': '123456', 'is_secret': False, 'is_required': False}, {'name': 'SIMPLE AGENT SECRET', 'team_id': 2, 'description': 'Setup agent secret in this workspace', 'is_environment': True, 'value': '123456', 'is_secret': True, 'is_required': False}]} -## Unreleased +## [Unreleased] ### Added @@ -44,7 +44,7 @@ All notable changes to this project will be documented in this file. | 🔴 Failed | 0 | | ⏱️ in | ~70s | -## v0.13.1 +## [0.13.1] ### Added @@ -62,7 +62,7 @@ All notable changes to this project will be documented in this file. | 🔴 Failed | 0 | | ⏱️ in | 65s | -## v0.12.0 +## [0.12.0] ### Added @@ -86,7 +86,7 @@ All notable changes to this project will be documented in this file. - `AgentResponse` nested schemas not rebuilt after dependent models — added `AgentResponse.model_rebuild()` after `Case.model_rebuild()` in `supervaizer/__init__.py` - `CaseNode.factory` typed as `Callable` which cannot appear in JSON Schema — changed to `Any` (behaviour unchanged) -## v0.11.0 +## [0.11.0] - **Job Poll mechanism** — New optional `job_poll` method in `AgentMethods` for manual external service polling. When defined, the workbench shows a "Check for updates" button on active jobs. Clicking it calls the agent's poll handler, which checks external services (email inboxes, call status APIs, etc.) and updates cases accordingly. Enables local development without webhooks — production uses real-time webhooks, local mode uses the poll button. - `AgentMethods`: new `job_poll: AgentMethod | None` field @@ -153,7 +153,7 @@ All notable changes to this project will be documented in this file. | 🔴 Failed | 0 | | ⏱️ in | 50s | -## v0.10.19 +## [0.10.19] ### Added @@ -165,7 +165,7 @@ All notable changes to this project will be documented in this file. - **Admin index** – Simplified displayed information in the admin index template. - **CI** – PyPI publish workflow: added concurrency settings to cancel in-progress runs. -## v0.10.18 +## [0.10.18] ### Added @@ -175,7 +175,7 @@ All notable changes to this project will be documented in this file. - **Refactor** – Code formatting and trailing whitespace cleanup (admin routes, server, examples, tests, templates). -## v0.10.17 +## [0.10.17] ### Added @@ -201,7 +201,7 @@ All notable changes to this project will be documented in this file. | 🔴 Failed | 0 | | ⏱️ in | 53.16s | -## v0.10.11 +## [0.10.11] ### Added diff --git a/justfile b/justfile index e43f711..812764a 100644 --- a/justfile +++ b/justfile @@ -10,10 +10,9 @@ YYYYMMDD:= `date +%Y%m%d` default: @just --list -# Dev install -dev-install: - uv venv - uv pip install -e .[dev] +# Install dev dependencies +install-dev: + uv sync --extra dev # Run pre-commit hooks manually precommit: @@ -83,7 +82,7 @@ release-major: just _bump-version major # Push tags to remote -push-tags: +push_tags: git push origin --tags @echo "Tags pushed to remote" @@ -151,10 +150,23 @@ push-main: release: just merge-to-main just push-main - just push-tags + just push_tags just gh-release @echo "✅ Release complete! Main branch and tags pushed to remote" +# Ship to production: precommit, merge develop→main, push (CI does the version bump) +# Embed bump type token ([MINOR]/[PATCH]/[MAJOR]) so CI picks up the right part. +# Usage: just ship [patch|minor|major] +ship part="minor": + #!/usr/bin/env bash + set -euo pipefail + just precommit + BUMP_TOKEN=$(echo "{{part}}" | tr '[:lower:]' '[:upper:]') + git checkout main + git pull origin main + git merge develop --no-ff -m "[${BUMP_TOKEN}] chore: merge develop to main" + git push origin main + # Create or update GitHub release for the latest tag on origin/main gh-release: bash tools/gh-release-latest-tag.sh supervaize/supervaizer diff --git a/pyproject.toml b/pyproject.toml index 7f81d74..218d9a2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -131,7 +131,7 @@ commit = true tag = true tag_name = "v{new_version}" tag_message = "Release {new_version}" -message = "Bump version: {current_version} → {new_version}" +message = "chore(release): v{new_version}" # Optional .devN is stripped on bump (CI publishes X.Y.Z only); use `just version-dev on` locally. parse = "(?P\\d+)\\.(?P\\d+)\\.(?P\\d+)(\\.dev(?P\\d+))?" serialize = ["{major}.{minor}.{patch}"] @@ -145,3 +145,8 @@ replace = 'VERSION = "{new_version}"' filename = "pyproject.toml" search = 'current_version = "{current_version}"' replace = 'current_version = "{new_version}"' + +[[tool.bumpversion.files]] +filename = "docs/CHANGELOG.md" +search = "## [Unreleased]" +replace = "## [Unreleased]\n\n## [{new_version}] - {now:%Y-%m-%d}" From 2e08da99d8f42cb400d73edf2697df62d664b84d Mon Sep 17 00:00:00 2001 From: Alain Prasquier Date: Tue, 14 Apr 2026 00:03:12 +0300 Subject: [PATCH 2/2] =?UTF-8?q?=E2=9C=A8=20chore:=20update=20CI,=20docs,?= =?UTF-8?q?=20and=20release=20steps-=20Update=20publish-pypi=20workflow=20?= =?UTF-8?q?to=20rebase=20local=20main=20before=20bumping=20version=20to=20?= =?UTF-8?q?avoid=20stale=20refs=20and=20ensure=20bump-my-version=20operate?= =?UTF-8?q?s=20on=20up-date=20history.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove redundant git fetch/re after bump and push --follow-tags. - Narrow python-package workflow to trigger pushes only on develop to prevent accidental builds from main; keep PR triggers for develop/main. - Standard developer install instructions replace ad-h invocations with just install-dev in CONTRIBUTING and GEMINI to match current Justfile and simplify onboarding. Rationale: - Prevent release failures caused by out-of-date main in CI and reduce git operations. - Align repository docs with actual tooling and minimize confusion for contributors. --- .github/workflows/publish-pypi.yml | 3 +-- .github/workflows/python-package.yml | 2 +- CONTRIBUTING.md | 2 +- GEMINI.md | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index f9ca8c1..df967a9 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -65,11 +65,10 @@ jobs: run: | git config --global user.name 'github-actions[bot]' git config --global user.email '41898282+github-actions[bot]@users.noreply.github.com' + git pull --rebase origin main bump-my-version bump ${{ steps.bump-type.outputs.part }} \ --config-file pyproject.toml \ --verbose - git fetch origin main - git rebase origin/main git push --follow-tags - name: Install Hatch diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index ca11f84..eeb5051 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -5,7 +5,7 @@ name: Python package on: push: - branches: ["develop", "main"] + branches: ["develop"] pull_request: branches: ["develop", "main"] workflow_call: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d6e3079..fe8114b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -18,7 +18,7 @@ just -l - `uv venv` - Windows: `.venv\Scripts\activate` - Unix/MacOS: `source .venv/bin/activate` -4. Install development dependencies: `uv pip install -e ".[dev]"` or `just dev-install` +4. Install development dependencies: `just install-dev` 5. Install Git hooks: `just install-hooks` ### Running Tests diff --git a/GEMINI.md b/GEMINI.md index 16e02a9..29d9845 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -7,7 +7,7 @@ This is a Python project that provides a toolkit for building, managing, and con The project's dependencies are listed in the `pyproject.toml` file. To install them, you can use the `just` command: ```bash -just dev-install +just install-dev ``` **2. Scaffolding:**