diff --git a/AGENTS.md b/AGENTS.md index 6af9dd9..0f4b15b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -90,9 +90,15 @@ release sections. ## Releases -Follow `RELEASING.md`. Agents may prepare release notes and validate a release, -but must not create tags, releases, documentation deployments, or package -publications without explicit human approval. +Follow `RELEASING.md` for the full checklist. The routine order is: merge the +approved release PR, confirm the exact version tag resolves to its merge +commit, obtain explicit approval for the tag-triggered package publication, +then create a public GitHub Release from that existing tag with concise +changelog-based notes. Verify that the release is neither a draft nor a +prerelease and that its tag still resolves to the expected commit. Agents may +prepare release notes and validate a release, but must not create tags, +releases, documentation deployments, or package publications without explicit +human approval. ## Change Guidelines diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c5f9627..78072e2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -51,80 +51,6 @@ The documentation site is automatically built by a [GitHub Actions workflow](htt ## Releasing -Follow [RELEASING.md](RELEASING.md) before using the walkthrough below. - -# Releasing - -Our release process is automated as a [continuous deployment](https://en.wikipedia.org/wiki/Continuous_deployment) via the [GitHub Actions](https://github.com/features/actions) framework. The logic that governs the process is stored in the `workflows` directory. - -That means that everything necessary to make a release can be done with a few clicks on the GitHub website. All you need to do is make a [tagged release](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository), then wait for the computers to handle the job. - -Before you can begin, you have to do the following one-time configuration: - -* On PyPI, [add a trusted publisher](https://docs.pypi.org/trusted-publishers/adding-a-publisher/) for this GitHub repository and `.github/workflows/continuous-deployment.yaml`. Leave the environment name blank unless you add one to the workflow. - -Once that is done, you can automatically release new versions. Here’s how to do it, step by step. The screenshots are from a different repository, but the process is the same. - -## 1. Go to the releases page - -The first step is to visit your repository's homepage and click on the "releases" headline in the right rail. - -![Release button](https://raw.githubusercontent.com/palewire/python-open-source-template/main/.github/images/releasing-releases-button.png) - -## 2. Click 'Draft a new release' - -Note the number of the latest release. Click the "Draft a new release" button in the upper-right corner. If you don't see this button, you do not have permission to make a release. Only the maintainers of the repository are able to release new code. - -![Draft button](https://raw.githubusercontent.com/palewire/python-open-source-template/main/.github/images/releasing-draft-button.png) - -## 3. Create a new tag - -Think about how big your changes are and decide if you're a major, minor or patch release. - -All version numbers should feature three numbers separated by the periods, like `1.0.1`. If you're making a major release that isn't backwards compatible, the latest release’s first number should go up by one. If you're making a minor release by adding a feature or major a large change, the second number should go up. If you're only fixing bugs or making small changes, the third number should go up. - -If you're unsure, review the standards defined at [semver.org](https://semver.org) to help make a decision. In the end don't worry about it too much. Our version numbers don't need to be perfect. They just need to be three numbers separated by periods. - -Once you've settled on the number for your new release, click on the "Choose a tag" pull down. - -![Tag button](https://raw.githubusercontent.com/palewire/python-open-source-template/main/.github/images/releasing-tag-button.png) - -Enter your version number into the box. Then click the "Create new tag" option that appears. - -![Tag dropdown](https://raw.githubusercontent.com/palewire/python-open-source-template/main/.github/images/releasing-name-tag.png) - -## 4. Name the release - -Enter the same number into the "Release title" box. - -![Name box](https://raw.githubusercontent.com/palewire/python-open-source-template/main/.github/images/releasing-name-release.png) - -## 5. Auto-generate release notes - -Click the "Auto-generate release notes" button in the upper right corner of the large description box. - -![Auto-generate release notes button](https://raw.githubusercontent.com/palewire/python-open-source-template/main/.github/images/releasing-changelog-button.png) - -That should fill in the box below. What appears will depend on how many pull requests you've merged since the last release. - -![Auto-generate release notes results](https://raw.githubusercontent.com/palewire/python-open-source-template/main/.github/images/releasing-changelog-entered.png) - -## 6. Publish the release - -Click the green button that says "Publish release" at the bottom of the page. - -![Publish button](https://raw.githubusercontent.com/palewire/python-open-source-template/main/.github/images/releasing-publish-button.png) - -## 7. Wait for the Action to finish - -GitHub will take you to a page dedicated to your new release and start an automated process that release our new version to the world. Follow its progress by clicking on the Actions tab near the top of the page. - -![Release page](https://raw.githubusercontent.com/palewire/python-open-source-template/main/.github/images/releasing-release-published.png) - -That will take you to the Actions monitoring page. The task charged with publishing your release should be at the top. - -![Actions page](https://raw.githubusercontent.com/palewire/python-open-source-template/main/.github/images/releasing-actions-start.png) - -After a few minutes, the process there should finish and show a green check mark. When it does, visit your package’s page on [PyPI](https://pypi.org/), where you should see the latest version displayed at the top of the page. - -If the action fails, something has gone wrong with the deployment process. You can click into its debugging panel to search for the cause or ask the project maintainers for help. +Follow [RELEASING.md](RELEASING.md), including its post-merge GitHub Release +follow-up. The continuous deployment workflow publishes the package when the +exact version tag is pushed. diff --git a/RELEASING.md b/RELEASING.md index a2d6bb7..94d3352 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -17,10 +17,53 @@ Git tags through `setuptools-scm`; do not edit a version file. dated version section. - [ ] Choose a major, minor, or patch version according to Semantic Versioning. - [ ] Obtain explicit human approval for the version and release. -- [ ] Create the matching Git tag and GitHub release. +- [ ] Merge the approved release PR. +- [ ] With explicit human approval, create or confirm the exact version tag on + the release PR's merge commit to trigger package publication. - [ ] Confirm the release workflow published the expected package to PyPI. +- [ ] Complete the post-merge GitHub Release follow-up below. - [ ] Confirm the documentation workflow deployed the matching Sphinx site. +## Post-merge GitHub Release Follow-up + +Do not create the GitHub Release until the release PR has merged, the exact +version tag exists, and the approved package publication has completed. The tag +must point to the expected merge commit. Creating a tag, publishing a package, +or creating a release still requires explicit human approval. + +1. Record the release PR's merge commit and confirm the exact tag resolves to + it: + + ```sh + VERSION=2.0.1 + EXPECTED_COMMIT= + git fetch origin --tags + test "$(git rev-parse "${VERSION}^{commit}")" = "$EXPECTED_COMMIT" + ``` + +2. Prepare concise release notes from the matching version section in + `CHANGELOG.md`. After the package publication succeeds and with explicit + human approval, create the GitHub Release from the existing tag: + + ```sh + gh release create "$VERSION" \ + --verify-tag \ + --title "$VERSION" \ + --notes-file /path/to/release-notes.md + ``` + + The GitHub UI may be used instead, but select the existing tag and publish + the release rather than creating a draft or prerelease. + +3. Verify that the public release uses the expected tag and commit: + + ```sh + test "$(gh release view "$VERSION" --json tagName --jq .tagName)" = "$VERSION" + test "$(gh release view "$VERSION" --json isDraft,isPrerelease \ + --jq '(.isDraft == false and .isPrerelease == false)')" = "true" + test "$(git rev-parse "${VERSION}^{commit}")" = "$EXPECTED_COMMIT" + ``` + ## Documentation Deployment Package documentation lives in this repository under `docs/`. The