From d4d104aea6f155db6349972895a009e2ba6f92b4 Mon Sep 17 00:00:00 2001 From: w-bonelli Date: Tue, 27 Jun 2023 13:30:09 -0400 Subject: [PATCH] refactor reusable release automation (extra layer of indirection), update docs --- .github/workflows/make_package.yml | 151 +++++++++++++ .github/workflows/release.yml | 286 +++++++++++++++++++------ .github/workflows/release_dispatch.yml | 249 +-------------------- docs/md/release.md | 86 +++++++- 4 files changed, 460 insertions(+), 312 deletions(-) create mode 100644 .github/workflows/make_package.yml diff --git a/.github/workflows/make_package.yml b/.github/workflows/make_package.yml new file mode 100644 index 0000000..ea608a2 --- /dev/null +++ b/.github/workflows/make_package.yml @@ -0,0 +1,151 @@ +name: Make package +on: + # workflow_call trigger lets this workflow be called from elsewhere + workflow_call: + inputs: + branch: + description: Branch to release from. + required: true + type: string + cliff_config: + description: Path of the git-cliff config file relative to the project root. + required: false + default: cliff.toml + type: string + cumulative_changelog: + description: Path of the cumulative changelog file relative to the project root. + required: false + default: HISTORY.md + type: string + package_name: + # currently assumes module dir is in project root, + # and module name is the same as package name with + # hyphens swapped for underscores + description: Name of the Python package to release. + required: true + type: string + python: + description: Python version to build the package with. + required: true + default: '3.8' + type: string + run_tests: + # currently assumes tests are in autotest/ + description: Run tests after building binaries. + required: false + type: boolean + default: true + trunk_branch: + description: Name of the trunk branch (e.g. 'main' or 'master'). + required: false + default: main + type: string + version: + description: Version number to use for release. + required: true + type: string + +jobs: + prep: + name: Prepare release + runs-on: ubuntu-22.04 + if: github.event_name == 'push' && github.ref_name != inputs.trunk_branch + permissions: + contents: write + pull-requests: write + defaults: + run: + shell: bash + steps: + + - name: Checkout release branch + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Setup Python + uses: actions/setup-python@v4 + with: + python-version: ${{ inputs.python }} + + - name: Install Python build/test dependencies + run: | + pip install --upgrade pip + pip install black build twine + pip install . + + - name: Update version + id: version + run: | + ref="${{ github.ref_name }}" + version="${ref#"v"}" + package="${{ inputs.package_name }}" + # assume module name is the same as package + # name with hyphens swapped for underscores + module="${package//-/_}" + python scripts/update_version.py -v "$version" + black -v $module/version.py + python -c "import $module; print('Version: ', $module.__version__)" + echo "version=$version" >> $GITHUB_OUTPUT + + - name: Build package + run: python -m build + + - name: Check package + run: twine check --strict dist/* + + - name: Upload package + uses: actions/upload-artifact@v3 + with: + name: dist + path: dist + + - name: Run tests + if: inputs.run_tests == true + # todo make configurable + working-directory: autotest + run: pytest -v -n=auto --durations=0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Touch changelog + run: touch HISTORY.md + + - name: Generate changelog + id: cliff + uses: orhun/git-cliff-action@v1 + with: + config: ${{ inputs.cliff_config }} + args: --verbose --unreleased --tag ${{ steps.version.outputs.version }} + env: + OUTPUT: CHANGELOG.md + + - name: Update changelog + id: update-changelog + run: | + # move changelog + clog="CHANGELOG_${{ steps.version.outputs.version }}.md" + echo "changelog=$clog" >> $GITHUB_OUTPUT + sudo cp "${{ steps.cliff.outputs.changelog }}" "$clog" + + # show current release changelog + cat "$clog" + + # substitute full group names + sed -i 's/#### Ci/#### Continuous integration/' "$clog" + sed -i 's/#### Feat/#### New features/' "$clog" + sed -i 's/#### Fix/#### Bug fixes/' "$clog" + sed -i 's/#### Refactor/#### Refactoring/' "$clog" + sed -i 's/#### Test/#### Testing/' "$clog" + + cat "$clog" HISTORY.md > temp_history.md + sudo mv temp_history.md HISTORY.md + + # show full changelog + cat HISTORY.md + + - name: Upload changelog + uses: actions/upload-artifact@v3 + with: + name: changelog + path: ${{ steps.update-changelog.outputs.changelog }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index dd4ec16..b5fef23 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,6 +1,9 @@ name: Release on: - # workflow_call trigger lets this workflow be called from elsewhere + # workflow_call trigger lets this be called from other workflows. + # note this workflow may be called multiple times in a release, + # first to trigger the distribution build, then to draft the PR + # to trunk, then publish the package, reinitialize develop, etc. workflow_call: inputs: branch: @@ -17,16 +20,33 @@ on: required: false default: HISTORY.md type: string + draft_release: + description: Draft a release post with assets and changelog. + required: false + default: true + type: boolean package_name: - # currently assumes module dir is in project root - description: Name of the Python package to release (must be identical to the module name). + # currently assumes module dir is in project root, + # and module name is the same as package name with + # hyphens swapped for underscores + description: Name of the Python package to release. required: true type: string - python_version: + publish_package: + description: Publish the package to PyPI. + required: false + default: true + type: boolean + python: description: Python version to build the package with. - required: true + required: false default: '3.8' type: string + reset_develop: + description: Reset the develop branch from the trunk. + required: false + default: true + type: boolean run_tests: # currently assumes tests are in autotest/ description: Run tests after building binaries. @@ -42,35 +62,48 @@ on: description: Version number to use for release. required: true type: string - jobs: - prep: - name: Prepare release + make_dist: + name: Make distribution + if: github.event_name != 'workflow_dispatch' && github.ref_name != inputs.trunk_branch + uses: ./.github/workflows/make_package.yml + with: + branch: ${{ inputs.branch }} + cliff_config: ${{ inputs.cliff_config }} + cumulative_changelog: ${{ inputs.cumulative_changelog }} + package_name: ${{ inputs.package_name }} + python: ${{ inputs.python }} + run_tests: ${{ inputs.run_tests }} + trunk_branch: ${{ inputs.trunk_branch }} + version: ${{ inputs.version }} + + release_pr: + name: Draft release PR + if: github.event_name != 'workflow_dispatch' && !contains(github.ref_name, 'rc') + needs: + - make_dist runs-on: ubuntu-22.04 - if: github.event_name == 'push' && github.ref_name != inputs.trunk_branch permissions: contents: write pull-requests: write - defaults: - run: - shell: bash steps: - - name: Checkout release branch + - name: Checkout repo uses: actions/checkout@v3 with: - fetch-depth: 0 + # use repository_owner to allow testing on a fork + repository: ${{ github.repository_owner }}/modflow-devtools + ref: ${{ github.ref }} - name: Setup Python uses: actions/setup-python@v4 with: - python-version: ${{ inputs.python_version }} + python-version: ${{ inputs.python }} - name: Install Python build/test dependencies run: | pip install --upgrade pip - pip install black build twine - pip install . + pip install black filelock - name: Update version id: version @@ -86,64 +119,183 @@ jobs: python -c "import $module; print('Version: ', $module.__version__)" echo "version=$version" >> $GITHUB_OUTPUT - - name: Build package - run: python -m build + - name: Commit & push changes + env: + GITHUB_TOKEN: ${{ github.token }} + run: | + 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): version ${{ inputs.version }}" + git push origin "${{ github.ref_name }}" + + # actions/download-artifact won't look at previous workflow runs but we need to in order to get changelog + - name: Download artifacts + uses: dawidd6/action-download-artifact@v2 + + - name: Create release PR + env: + GITHUB_TOKEN: ${{ github.token }} + run: | + ver="${{ inputs.version }}" + changelog=$(cat CHANGELOG.md) + + title="Release $ver" + trunk="${{ inputs.trunk_branch }}" + body=' + # Release '$ver' + + The release can be approved by merging this pull request into `$trunk`. This will trigger jobs to publish the release to PyPI and reset `develop` from `$trunk`. + + ## Changelog + + '$changelog' + ' + gh pr create -B "$trunk" -H "${{ github.ref_name }}" --title "$title" --draft --body "$body" + + release: + name: Draft release + needs: + - make_dist + # runs only when changes are merged to trunk + if: github.event_name == 'push' && github.ref_name == inputs.trunk_branch && (inputs.draft_release == '' || inputs.draft_release == true) + runs-on: ubuntu-22.04 + permissions: + contents: write + pull-requests: write + steps: + + - name: Checkout repo + uses: actions/checkout@v3 + with: + # use repository_owner to allow testing on a fork + repository: ${{ github.repository_owner }}/modflow-devtools + ref: ${{ inputs.trunk_branch }} + + # actions/download-artifact won't look at previous workflow runs but we need to in order to get changelog + - name: Download artifacts + uses: dawidd6/action-download-artifact@v2 + + - name: Draft release + env: + GITHUB_TOKEN: ${{ github.token }} + run: | + version=$(cat version.txt) + title="${{ inputs.package_name }} $version" + notes=$(cat "changelog/CHANGELOG_$version.md" | grep -v "### Version $version") + gh release create "$version" \ + --target ${{ inputs.trunk_branch }} \ + --title "$title" \ + --notes "$notes" \ + --draft \ + --latest + + publish: + name: Publish package + needs: + - make_dist + - release + # runs only after release is published (manually promoted from draft) + if: github.event_name == 'release' && (inputs.publish_package == '' || inputs.publish_package == true) + runs-on: ubuntu-22.04 + permissions: + contents: write + pull-requests: write + id-token: write # mandatory for trusted publishing + environment: # requires a 'pypi' environment in repo settings + name: pypi + url: https://pypi.org/p/${{ inputs.package_name }} + steps: + + - name: Checkout trunk + uses: actions/checkout@v3 + with: + # use repository_owner to allow testing on a fork + repository: ${{ github.repository_owner }}/modflow-devtools + ref: ${{ inputs.trunk_branch }} + + - name: Setup Python + uses: actions/setup-python@v4 + with: + python-version: ${{ inputs.python }} + + - name: Install Python dependencies + run: | + pip install --upgrade pip + pip install twine - name: Check package run: twine check --strict dist/* - - name: Upload package - uses: actions/upload-artifact@v3 - with: - name: dist - path: dist - - - name: Run tests - if: inputs.run_tests == true - # todo make configurable - working-directory: autotest - run: pytest -v -n=auto --durations=0 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Publish package + run: twine upload dist/* + + reset_pr: + name: Draft reset PR + needs: + - make_dist + - release + if: github.event_name == 'release' && (inputs.reset_develop == '' || inputs.reset_develop == true) + runs-on: ubuntu-22.04 + permissions: + contents: write + pull-requests: write + steps: - - name: Touch changelog - run: touch HISTORY.md + - name: Checkout trunk branch + uses: actions/checkout@v3 + with: + # use repository_owner to allow testing on a fork + repository: ${{ github.repository_owner }}/modflow-devtools + ref: ${{ inputs.trunk_branch }} - - name: Generate changelog - id: cliff - uses: orhun/git-cliff-action@v1 + - name: Setup Python + uses: actions/setup-python@v4 with: - config: ${{ inputs.cliff_config }} - args: --verbose --unreleased --tag ${{ steps.version.outputs.version }} - env: - OUTPUT: CHANGELOG.md + python-version: ${{ inputs.python }} + cache: 'pip' - - name: Update changelog - id: update-changelog + - name: Install Python dependencies run: | - # move changelog - clog="CHANGELOG_${{ steps.version.outputs.version }}.md" - echo "changelog=$clog" >> $GITHUB_OUTPUT - sudo cp "${{ steps.cliff.outputs.changelog }}" "$clog" - - # show current release changelog - cat "$clog" - - # substitute full group names - sed -i 's/#### Ci/#### Continuous integration/' "$clog" - sed -i 's/#### Feat/#### New features/' "$clog" - sed -i 's/#### Fix/#### Bug fixes/' "$clog" - sed -i 's/#### Refactor/#### Refactoring/' "$clog" - sed -i 's/#### Test/#### Testing/' "$clog" - - cat "$clog" HISTORY.md > temp_history.md - sudo mv temp_history.md HISTORY.md - - # show full changelog - cat HISTORY.md + pip install --upgrade pip + pip install black filelock - - name: Upload changelog - uses: actions/upload-artifact@v3 + - name: Get release tag + uses: oprypin/find-latest-tag@v1 + id: latest_tag with: - name: changelog - path: ${{ steps.update-changelog.outputs.changelog }} + repository: ${{ github.repository }} + releases-only: true + + - name: Draft pull request + env: + GITHUB_TOKEN: ${{ github.token }} + run: | + # create reset branch from trunk + reset_branch="post-release-${{ steps.latest_tag.outputs.tag }}-reset" + git switch -c $reset_branch + + # update version (add + to version.txt to indicate development status) + package=${{ inputs.package_name }} + module=${package//-/_} + version=$(python update_version.py -g) + python scripts/update_version.py -v "$version+" + black -v $module/version.py + + # commit and push reset branch + trunk=${{ inputs.trunk_branch }} + 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(post-release): update develop from $trunk" + git push -u origin $reset_branch + + # create PR into develop + body=' + # Reinitialize for development + + Updates the `develop` branch from `$trunk` following a successful release. + ' + gh pr create -B "develop" -H "$reset_branch" --title "Reinitialize develop branch" --draft --body "$body" \ No newline at end of file diff --git a/.github/workflows/release_dispatch.yml b/.github/workflows/release_dispatch.yml index bd29a3d..b0264f0 100644 --- a/.github/workflows/release_dispatch.yml +++ b/.github/workflows/release_dispatch.yml @@ -55,9 +55,7 @@ jobs: shell: bash -l {0} outputs: branch: ${{ steps.set_branch.outputs.branch }} - package: ${{ steps.set_package.outputs.package }} python: ${{ steps.set_python.outputs.python }} - trunk: ${{ steps.set_trunk.outputs.trunk }} version: ${{ steps.set_version.outputs.version }} steps: @@ -83,10 +81,6 @@ jobs: exit 1 fi echo "branch=$branch" >> $GITHUB_OUTPUT - - - name: Set package name - id: set_package - run: echo "package=modflow-devtools" >> $GITHUB_OUTPUT - name: Set Python id: set_python @@ -101,10 +95,6 @@ jobs: fi echo "python=$python" >> $GITHUB_OUTPUT - - name: Set trunk branch - id: set_trunk - run: echo "trunk=main" >> $GITHUB_OUTPUT - - name: Set version id: set_version run: | @@ -124,240 +114,19 @@ jobs: fi echo "version=$ver" >> $GITHUB_OUTPUT - make_dist: + release: name: Do release uses: ./.github/workflows/release.yml needs: - set_options with: branch: ${{ needs.set_options.outputs.branch }} - package_name: ${{ needs.set_options.outputs.package }} - python_version: ${{ needs.set_options.outputs.python }} - trunk_branch: ${{ needs.set_options.outputs.trunk }} + draft_release: true + package_name: modflow-devtools + publish_package: false + python: ${{ needs.set_options.outputs.python }} + reset_develop: true + run_tests: true + trunk_branch: main version: ${{ needs.set_options.outputs.version }} - - pr: - name: Draft release PR - needs: - - set_options - - make_dist - runs-on: ubuntu-22.04 - permissions: - contents: write - pull-requests: write - steps: - - - name: Checkout repo - uses: actions/checkout@v3 - with: - # use repository_owner to allow testing on a fork - repository: ${{ github.repository_owner }}/modflow-devtools - ref: ${{ github.ref }} - - - name: Setup Python - uses: actions/setup-python@v4 - with: - python-version: ${{ inputs.python }} - - - name: Install Python build/test dependencies - run: | - pip install --upgrade pip - pip install black filelock - - - name: Update version - id: version - run: | - ref="${{ github.ref_name }}" - version="${ref#"v"}" - package="${{ needs.set_options.outputs.package }}" - # assume module name is the same as package - # name with hyphens swapped for underscores - module="${package//-/_}" - python scripts/update_version.py -v "$version" - black -v $module/version.py - python -c "import $module; print('Version: ', $module.__version__)" - echo "version=$version" >> $GITHUB_OUTPUT - - - name: Commit & push changes - env: - GITHUB_TOKEN: ${{ github.token }} - run: | - ver="${{ needs.set_options.outputs.version }}" - - 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): version $ver" - git push origin "${{ github.ref_name }}" - - # actions/download-artifact won't look at previous workflow runs but we need to in order to get changelog - - name: Download artifacts - uses: dawidd6/action-download-artifact@v2 - - - name: Create release PR - env: - GITHUB_TOKEN: ${{ github.token }} - run: | - ver="${{ needs.set_options.outputs.version }}" - changelog=$(cat CHANGELOG.md) - - title="Release $ver" - trunk="${{ needs.set_options.outputs.trunk }}" - body=' - # Release '$ver' - - The release can be approved by merging this pull request into `$trunk`. This will trigger jobs to publish the release to PyPI and reset `develop` from `$trunk`. - - ## Changelog - - '$changelog' - ' - gh pr create -B "$trunk" -H "${{ github.ref_name }}" --title "$title" --draft --body "$body" - - release: - name: Draft release - needs: - - set_options - - make_dist - # runs only when changes are merged to trunk - if: github.event_name == 'push' && github.ref_name == needs.set_options.outputs.trunk && inputs.draft_release == true - runs-on: ubuntu-22.04 - permissions: - contents: write - pull-requests: write - steps: - - - name: Checkout repo - uses: actions/checkout@v3 - with: - # use repository_owner to allow testing on a fork - repository: ${{ github.repository_owner }}/modflow-devtools - ref: ${{ needs.set_options.outputs.trunk }} - - # actions/download-artifact won't look at previous workflow runs but we need to in order to get changelog - - name: Download artifacts - uses: dawidd6/action-download-artifact@v2 - - - name: Draft release - env: - GITHUB_TOKEN: ${{ github.token }} - run: | - version=$(cat version.txt) - title="${{ needs.set_options.outputs.package }} $version" - notes=$(cat "changelog/CHANGELOG_$version.md" | grep -v "### Version $version") - gh release create "$version" \ - --target ${{ needs.set_options.outputs.trunk }} \ - --title "$title" \ - --notes "$notes" \ - --draft \ - --latest - - publish: - name: Publish package - needs: - - set_options - - make_dist - # runs only after release is published (manually promoted from draft) - if: github.event_name == 'release' && inputs.publish_package == true - runs-on: ubuntu-22.04 - permissions: - contents: write - pull-requests: write - id-token: write # mandatory for trusted publishing - environment: # requires a 'pypi' environment in repo settings - name: pypi - url: https://pypi.org/p/${{ needs.set_options.outputs.package }} - steps: - - - name: Checkout trunk - uses: actions/checkout@v3 - with: - # use repository_owner to allow testing on a fork - repository: ${{ github.repository_owner }}/modflow-devtools - ref: ${{ needs.set_options.outputs.trunk }} - - - name: Setup Python - uses: actions/setup-python@v4 - with: - python-version: ${{ needs.set_options.outputs.python }} - - - name: Install Python dependencies - run: | - pip install --upgrade pip - pip install twine - - - name: Check package - run: twine check --strict dist/* - - - name: Publish package - run: twine upload dist/* - - reset: - name: Draft reset PR - needs: - - set_options - - make_dist - if: github.event_name == 'release' && inputs.reset_develop == true - runs-on: ubuntu-22.04 - permissions: - contents: write - pull-requests: write - steps: - - - name: Checkout trunk branch - uses: actions/checkout@v3 - with: - # use repository_owner to allow testing on a fork - repository: ${{ github.repository_owner }}/modflow-devtools - ref: ${{ needs.set_options.outputs.trunk }} - - - name: Setup Python - uses: actions/setup-python@v4 - with: - python-version: ${{ needs.set_options.outputs.python }} - cache: 'pip' - - - name: Install Python dependencies - run: | - pip install --upgrade pip - pip install black filelock - - - name: Get release tag - uses: oprypin/find-latest-tag@v1 - id: latest_tag - with: - repository: ${{ github.repository }} - releases-only: true - - - name: Draft pull request - env: - GITHUB_TOKEN: ${{ github.token }} - run: | - # create reset branch from trunk - reset_branch="post-release-${{ steps.latest_tag.outputs.tag }}-reset" - git switch -c $reset_branch - - # update version (add + to version.txt to indicate development status) - package=${{ needs.set_options.outputs.package }} - module=${package//-/_} - version=$(python update_version.py -g) - python scripts/update_version.py -v "$version+" - black -v $module/version.py - - # commit and push reset branch - trunk=${{ needs.set_options.outputs.trunk }} - 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(post-release): update develop from $trunk" - git push -u origin $reset_branch - - # create PR into develop - body=' - # Reinitialize for development - - Updates the `develop` branch from `$trunk` following a successful release. - ' - gh pr create -B "develop" -H "$reset_branch" --title "Reinitialize develop branch" --draft --body "$body" \ No newline at end of file + \ No newline at end of file diff --git a/docs/md/release.md b/docs/md/release.md index f2fcc8b..7faaf32 100644 --- a/docs/md/release.md +++ b/docs/md/release.md @@ -2,8 +2,22 @@ This repository provides a [reusable GitHub Actions workflow](https://docs.github.com/en/actions/using-workflows/reusing-workflows) for EC-related Python packages. This workflow is used by the `modflow-devtools` project itself, and can be used by other projects provided a few requirements are met. +## Overview + +There are two reusable release workflows in this repository: + +- `make_package.yml`: builds (and optionally tests) the Python package to be released +- `release.yml`: orchestrates optional release procedures after the package is built, including merging to trunk and back to `develop`, publishing to PyPI, creating a release post, and reinitializing the `develop` from trunk. + +A third workflow, `release_dispatch.yml`, contains triggers to start the release procedure either on: + +- manual dispatch from the GitHub UI or CLI +- push of a branch named `vx.y.z` or `vx.y.zrc`, where `x`, `y`, and `z` are semantic version numbers + ## Requirements +A few assumptions are made about projects consuming the release workflows defined here. + 1. Trusted publishing The release workflow assumes the consuming repository is configured for [trusted publishing](https://docs.pypi.org/trusted-publishers/) to PyPI. As such, PyPI credentials need not be stored as repo secrets. Note that trusted publishing requires a [deployment environment](https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment) named `pypi`. The environment may be empty. @@ -26,10 +40,10 @@ The release workflow is triggered when a release branch is pushed to the reposit ## Usage -Reusable workflows are [called directly from jobs](https://docs.github.com/en/actions/using-workflows/reusing-workflows#calling-a-reusable-workflow) rather than from steps within a job. For instance, to call the release workflow from a workflow in a repository containing a Python package named `mypackage` which should be built with Python 3.9, add a workflow like the following: +Reusable workflows are [called directly from jobs](https://docs.github.com/en/actions/using-workflows/reusing-workflows#calling-a-reusable-workflow) rather than from steps within a job. For instance, to call the release workflow from a workflow in a repository containing a Python package named `mypackage` which should be built with Python 3.9: ```yaml -name: Release +name: Release mypackage on: push: branches: @@ -42,10 +56,72 @@ on: # third phase trigger after release is published - published jobs: + # configure options which may be set as dispatch + # inputs or dynamically assigned default values + 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 }} + version: ${{ steps.set_version.outputs.version }} + steps: + + - 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 develop or master + if [[ ("$branch" == "develop") || ("$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 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 + release: - uses: MODFLOW-USGS/modflow-devtools/.github/workflows/reusable_release.yml@main + uses: MODFLOW-USGS/modflow-devtools/.github/workflows/release.yml@main with: + branch: ${{ needs.set_options.outputs.branch }} + draft_release: true package_name: mypackage - python_version: 3.9 - trunk_branch: master + publish_package: true + python: '3.9' + reset_develop: true + run_tests: true + trunk_branch: main # substitute master if needed + version: '0.1.2' ``` \ No newline at end of file