Skip to content

9.9.9 - Version Bump and Changelog Generation #3

9.9.9 - Version Bump and Changelog Generation

9.9.9 - Version Bump and Changelog Generation #3

Workflow file for this run

# **what?**
# Perform the version bump, generate the changelog and run tests.
#
# Inputs:
# version_number: The release version number (i.e. 1.0.0b1, 1.2.3rc2, 1.0.0)
# test_run: Test run (The temp branch will be used for release)
#
# Branching strategy:
# - During execution workflow execution the temp branch will be generated.
# - For normal runs the temp branch will be removed once changes were merged to target branch;
# - For test runs we will keep temp branch and will use it for release;
# Naming strategy:
# - For normal runs: prep-release/${{ inputs.version_number }}_$GITHUB_RUN_ID
# - For test runs: prep-release/test-run/${{ inputs.version_number }}_$GITHUB_RUN_ID
#
# **why?**
# Reusable and consistent GitHub release process.
#
# **when?**
# Call when ready to kick off a build and release
#
# Validation Checks
#
# 1. Bump the version if it has not been bumped
# 2. Generate the changelog (via changie) if there is no markdown file for this version
#
name: Version Bump and Changelog Generation
run-name: "${{ inputs.version_number }} - Version Bump and Changelog Generation"
on:
workflow_dispatch:
inputs:
version_number:
required: true
type: string
test_run:
required: false
default: true
type: boolean
permissions:
contents: write
defaults:
run:
shell: bash
env:
PYTHON_TARGET_VERSION: 3.9
NOTIFICATION_PREFIX: "[Release Preparation]"
jobs:
log-inputs:
runs-on: ubuntu-latest
steps:
- name: "[DEBUG] Print Variables"
run: |
# WORKFLOW INPUTS
echo The release version number: ${{ inputs.version_number }}
echo Test run: ${{ inputs.test_run }}
# ENVIRONMENT VARIABLES
echo Python target version: ${{ env.PYTHON_TARGET_VERSION }}
echo Notification prefix: ${{ env.NOTIFICATION_PREFIX }}
audit-changelog:
runs-on: ubuntu-latest
outputs:
changelog_path: ${{ steps.set_path.outputs.changelog_path }}
exists: ${{ steps.set_existence.outputs.exists }}
base_version: ${{ steps.semver.outputs.base-version }}
prerelease: ${{ steps.semver.outputs.pre-release }}
is_prerelease: ${{ steps.semver.outputs.is-pre-release }}
steps:
- name: "Checkout ${{ github.repository }} Commit ${{ github.ref }}"
uses: actions/checkout@v4
with:
ref: ${{ github.ref }}
- name: "Audit Version And Parse Into Parts"
id: semver
uses: dbt-labs/actions/parse-semver@v1.1.0
with:
version: ${{ inputs.version_number }}
- name: "Set Changelog Path"
id: set_path
run: |
path=".changes/${{ steps.semver.outputs.base-version }}.md"
# Send notification
echo "changelog_path=$path" >> $GITHUB_OUTPUT
title="Changelog path"
echo "::notice title=${{ env.NOTIFICATION_PREFIX }}: $title::$changelog_path"
- name: "Set Changelog Existence For Subsequent Jobs"
id: set_existence
run: |
does_exist=false
if test -f ${{ steps.set_path.outputs.changelog_path }}
then
does_exist=true
fi
echo "exists=$does_exist">> $GITHUB_OUTPUT
- name: "[Notification] Set Changelog Existence For Subsequent Jobs"
run: |
title="Changelog exists"
if [[ ${{ steps.set_existence.outputs.exists }} == true ]]
then
message="Changelog file ${{ steps.set_path.outputs.changelog_path }} already exists"
else
message="Changelog file ${{ steps.set_path.outputs.changelog_path }} doesn't exist"
fi
echo "::notice title=${{ env.NOTIFICATION_PREFIX }}: $title::$message"
- name: "[DEBUG] Print Outputs"
run: |
echo changelog_path: ${{ steps.set_path.outputs.changelog_path }}
echo exists: ${{ steps.set_existence.outputs.exists }}
echo base_version: ${{ steps.semver.outputs.base-version }}
echo prerelease: ${{ steps.semver.outputs.pre-release }}
echo is_prerelease: ${{ steps.semver.outputs.is-pre-release }}
audit-version-in-code:
runs-on: ubuntu-latest
outputs:
up_to_date: ${{ steps.version-check.outputs.up_to_date }}
steps:
- name: "Checkout ${{ github.repository }} Commit ${{ github.ref }}"
uses: actions/checkout@v4
with:
ref: ${{ github.ref }}
- name: "Set up Python & Hatch - ${{ env.PYTHON_TARGET_VERSION }}"
uses: ./.github/actions/setup-python-hatch
with:
python-version: "${{ env.PYTHON_TARGET_VERSION }}"
- name: "Check Current Version In Code"
id: version-check
run: |
is_updated=false
current_version=$(hatch version)
if [ "$current_version" == "${{ inputs.version_number }}" ]; then
is_updated=true
fi
echo "up_to_date=$is_updated" >> $GITHUB_OUTPUT
- name: "[Notification] Check Current Version In Code"
run: |
title="Version check"
if [[ ${{ steps.version-check.outputs.up_to_date }} == true ]]
then
message="The version in the codebase is equal to the provided version"
else
message="The version in the codebase differs from the provided version"
fi
echo "::notice title=${{ env.NOTIFICATION_PREFIX }}: $title::$message"
- name: "[DEBUG] Print Outputs"
run: |
echo up_to_date: ${{ steps.version-check.outputs.up_to_date }}
skip-generate-changelog:
runs-on: ubuntu-latest
needs: [audit-changelog]
if: needs.audit-changelog.outputs.exists == 'true'
steps:
- name: "Changelog Exists, Skip Generating New Changelog"
run: |
# Send notification
title="Skip changelog generation"
message="A changelog file already exists at ${{ needs.audit-changelog.outputs.changelog_path }}, skipping generating changelog"
echo "::notice title=${{ env.NOTIFICATION_PREFIX }}: $title::$message"
skip-version-bump:
runs-on: ubuntu-latest
needs: [audit-version-in-code]
if: needs.audit-version-in-code.outputs.up_to_date == 'true'
steps:
- name: "Version Already Bumped"
run: |
# Send notification
title="Skip version bump"
message="The version has already been bumped to ${{ inputs.version_number }}, skipping version bump"
echo "::notice title=${{ env.NOTIFICATION_PREFIX }}: $title::$message"
create-temp-branch:
runs-on: ubuntu-latest
needs: [audit-changelog, audit-version-in-code]
if: needs.audit-changelog.outputs.exists == 'false' || needs.audit-version-in-code.outputs.up_to_date == 'false'
outputs:
branch_name: ${{ steps.variables.outputs.branch_name }}
steps:
- name: "Checkout ${{ github.repository }} Commit ${{ github.ref }}"
uses: actions/checkout@v4
with:
ref: ${{ github.ref }}
- name: "Generate Branch Name"
id: variables
run: |
name="prep-release/"
if [[ ${{ inputs.test_run }} == true ]]
then
name+="test-run/"
fi
name+="${{ inputs.version_number }}_$GITHUB_RUN_ID"
echo "branch_name=$name" >> $GITHUB_OUTPUT
- name: "Create Branch - ${{ steps.variables.outputs.branch_name }}"
run: |
git checkout -b ${{ steps.variables.outputs.branch_name }}
git push -u origin ${{ steps.variables.outputs.branch_name }}
- name: "[Notification] Temp branch created"
run: |
# Send notification
title="Temp branch generated"
message="The ${{ steps.variables.outputs.branch_name }} branch created"
echo "::notice title=${{ env.NOTIFICATION_PREFIX }}: $title::$message"
- name: "[DEBUG] Print Outputs"
run: |
echo branch_name ${{ steps.variables.outputs.branch_name }}
generate-changelog-bump-version:
runs-on: ubuntu-latest
needs: [audit-changelog, audit-version-in-code, create-temp-branch]
steps:
- name: "Checkout ${{ github.repository }} Branch ${{ needs.create-temp-branch.outputs.branch_name }}"
uses: actions/checkout@v4
with:
ref: ${{ needs.create-temp-branch.outputs.branch_name }}
- name: "Set Git User"
run: |
git config user.name "Github Build Bot"
git config user.email "buildbot@fishtownanalytics.com"
- name: "Add Homebrew To PATH"
run: |
echo "/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin" >> $GITHUB_PATH
- name: "Install Homebrew Packages"
run: |
brew install pre-commit
brew tap miniscruff/changie https://github.com/miniscruff/changie
brew install changie
- name: "Set json File Name"
id: json_file
run: |
echo "name=output_$GITHUB_RUN_ID.json" >> $GITHUB_OUTPUT
- name: "Get Core Team Membership"
run: |
gh api -H "Accept: application/vnd.github+json" orgs/dbt-labs/teams/core-group/members > ${{ steps.json_file.outputs.name }}
env:
GH_TOKEN: ${{ secrets.IT_TEAM_MEMBERSHIP }}
- name: "Set Core Team Membership for Changie Contributors exclusion"
id: set_team_membership
run: |
team_list=$(jq -r '.[].login' ${{ steps.json_file.outputs.name }})
echo $team_list
team_list_single=$(echo $team_list | tr '\n' ' ')
echo "CHANGIE_CORE_TEAM=$team_list_single" >> $GITHUB_ENV
- name: "Delete the json File"
run: |
rm ${{ steps.json_file.outputs.name }}
- name: "Generate Release Changelog"
if: needs.audit-changelog.outputs.exists == 'false'
run: |
if [[ -d ".changes/${{ needs.audit-changelog.outputs.base_version }}" ]]
then
changie batch ${{ needs.audit-changelog.outputs.base_version }} --include '${{ needs.audit-changelog.outputs.base_version }}' --remove-prereleases
else # releasing a final patch with no prereleases
changie batch ${{ needs.audit-changelog.outputs.base_version }}
fi
changie merge
git status
- name: "Check Changelog Created Successfully"
if: needs.audit-changelog.outputs.exists == 'false'
run: |
title="Changelog"
if [[ -f ${{ needs.audit-changelog.outputs.changelog_path }} ]]
then
message="Changelog file created successfully"
echo "::notice title=${{ env.NOTIFICATION_PREFIX }}: $title::$message"
else
message="Changelog failed to generate"
echo "::error title=${{ env.NOTIFICATION_PREFIX }}: $title::$message"
exit 1
fi
- name: "Set up Python & Hatch - ${{ env.PYTHON_TARGET_VERSION }}"
uses: ./.github/actions/setup-python-hatch
with:
python-version: "${{ env.PYTHON_TARGET_VERSION }}"
- name: "Bump Version To ${{ inputs.version_number }}"
if: needs.audit-version-in-code.outputs.up_to_date == 'false'
run: |
hatch version "${{ inputs.version_number }}"
git status
- name: "[Notification] Bump Version To ${{ inputs.version_number }}"
if: needs.audit-version-in-code.outputs.up_to_date == 'false'
run: |
title="Version bump"
message="Version successfully bumped in codebase to ${{ inputs.version_number }}"
echo "::notice title=${{ env.NOTIFICATION_PREFIX }}: $title::$message"
# this step will fail on whitespace errors but also correct them, so add a `| true` to avoid failure
- name: "Remove Trailing Whitespace Via Pre-commit"
run: |
pre-commit run trailing-whitespace --files .bumpversion.cfg CHANGELOG.md .changes/* || true
git status
# this step will fail on newline errors but also correct them, so add a `| true` to avoid failure
- name: "Removing Extra Newlines Via Pre-commit"
run: |
pre-commit run end-of-file-fixer --files .bumpversion.cfg CHANGELOG.md .changes/* || true
git status
- name: "Commit & Push Changes"
run: |
commit_message="Bumping version to ${{ inputs.version_number }} and generate changelog"
#Commit changes to branch
git pull
git add .
git commit -m "$commit_message"
git push
run-unit-tests:
runs-on: ubuntu-latest
needs: [create-temp-branch, generate-changelog-bump-version]
env:
TOXENV: unit
steps:
- name: "Checkout ${{ github.repository }} Branch ${{ needs.create-temp-branch.outputs.branch_name }}"
uses: actions/checkout@v4
with:
ref: ${{ needs.create-temp-branch.outputs.branch_name }}
- name: "Set up Python & Hatch - ${{ env.PYTHON_TARGET_VERSION }}"
uses: ./.github/actions/setup-python-hatch
with:
python-version: "${{ env.PYTHON_TARGET_VERSION }}"
- name: "Run Tests"
run: |
hatch run test:unit
merge-changes:
name: "Merge Changes Into ${{ github.ref }}"
runs-on: ubuntu-latest
needs: [run-unit-tests, create-temp-branch, audit-version-in-code, audit-changelog]
if: |
!failure() && !cancelled() &&
inputs.test_run == false &&
(
needs.audit-changelog.outputs.exists == 'false' ||
needs.audit-version-in-code.outputs.up_to_date == 'false'
)
steps:
- name: "[Debug] Print Variables"
run: |
echo branch_name: ${{ needs.create-temp-branch.outputs.branch_name }}
echo inputs.test_run: ${{ inputs.test_run }}
echo needs.audit-changelog.outputs.exists: ${{ needs.audit-changelog.outputs.exists }}
echo needs.audit-version-in-code.outputs.up_to_date: ${{ needs.audit-version-in-code.outputs.up_to_date }}
- name: "Set Git User"
run: |
git config user.name "Github Build Bot"
git config user.email "buildbot@fishtownanalytics.com"
- name: "Checkout Repo ${{ github.repository }}"
uses: actions/checkout@v4
with:
ref: ${{ github.ref }}
token: ${{ secrets.FISHTOWN_BOT_PAT }}
- name: "Merge in changes"
run: |
git fetch origin ${{ needs.create-temp-branch.outputs.branch_name }}
if ! git merge origin/${{ needs.create-temp-branch.outputs.branch_name }} --no-ff -m "Merge version bump and changelogs"; then
echo "::error::Merge failed"
exit 1
fi
git push origin HEAD || {
echo "::error::Push failed"
exit 1
}
- name: "Delete Temp Branch"
env:
GH_TOKEN: ${{ secrets.FISHTOWN_BOT_PAT }}
run: |
gh api -X DELETE repos/${{ github.repository }}/git/refs/heads/${{ needs.create-temp-branch.outputs.branch_name }}
- name: "[Notification] Changes Merged"
run: |
title="Changelog and Version Bump Branch Merge"
message="The ${{ needs.create-temp-branch.outputs.branch_name }} branch was merged into ${{ github.ref }}"
echo "::notice title=${{ env.NOTIFICATION_PREFIX }}: $title::$message"