diff --git a/.github/release.yml b/.github/release.yml new file mode 100644 index 00000000..8cb88251 --- /dev/null +++ b/.github/release.yml @@ -0,0 +1,8 @@ +changelog: + categories: + - title: Changes + labels: ["*"] + exclude: + labels: ["dependencies"] + - title: Dependencies + labels: ["dependencies"] diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index 55860ba2..600c2906 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -3,8 +3,9 @@ name: Publish to PyPI # On a release tag, uploads agentenv-framework-protocol and then agentenv-framework to PyPI through trusted # publishing, so no token is stored anywhere. Each job builds its distribution the way the release does # (agentenv-framework pinned to the exact agentenv-framework-protocol it was released with) and runs in its own -# environment, because PyPI binds a pending publisher to one workflow and environment per project. Files already on -# PyPI are skipped, so a rerun is safe. +# environment, because PyPI binds a pending publisher to one workflow and environment per project. Once both are on +# PyPI, it creates the tag's GitHub release, whose notes list the pull requests merged since the previous tag. Files +# already on PyPI and a release that already exists are skipped, so a rerun is safe. on: push: @@ -70,3 +71,35 @@ jobs: run: uvx --index-url https://pypi.org/simple twine check --strict dist/* - name: Publish agentenv-framework run: uv publish --trusted-publishing always --check-url https://pypi.org/simple/ dist/* + + release: + needs: framework + runs-on: ubuntu-latest + timeout-minutes: 5 + permissions: + contents: write + steps: + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + with: + fetch-depth: 0 + persist-credentials: false + - name: Create the GitHub release, with notes from the pull requests since the previous tag + env: + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} + run: | + tag="${GITHUB_REF_NAME}" + if gh release view "$tag" >/dev/null 2>&1; then + echo "Release ${tag} already exists." + exit 0 + fi + framework="${tag#v}" + protocol=$(sed -n 's/^version = "\(.*\)"/\1/p' packages/agentenv-protocol/pyproject.toml) + header="On PyPI: [agentenv-framework ${framework}](https://pypi.org/project/agentenv-framework/${framework}/) ยท [agentenv-framework-protocol ${protocol}](https://pypi.org/project/agentenv-framework-protocol/${protocol}/)" + args=(--verify-tag --title "$tag" --generate-notes --notes "$header") + # Without a start tag, GitHub counts from the previous release rather than the previous tag. + previous=$(git tag --list 'v*' --sort=-v:refname | grep -A1 -x "$tag" | sed -n 2p) + if [ -n "$previous" ]; then + args+=(--notes-start-tag "$previous") + fi + gh release create "$tag" "${args[@]}" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e503f573..3ee3ff19 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -81,7 +81,9 @@ Every pull request needs an approving review from a code owner (see `CODEOWNERS` Maintainers cut releases. Version bumps are automated when a labelled pull request merges, so contributors should not edit `version` in `pyproject.toml`. Each release publishes `agentenv-framework` and `agentenv-framework-protocol` to PyPI (`.github/workflows/publish-pypi.yml`, trusted publishing -on the release tag); the import package `agent_env` and the command `agent-env` keep their names. +on the release tag); the import package `agent_env` and the command `agent-env` keep their names. Once both are +on PyPI, the same workflow creates the GitHub release, whose notes are the titles of the pull requests merged since +the previous tag, so a clear pull request title is also the release note. ## Getting help diff --git a/README.md b/README.md index 5c733f5c..b794ba14 100644 --- a/README.md +++ b/README.md @@ -348,7 +348,7 @@ The `agentenv-framework` distribution and `agentenv-framework-protocol` are vers ### Releases -A release is a version bump in both `pyproject.toml` files plus a `vX.Y.Z` tag. Maintainers cut releases: the bump is automated when a labelled pull request merges, so contributors do not edit `version` or push tags (see the Releases section of [CONTRIBUTING.md](https://github.com/scaleapi/agentenv-framework/blob/main/CONTRIBUTING.md)). Each release publishes both packages to PyPI; there is no `CHANGELOG.md`. +A release is a version bump in both `pyproject.toml` files plus a `vX.Y.Z` tag. Maintainers cut releases: the bump is automated when a labelled pull request merges, so contributors do not edit `version` or push tags (see the Releases section of [CONTRIBUTING.md](https://github.com/scaleapi/agentenv-framework/blob/main/CONTRIBUTING.md)). Each release publishes both packages to PyPI and gets a [GitHub release](https://github.com/scaleapi/agentenv-framework/releases) whose notes list the pull requests merged since the previous one; there is no `CHANGELOG.md`. ### Support, security, license diff --git a/packages/agentenv-protocol/pyproject.toml b/packages/agentenv-protocol/pyproject.toml index 07864dfd..1cc596cb 100644 --- a/packages/agentenv-protocol/pyproject.toml +++ b/packages/agentenv-protocol/pyproject.toml @@ -45,6 +45,7 @@ Homepage = "https://www.agentenvframework.com" Documentation = "https://www.agentenvframework.com/docs" Repository = "https://github.com/scaleapi/agentenv-framework/tree/main/packages/agentenv-protocol" Issues = "https://github.com/scaleapi/agentenv-framework/issues" +Changelog = "https://github.com/scaleapi/agentenv-framework/releases" [build-system] requires = ["hatchling"] diff --git a/pyproject.toml b/pyproject.toml index f743d2de..ec122d69 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -83,6 +83,7 @@ Homepage = "https://www.agentenvframework.com" Documentation = "https://www.agentenvframework.com/docs" Repository = "https://github.com/scaleapi/agentenv-framework" Issues = "https://github.com/scaleapi/agentenv-framework/issues" +Changelog = "https://github.com/scaleapi/agentenv-framework/releases" [tool.hatch.build.targets.wheel] packages = ["src/agent_env"]