From 44d5a877a1b67fe217b9e822efa1517cfb71c94f Mon Sep 17 00:00:00 2001 From: Nathan Baker Date: Sat, 12 Sep 2026 15:39:23 -0700 Subject: [PATCH] Consolidate release automation --- .github/workflows/build.yaml | 102 +++++++++++++++++++++++++-------- .github/workflows/release.yaml | 59 ------------------- docs/release_procedure.md | 89 ++++++++++++++-------------- 3 files changed, 122 insertions(+), 128 deletions(-) delete mode 100644 .github/workflows/release.yaml diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index a0ec65ae..fbe2cebb 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -216,7 +216,7 @@ jobs: shell: bash - name: Create package for Mac and Linux - if: matrix.create-package && startsWith(matrix.os, 'macos') || startswith(matrix.os, 'ubuntu') # Mac or Linux only + if: matrix.create-package && (startsWith(matrix.os, 'macos') || startsWith(matrix.os, 'ubuntu')) # Mac or Linux only id: cpack-ml run: | cd build @@ -329,7 +329,7 @@ jobs: # shell: bash - name: Download artifacts - uses: actions/download-artifact@v4.1.7 + uses: actions/download-artifact@v8.0.1 with: name: ${{ matrix.package_file }} @@ -360,43 +360,95 @@ jobs: # uses: mxschmitt/action-tmate@v3 + validate-release: + name: Validate Release Inputs + + needs: [build, test] + + runs-on: ubuntu-22.04 + + steps: + + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Prepare release notes + run: | + version="$(grep -E '^[0-9]+_[0-9]+_[0-9]+' VERSION | sed 's/_/./g')" + if [[ "${GITHUB_REF}" == refs/tags/* && "${GITHUB_REF_NAME}" != "v${version}" ]]; then + echo "Tag ${GITHUB_REF_NAME} does not match VERSION v${version}." >&2 + exit 1 + fi + ./.extract_section.sh -v "${version}" -f docs/releases.rst > this_release.rst + if [[ ! -s this_release.rst ]]; then + echo "No release notes found for version ${version}." >&2 + exit 1 + fi + shell: bash + + - name: Convert release notes to Markdown + uses: docker://pandoc/core:2.16.2 + with: + args: >- + --standalone + --from rst + --to markdown + --output=this_release.md + this_release.rst + + - name: Download artifacts + uses: actions/download-artifact@v8.0.1 + with: + pattern: APBS-* + path: release-artifacts + merge-multiple: true + + - name: Verify release artifacts + run: | + artifact_count="$(find release-artifacts -maxdepth 1 -name 'APBS-*.zip' | wc -l | tr -d ' ')" + if [[ "${artifact_count}" != "3" ]]; then + echo "Expected 3 release ZIP files, found ${artifact_count}." >&2 + find release-artifacts -maxdepth 2 -type f -print + exit 1 + fi + cp this_release.md release-artifacts/ + shell: bash + + - name: Store release candidate + uses: actions/upload-artifact@v7 + with: + name: release-candidate + path: release-artifacts + if-no-files-found: error + retention-days: 5 + release: name: Publish Release Artifacts - needs: [build, test] + needs: validate-release - if: startswith(github.ref, 'refs/tags/') # Tag/release only + if: startsWith(github.ref, 'refs/tags/v') - runs-on: ${{ matrix.os }} + runs-on: ubuntu-22.04 - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest, macOS-latest, windows-latest] - include: - - os: ubuntu-latest - package_file: ${{ needs.build.outputs.cpack-out-lin-zip }} - - os: macOS-latest - package_file: ${{ needs.build.outputs.cpack-out-mac-zip }} - - os: windows-latest - package_file: ${{ needs.build.outputs.cpack-out-win-zip }} + permissions: + contents: write steps: - - name: Download artifacts - uses: actions/download-artifact@v4.1.7 + - name: Download release candidate + uses: actions/download-artifact@v8.0.1 with: - name: ${{ matrix.package_file }} + name: release-candidate + path: release-candidate - name: Release artifacts - uses: softprops/action-gh-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }} + uses: softprops/action-gh-release@v3 with: - files: | - ${{ matrix.package_file }} + body_path: release-candidate/this_release.md + files: release-candidate/APBS-*.zip fail_on_unmatched_files: true - tag_name: ${{ needs.build.outputs.apbs-tag }} + tag_name: ${{ github.ref_name }} # For debugging # - name: Setup tmate session diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml deleted file mode 100644 index 46ab0c95..00000000 --- a/.github/workflows/release.yaml +++ /dev/null @@ -1,59 +0,0 @@ -name: Tag and Release - -on: - push: - branches: [ release ] - - workflow_dispatch: - -permissions: - contents: read - -jobs: - - Release: - - runs-on: ubuntu-22.04 - - steps: - - - name: Checkout the repo - uses: actions/checkout@v4 - - - name: Extract version - run: | - version="$(grep -E '^[0-9]+_[0-9]+_[0-9]+' VERSION | sed 's/_/./g')" - echo $version - echo "apbs-version=${version}" >> "$GITHUB_OUTPUT" - echo "apbs-tag=v${version}" >> "$GITHUB_OUTPUT" - ./.extract_section.sh -v ${version} -f docs/releases.rst > this_release.rst - cat this_release.rst - shell: bash - id: extract-version - - - name: Convert release text to markdown - uses: docker://pandoc/core:2.16.2 - with: - args: >- - --standalone - --from rst - --to markdown - --output=this_release.md - this_release.rst - - - name: Check release text - run: cat this_release.md - - - name: Create tag - uses: tvdias/github-tagger@v0.0.1 - with: - repo-token: "${{ secrets.RELEASE_TOKEN }}" - tag: ${{ steps.extract-version.outputs.apbs-tag }} - - - name: Create Release - uses: softprops/action-gh-release@v2 - env: - GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }} - with: - body_path: this_release.md - tag_name: ${{ steps.extract-version.outputs.apbs-tag }} diff --git a/docs/release_procedure.md b/docs/release_procedure.md index 4131d568..67c5771e 100644 --- a/docs/release_procedure.md +++ b/docs/release_procedure.md @@ -1,44 +1,45 @@ -APBS Release Procedure ------------------------ - 1. Change Version Number - - [ ] Edit [VERSION]([https://github.com/Electrostatics/apbs/blob/main/apbs/VERSION) - Increment the value after the comment block, which is in the form - M_m_u - Where: - - M is the Major version - increment if there are breaking changes or dropping support for previous features - - m is the Minor version - increment for new features added - - u is the Micro version - increment for adding small changes like new tests or fixing small bugs - - 2. Update the Releases document - - [ ] Edit [docs/releases.rst]([https://github.com/Electrostatics/apbs/blob/main/apbs/docs/releases.rst) - - Document major/minor changes for this release - - 3. Update License info - - [ ] Update license dates and information in source files - - In apbs/src edit all .c source files and all .h header files, update dates - - 4. Create a Pull Request (PR) - - [ ] Create a new [Pull Request](https://github.com/Electrostatics/apbs/pulls) - - Base branch should be `release` - - Source branch should be `main` - - Briefly describe the changes included - - 5. Check tests - - Go to the [Actions](https://github.com/Electrostatics/apbs/actions) tab in GitHub - - Tests are performed for three target platforms: - - Ubuntu - - MacOSX - - Windows - - [ ] Ensure that the builds and associated tests were successful - - [ ] Ensure that the use tests were successful - - [ ] Ensure that the build artifacts were uploaded to the action - - 6. Merge the PR - - [ ] Ensure that the [Release](https://github.com/Electrostatics/apbs/releases) is correctly created - - [ ] Ensure that the builds and associated tests were successful - - [ ] Ensure that the use tests were successful - - [ ] Ensure that the build artifacts were uploaded to the Release - - 7. Update http://www.poissonboltzmann.org/apbs/release-history with new release information. - - 8. Pat yourself on the back for a job well done! +# APBS release procedure + +## 1. Prepare the release + +- Update `VERSION`. The value uses `MAJOR_MINOR_PATCH` format. +- Add the release notes to `docs/releases.rst` under a heading matching the new + version. +- Update copyright or license dates only where they are no longer accurate. +- Open and merge a pull request into `main`. + +## 2. Run a package dry run + +- Open the **Build APBS** workflow in GitHub Actions. +- Select **Run workflow** on `main`. +- Confirm that all compile, CTest, package, and packaged-example jobs pass for + Ubuntu, macOS, and Windows. +- Confirm that **Validate Release Inputs** succeeds. +- Download the `release-candidate` artifact and inspect its release notes and + three ZIP packages. + +Manual workflow runs never publish a GitHub release. + +## 3. Publish the release + +After the package dry run passes, create an annotated tag at the tested `main` +commit. The tag must match `VERSION`; for example, `VERSION` value `3_5_0` +requires tag `v3.5.0`. + +```shell +git switch main +git pull --ff-only +git tag -a v3.5.0 -m "APBS 3.5.0" +git push origin v3.5.0 +``` + +The tag starts the same three-platform build, test, package, and packaged-example +jobs. After they pass, the workflow creates the GitHub release, converts the +matching section of `docs/releases.rst` to Markdown, and attaches all three ZIP +packages. + +## 4. Verify publication + +- Confirm that the GitHub release notes and all three ZIP assets are present. +- Download and inspect each published archive. +- Update the APBS release history on `www.poissonboltzmann.org`.