From 7747f414bad1f1cf6760172af609e76236c71bb8 Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Mon, 29 Aug 2022 11:32:20 -0500 Subject: [PATCH] ci: Add bump version workflow for release tags * Add tbump based bump version workflow for managing release tags from GitHub Actions workflow dispatch. The workflow adds support for: - bumping versions, creating tags, pushing the tags back to GitHub - release candidates as viable options - automated checks that the SemVer type of bump (major, minor, patch), and if it was or wan't a release candidate, makes sense given the latest tags available on GitHub and the new tag number entered - dry runs (the default) to test that your options all look good --- .github/workflows/bump-version.yml | 244 +++++++++++++++++++++++++++++ 1 file changed, 244 insertions(+) create mode 100644 .github/workflows/bump-version.yml diff --git a/.github/workflows/bump-version.yml b/.github/workflows/bump-version.yml new file mode 100644 index 00000000..5efb256c --- /dev/null +++ b/.github/workflows/bump-version.yml @@ -0,0 +1,244 @@ +name: Bump version + +on: + workflow_dispatch: + inputs: + part: + description: 'Semver type of new version (major | minor | patch)' + required: true + type: choice + options: + - patch + - minor + - major + release_candidate: + type: choice + description: 'Release candidate?' + options: + - false + - true + new_version: + description: 'New version to bump to' + required: true + force: + type: choice + description: 'Force override check?' + options: + - false + - true + dry_run: + type: choice + description: 'Perform a dry run to check?' + options: + - true + - false + +jobs: + bump-version: + runs-on: ubuntu-latest + if: github.repository == 'scikit-hep/pylhe' + + steps: + # Use GitHub PAT to authenticate so other workflows trigger + - name: Checkout code + uses: actions/checkout@v3 + with: + fetch-depth: 0 + token: ${{ secrets.ACCESS_TOKEN }} + + - name: Verify new version bump step is valid + if: github.event.inputs.force == 'false' + id: script + shell: bash + run: | + current_tag="$(git describe --tags --abbrev=0)" + current_tag="${current_tag:1}" + + latest_stable_tag="$(git tag | grep --invert-match 'rc' | tail -n 1)" + latest_stable_tag="${latest_stable_tag:1}" + + echo "* Current version: ${current_tag}" + echo "* Latest stable version: ${latest_stable_tag}" + + if [ ${{ github.event.inputs.release_candidate }} == 'true' ]; then + echo "* Attempting a ${{ github.event.inputs.part }} version release candidate bump from ${current_tag} to: ${{ github.event.inputs.new_version }}" + else + # For ease of use, set current tag to latest stable + current_tag="${latest_stable_tag}" + + echo "* Attempting a ${{ github.event.inputs.part }} version bump from ${current_tag} to: ${{ github.event.inputs.new_version }}" + fi + + echo "* Validating bump target version matches SemVer..." + + # IFS is single charecter, so split on the 'r' in "rc" + IFS='r' read current_tag_read current_rc <- + github.event_name == 'workflow_dispatch' + && ( + github.event.sender.login == 'lukasheinrich' || + github.event.sender.login == 'matthewfeickert' || + github.event.sender.login == 'eduardo-rodrigues' + ) + shell: bash + run: | + tbump --non-interactive --no-push ${{ github.event.inputs.new_version }} + + - name: Update the Git tag annotation + if: ${{ github.event.inputs.dry_run }} == 'false' + shell: bash + run: | + OLD_TAG=${{ steps.script.outputs.old_tag }} + git tag -n99 --list "${OLD_TAG}" + + NEW_TAG=v${{ github.event.inputs.new_version }} + git tag -n99 --list "${NEW_TAG}" + + CHANGES=$(git log --pretty=format:'%s' "${OLD_TAG}"..HEAD --regexp-ignore-case --extended-regexp --grep='^([a-z]*?):') + CHANGES_NEWLINE="$(echo "${CHANGES}" | sed -e 's/^/ - /')" + SANITIZED_CHANGES=$(echo "${CHANGES}" | sed -e 's/^/
  • /' -e 's|$|
  • |' -e 's/(#[0-9]\+)//' -e 's/"/'"'"'/g') + NUM_CHANGES=$(echo -n "${CHANGES}" | grep -c '^') + + if [ ${{ github.event.inputs.release_candidate }} == 'true' ]; then + git tag "${NEW_TAG}" "${NEW_TAG}"^{} -f -m "$(printf "This is a ${{ github.event.inputs.part }} release candidate from ${OLD_TAG} → ${NEW_TAG}.\n\nChanges:\n${CHANGES_NEWLINE}")" + else + git tag "${NEW_TAG}" "${NEW_TAG}"^{} -f -m "$(printf "This is a ${{ github.event.inputs.part }} release from ${OLD_TAG} → ${NEW_TAG}.\n\nChanges:\n${CHANGES_NEWLINE}")" + fi + + git tag -n99 --list "${NEW_TAG}" + + - name: Show annotated Git tag + shell: bash + run: | + git show v${{ github.event.inputs.new_version }} + + - name: Push new tag back to GitHub + shell: bash + run: | + if [ ${{ github.event.inputs.dry_run }} == 'true' ]; then + echo "# DRY RUN" + else + git push origin master --tags + fi