MODFLOW 6 release dispatch #226
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: MODFLOW 6 release dispatch | |
| on: | |
| push: | |
| branches: | |
| # initial phase of the release procedure is triggered by pushing a release branch | |
| - v[0-9]+.[0-9]+.[0-9]+* | |
| # intermediate phase is triggered by merging the release branch to master | |
| - master | |
| # final phase is triggered by promoting/publishing a GitHub release draft to a full release | |
| release: | |
| types: | |
| - published | |
| # workflow_dispatch trigger to start release via GitHub UI or CLI, | |
| # as an alternative to triggering when a release branch is pushed. | |
| # see https://docs.github.com/en/actions/managing-workflow-runs/manually-running-a-workflow | |
| workflow_dispatch: | |
| inputs: | |
| branch: | |
| description: 'Branch to release from.' | |
| required: true | |
| type: string | |
| compiler_toolchain: | |
| description: 'Compiler toolchain to use. For supported options see https://github.com/MODFLOW-ORG/modflow6/blob/develop/DEVELOPER.md#compiler-compatibility.' | |
| required: false | |
| type: string | |
| default: 'intel-classic' | |
| compiler_version: | |
| description: 'Compiler version to use. For supported options see https://github.com/MODFLOW-ORG/modflow6/blob/develop/DEVELOPER.md#compiler-compatibility.' | |
| required: false | |
| type: string | |
| default: '2021.6' | |
| releasemode: | |
| description: 'Build a full distribution containing sources, examples, and all documentation. If false, the distribution contains only binaries, mf6io, release notes, and code.json, with binaries built in develop mode, and disclaimers & version strings indicating preliminary/provisional status. If true, a full distribution is created, with binaries built in release mode, and disclaimer language indicating review and approval.' | |
| required: false | |
| type: boolean | |
| default: false | |
| run_tests: | |
| description: 'Run tests after building binaries.' | |
| required: false | |
| type: boolean | |
| default: true | |
| version: | |
| description: 'Version number to use for release.' | |
| required: true | |
| type: string | |
| patch: | |
| description: 'Create a patch release. If true, only bug fixes will be included in generated documentation.' | |
| required: false | |
| type: boolean | |
| default: false | |
| jobs: | |
| set_options: | |
| name: Set release options | |
| if: github.ref_name != 'master' | |
| runs-on: ubuntu-22.04 | |
| defaults: | |
| run: | |
| shell: bash -l {0} | |
| outputs: | |
| branch: ${{ steps.set_branch.outputs.branch }} | |
| compiler_toolchain: ${{ steps.set_compiler.outputs.compiler_toolchain }} | |
| compiler_version: ${{ steps.set_compiler.outputs.compiler_version }} | |
| version: ${{ steps.set_version.outputs.version }} | |
| patch: ${{ steps.set_patch.outputs.patch }} | |
| steps: | |
| - name: Checkout modflow6 | |
| uses: actions/checkout@v6 | |
| with: | |
| repository: ${{ github.repository_owner }}/modflow6 | |
| ref: ${{ github.ref }} | |
| - name: Set branch | |
| id: set_branch | |
| run: | | |
| # if branch was provided explicitly via workflow_dispatch, use it | |
| if [[ ("${{ github.event_name }}" == "workflow_dispatch") && (-n "${{ inputs.branch }}") ]]; then | |
| branch="${{ inputs.branch }}" | |
| # prevent releases from master | |
| if [[ "$branch" == "master" ]]; then | |
| echo "error: releases may not be triggered from branch $branch" | |
| exit 1 | |
| fi | |
| echo "using branch $branch from workflow_dispatch" | |
| elif [[ ("${{ github.event_name }}" == "push") && ("${{ github.ref_name }}" != "master") ]]; then | |
| # if release was triggered by pushing a release branch, use that branch | |
| branch="${{ github.ref_name }}" | |
| echo "using branch $branch from ref ${{ github.ref }}" | |
| else | |
| # otherwise exit with an error | |
| echo "error: this workflow should not have triggered for event ${{ github.event_name }} on branch ${{ github.ref_name }}" | |
| exit 1 | |
| fi | |
| echo "branch=$branch" >> $GITHUB_OUTPUT | |
| - name: Set compiler | |
| id: set_compiler | |
| run: | | |
| # if compiler toolchain was provided explicitly via workflow_dispatch, use it | |
| if [[ ("${{ github.event_name }}" == "workflow_dispatch") && (-n "${{ inputs.compiler_toolchain }}") ]]; then | |
| compiler_toolchain="${{ inputs.compiler_toolchain }}" | |
| compiler_version="${{ inputs.compiler_version }}" | |
| echo "using compiler toolchain $compiler_toolchain version $compiler_version from workflow_dispatch" | |
| elif [[ ("${{ github.event_name }}" == "push") && ("${{ github.ref_name }}" != "master") ]]; then | |
| # if release was triggered by pushing a release branch, use the default toolchain and version | |
| compiler_toolchain="intel-classic" | |
| compiler_version="2021.6" | |
| echo "using default compiler toolchain $compiler_toolchain version $compiler_version" | |
| else | |
| # otherwise exit with an error | |
| echo "error: this workflow should not have triggered for event ${{ github.event_name }} on branch ${{ github.ref_name }}" | |
| exit 1 | |
| fi | |
| echo "compiler_toolchain=$compiler_toolchain" >> $GITHUB_OUTPUT | |
| echo "compiler_version=$compiler_version" >> $GITHUB_OUTPUT | |
| - name: Set version | |
| id: set_version | |
| run: | | |
| # if version number was provided explicitly via workflow_dispatch, use it | |
| if [[ ("${{ github.event_name }}" == "workflow_dispatch") && (-n "${{ inputs.version }}") ]]; then | |
| ver="${{ inputs.version }}" | |
| echo "using version number $ver from workflow_dispatch" | |
| elif [[ ("${{ github.event_name }}" == "push") && ("${{ github.ref_name }}" != "master") ]]; then | |
| # if release was triggered by pushing a release branch, parse version number from branch name (sans leading 'v') | |
| ref="${{ github.ref_name }}" | |
| ver="${ref#"v"}" | |
| echo "parsed version number $ver from branch name $ref" | |
| else | |
| # otherwise exit with an error | |
| echo "error: version number not provided explicitly (via workflow_dispatch input) or implicitly (via branch name)" | |
| exit 1 | |
| fi | |
| echo "version=$ver" >> $GITHUB_OUTPUT | |
| - name: Set patch | |
| id: set_patch | |
| run: | | |
| # if patch was provided explicitly via workflow_dispatch, use it | |
| if [[ ("${{ github.event_name }}" == "workflow_dispatch") && (-n "${{ inputs.patch }}") ]]; then | |
| patch="${{ inputs.patch }}" | |
| echo "using patch setting $patch from workflow_dispatch" | |
| elif [[ ("${{ github.event_name }}" == "push") && ("${{ github.ref_name }}" != "master") ]]; then | |
| # if release was triggered by pushing a release branch, check the version against the latest | |
| # tag on master to determine if this is a patch release | |
| latest_tag=$(git ls-remote --tags origin "6.*" | awk -F/ '{print $3}' | sort -V | tail -n1) | |
| echo "latest version on master is $latest_tag" | |
| IFS='.' read -r -a latest_parts <<< "$latest_tag" | |
| IFS='.' read -r -a new_parts <<< "${{ steps.set_version.outputs.version }}" | |
| if [[ ${#latest_parts[@]} -ne 3 || ${#new_parts[@]} -ne 3 ]]; then | |
| echo "error: version number is not in major.minor.patch format" | |
| exit 1 | |
| fi | |
| if [[ ${latest_parts[0]} -ne ${new_parts[0]} || ${latest_parts[1]} -ne ${new_parts[1]} ]]; then | |
| patch="false" | |
| echo "major or minor version has changed, not a patch release" | |
| elif [[ ${latest_parts[2]} -lt ${new_parts[2]} ]]; then | |
| patch="true" | |
| echo "patch version has changed, this is a patch release" | |
| fi | |
| else | |
| # otherwise exit with an error | |
| echo "error: this workflow should not have triggered for event ${{ github.event_name }} on branch ${{ github.ref_name }}" | |
| exit 1 | |
| fi | |
| echo "patch=$patch" >> $GITHUB_OUTPUT | |
| make_dist: | |
| name: Make distribution | |
| uses: wpbonelli/modflow6/.github/workflows/release.yml@ci | |
| needs: set_options | |
| with: | |
| # If the workflow is manually triggered, the maintainer must manually set approve=true to approve a release. | |
| # If triggered by pushing a release branch, the release is approved if the branch name doesn't contain "rc". | |
| compiler_toolchain: ${{ needs.set_options.outputs.compiler_toolchain }} | |
| compiler_version: ${{ needs.set_options.outputs.compiler_version }} | |
| branch: ${{ needs.set_options.outputs.branch }} | |
| # If the workflow is manually triggered, the maintainer must manually set releasemode to true, otherwise the default is false. | |
| # If triggered by pushing a release branch, the release is developmode if the branch name contains "rc", otherwise releasemode. | |
| releasemode: ${{ (github.event_name == 'workflow_dispatch' && inputs.releasemode == 'true') || github.event_name != 'workflow_dispatch' }} | |
| # If the workflow is manually triggered, the maintainer must manually set run_tests to false, otherwise the default is true. | |
| # If triggered by pushing a release branch, tests are enabled. | |
| run_tests: ${{ (github.event_name == 'workflow_dispatch' && inputs.run_tests == 'true') || github.event_name != 'workflow_dispatch' }} | |
| version: ${{ needs.set_options.outputs.version }} | |
| patch: ${{ (github.event_name == 'workflow_dispatch' && inputs.patch == 'true') || (github.event_name != 'workflow_dispatch' && needs.set_options.outputs.patch == 'true') }} | |
| pr: | |
| name: Draft release PR | |
| if: ${{ github.ref_name != 'master' && ((github.event_name == 'workflow_dispatch' && inputs.releasemode == 'true') || (github.event_name != 'workflow_dispatch' && !contains(github.ref_name, 'rc'))) }} | |
| needs: | |
| - set_options | |
| - make_dist | |
| runs-on: ubuntu-22.04 | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| defaults: | |
| run: | |
| shell: bash -l {0} | |
| steps: | |
| - name: Checkout modflow6 | |
| uses: actions/checkout@v6 | |
| with: | |
| repository: ${{ github.repository_owner }}/modflow6 | |
| ref: ${{ github.ref }} | |
| - name: Setup Micromamba | |
| uses: mamba-org/setup-micromamba@v1 | |
| with: | |
| environment-file: environment.yml | |
| cache-downloads: true | |
| cache-environment: true | |
| - name: Update version | |
| working-directory: distribution | |
| run: | | |
| # update version files | |
| ver="${{ needs.set_options.outputs.version }}" | |
| # approve will be empty if workflow was triggered by pushing a release branch | |
| # todo: pull approve into set_options job/output? | |
| if [[ ("${{ inputs.releasemode }}" == "true") || ("${{ inputs.releasemode }}" == "") ]]; then | |
| python update_version.py -v "$ver" --releasemode | |
| else | |
| python update_version.py -v "$ver" | |
| fi | |
| # lint version.f90 | |
| fprettify -c ../.fprettify.yaml ../src/Utilities/version.f90 | |
| # commit and push | |
| git config core.sharedRepository true | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| git add -A | |
| git commit -m "ci(release): update version to $ver" | |
| git push origin "${{ github.ref }}" | |
| - name: Create pull request | |
| env: | |
| GITHUB_TOKEN: ${{ github.token }} | |
| run: | | |
| ver="${{ needs.set_options.outputs.version }}" | |
| body=' | |
| # MODFLOW '$ver' release | |
| The release can be approved by merging this PR into `master`. Merging rather than squashing is necessary to preserve the commit history. | |
| When this PR is merged, a final job will be triggered to draft a tagged GitHub release, then upload assets (OS distributions and release notes). | |
| ' | |
| gh pr create -B "master" -H "${{ github.ref }}" --title "Release $ver" --draft --body "$body" | |
| release: | |
| name: Draft release | |
| # runs only after release PR is merged to master | |
| if: github.event_name == 'push' && github.ref_name == 'master' | |
| runs-on: ubuntu-22.04 | |
| defaults: | |
| run: | |
| shell: bash -l {0} | |
| steps: | |
| - name: Checkout modflow6 | |
| uses: actions/checkout@v6 | |
| with: | |
| repository: ${{ github.repository_owner }}/modflow6 | |
| path: modflow6 | |
| - name: Setup Micromamba | |
| uses: mamba-org/setup-micromamba@v1 | |
| with: | |
| environment-file: modflow6/environment.yml | |
| cache-downloads: true | |
| cache-environment: true | |
| - name: Download artifacts | |
| uses: dawidd6/action-download-artifact@v13 | |
| - name: Draft release | |
| working-directory: modflow6 | |
| env: | |
| GITHUB_TOKEN: ${{ github.token }} | |
| run: | | |
| # create draft release | |
| version=$(python distribution/update_version.py -g) | |
| title="MODFLOW $version" | |
| citation=$(python distribution/update_version.py -c) | |
| notes=' | |
| This is the approved USGS MODFLOW '$version' release. | |
| '$citation' | |
| Visit the USGS "MODFLOW and Related Programs" site for information on MODFLOW 6 and related software: https://doi.org/10.5066/F76Q1VQV | |
| ' | |
| gh release create "$version" ../mf*/mf*.zip ../release_notes/release.pdf --target master --title "$title" --notes "$notes" --draft --latest |