Skip to content

Commit

Permalink
chore: Refactor release steps ensuring tag is created before running …
Browse files Browse the repository at this point in the history
…tests and creating release (#2154)

* initial structure

* fix: use github output

* fix: ensure tag step uses latest commit from master

* fix: handle properly string value of output value

* rename initial step for processing inputs

* add new input for commit workflow

* simplify conditionals by using cancelled() and contains(needs.*.result, 'failure')

* add FAQ section in releasing docs

* fix link to workflow
  • Loading branch information
AgustinBettati authored Apr 18, 2024
1 parent bdab19c commit 1400b8a
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 44 deletions.
115 changes: 71 additions & 44 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: 'New Release'
run-name: 'Release ${{ inputs.version_number }}'
run-name: 'Release ${{ inputs.version_number }} (skip tests: ${{ inputs.skip_tests }}, use existing tag: ${{ inputs.use_existing_tag}})'

# Used for creating a new release. This workflow will run qa acceptance tests, create a new tag, and generate the release with GoReleaser.
on:
Expand All @@ -9,38 +9,43 @@ on:
description: 'Version number (e.g., v1.0.0, v1.0.0-pre, v1.0.0-pre1)'
required: true
skip_tests:
description: 'Skip QA acceptance tests, define value to `true` to explicitly skip'
description: 'Set value to `true` to skip QA acceptance tests, default is `false`'
default: 'false'
use_existing_tag:
description: 'Set value to `true` to use an existing tag for this release version, default is `false`'
description: 'Set value to `true` to use an existing tag for the release process, default is `false`'
default: 'false'

jobs:

release-config:
runs-on: ubuntu-latest
outputs:
creates_new_tag: ${{ steps.evaluate_inputs.outputs.creates_new_tag }}
is_official_release: ${{ steps.evaluate_inputs.outputs.is_official_release }}
runs_tests: ${{ steps.evaluate_inputs.outputs.runs_tests }}
steps:
- id: evaluate_inputs
run: |
{
echo "creates_new_tag=$(if [ '${{ inputs.use_existing_tag }}' = 'true' ]; then echo 'false'; else echo 'true'; fi)"
echo "is_official_release=$(if echo '${{ inputs.version_number }}' | grep -q 'pre'; then echo 'false'; else echo 'true'; fi)"
echo "runs_tests=$(if [ '${{ inputs.skip_tests }}' = 'true' ]; then echo 'false'; else echo 'true'; fi)"
} >> "$GITHUB_OUTPUT"
validate-version-input:
runs-on: ubuntu-latest
steps:
- name: Validation of version format
run: |
echo "${{ inputs.version_number }}" | grep -P '^v\d+\.\d+\.\d+(-pre[A-Za-z0-9-]*)?$'
echo "${{ inputs.version_number }}" | grep -P '^v\d+\.\d+\.\d+(-pre[A-Za-z0-9-]*)?$'
run-qa-acceptance-tests:
needs: [ validate-version-input ]
# QA acceptance tests are skipped when explicit input parameter is used
# As this job may be skipped following jobs require using 'always()' to make sure they are still run
if: needs.validate-version-input.result == 'success' && inputs.skip_tests != 'true'
secrets: inherit
uses: ./.github/workflows/acceptance-tests.yml
with:
atlas_cloud_env: "qa"
ref: ${{ inputs.use_existing_tag == 'true' && inputs.version_number || github.ref }}

update-examples-reference-in-docs:
needs: [ validate-version-input, run-qa-acceptance-tests ]
needs: [ release-config, validate-version-input ]
if: >-
always()
&& inputs.use_existing_tag != 'true'
&& !contains(inputs.version_number, 'pre')
&& needs.validate-version-input.result == 'success'
&& (needs.run-qa-acceptance-tests.result == 'skipped' || needs.run-qa-acceptance-tests.result == 'success')
!cancelled()
&& !contains(needs.*.result, 'failure')
&& needs.release-config.outputs.creates_new_tag == 'true'
&& needs.release-config.outputs.is_official_release == 'true'
uses: ./.github/workflows/run-script-and-commit.yml
with:
script_call: './scripts/update-examples-reference-in-docs.sh ${{inputs.version_number}}'
Expand All @@ -52,13 +57,12 @@ jobs:
passphrase: ${{ secrets.APIX_BOT_PASSPHRASE }}

update-changelog-header:
needs: [ validate-version-input, run-qa-acceptance-tests, update-examples-reference-in-docs ]
needs: [ release-config, validate-version-input, update-examples-reference-in-docs ]
if: >-
always()
&& inputs.use_existing_tag != 'true'
&& !contains(inputs.version_number, 'pre')
&& needs.validate-version-input.result == 'success'
&& (needs.run-qa-acceptance-tests.result == 'skipped' || needs.run-qa-acceptance-tests.result == 'success')
!cancelled()
&& !contains(needs.*.result, 'failure')
&& needs.release-config.outputs.creates_new_tag == 'true'
&& needs.release-config.outputs.is_official_release == 'true'
uses: ./.github/workflows/run-script-and-commit.yml
with:
script_call: './scripts/update-changelog-header-for-release.sh ${{inputs.version_number}}'
Expand All @@ -68,24 +72,19 @@ jobs:
remote: https://svc-apix-bot:${{ secrets.APIX_BOT_PAT }}@github.com/${{ github.repository }}
gpg_private_key: ${{ secrets.APIX_BOT_GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.APIX_BOT_PASSPHRASE }}
release:

create-tag:
runs-on: ubuntu-latest
needs: [ validate-version-input, run-qa-acceptance-tests, update-examples-reference-in-docs, update-changelog-header ]
# Release is skipped if there are failures in previous steps
if: >-
always()
&& needs.validate-version-input.result == 'success'
&& (needs.run-qa-acceptance-tests.result == 'skipped' || needs.run-qa-acceptance-tests.result == 'success')
&& (needs.update-examples-reference-in-docs.result == 'skipped' || needs.update-examples-reference-in-docs.result == 'success')
&& (needs.update-changelog-header.result == 'skipped' || needs.update-changelog-header.result == 'success')
steps:
needs: [ release-config, validate-version-input, update-examples-reference-in-docs, update-changelog-header ]
if: >-
!cancelled()
&& !contains(needs.*.result, 'failure')
&& needs.release-config.outputs.creates_new_tag == 'true'
steps:
- name: Checkout
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633
with:
ref: ${{ inputs.use_existing_tag == 'true' && inputs.version_number || 'master' }}
- name: Unshallow
run: git fetch --prune --unshallow
ref: 'master'
- name: Get the latest commit SHA
id: get-sha
run: echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
Expand All @@ -96,7 +95,31 @@ jobs:
commit_sha: ${{ steps.get-sha.outputs.sha }}
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
gpg_passphrase: ${{ secrets.PASSPHRASE }}
tag_exists_error: ${{ inputs.use_existing_tag != 'true' }}

run-qa-acceptance-tests:
needs: [ release-config, validate-version-input, update-examples-reference-in-docs, update-changelog-header, create-tag ]
if: >-
!cancelled()
&& !contains(needs.*.result, 'failure')
&& needs.release-config.outputs.runs_tests == 'true'
secrets: inherit
uses: ./.github/workflows/acceptance-tests.yml
with:
atlas_cloud_env: "qa"
ref: ${{ inputs.version_number }}

release:
runs-on: ubuntu-latest
needs: [ validate-version-input, update-examples-reference-in-docs, update-changelog-header, create-tag, run-qa-acceptance-tests ]
# Release is skipped if there are failures in previous steps
if: >-
!cancelled()
&& !contains(needs.*.result, 'failure')
steps:
- name: Checkout
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633
with:
ref: ${{ inputs.version_number }}
- name: Set up Go
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491
with:
Expand All @@ -117,9 +140,13 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

jira-release-version:
if: ${{ !contains(inputs.version_number, 'pre') }}
needs: [ release ]
runs-on: ubuntu-latest
needs: [ release-config, release ]
# if release job is skipped, cancelled, or failed we do not run this job
if: >-
!cancelled()
&& needs.release.result == 'success'
&& needs.release-config.outputs.is_official_release == 'true'
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633
- uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491
Expand Down
16 changes: 16 additions & 0 deletions RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,19 @@ Pre-releases are not needed for a regular release process, but they can be gener
- You will see the release in the [GitHub Release page](https://github.com/mongodb/terraform-provider-mongodbatlas/releases) once the [release action](.github/workflows/release.yml) has completed. HashiCorp has a process in place that will retrieve the latest release from the GitHub repository and add the binaries to the HashiCorp Terraform Registry (more details [here](https://developer.hashicorp.com/terraform/registry/providers/publishing#webhooks)).
- **CDKTF Update - Only for major release, i.e. the left most version digit increment (see this [comment](https://github.com/cdktf/cdktf-repository-manager/pull/202#issuecomment-1602562201))**: Once the provider has been released, we need to update the provider version in our CDKTF. Raise a PR against [cdktf/cdktf-repository-manager](https://github.com/cdktf/cdktf-repository-manager).
- Example PR: [#183](https://github.com/cdktf/cdktf-repository-manager/pull/183)

## FAQ

**What happens if a release execution fails to create the tag but generated automatic commits into master?**

All steps before creating the tag are idempotent, meaning you can run the process again and no additional commits will be generated in the second run.

**What happens if a release execution creates a tag but fails during acceptance tests or creating the release (go releaser step)?**

Once a tag has been created in a previous execution, you can make use of the input `Using an existing tag` to run a new release process.

Depending on the nature of the failure, you may want to introduce new changes into the current release. In this case you must:
- Delete the existing tag.
- Incorporate any new fixes into master.
- Manually trigger the [Generate Changelog workflow](https://github.com/mongodb/terraform-provider-mongodbatlas/actions/workflows/generate-changelog.yml) to remove the current header and including any new entries that have been merged. This will run automatically if you have merged PRs after deleting the tag.
- Trigger a new release process, this will create a tag that includes your latest fixes.

0 comments on commit 1400b8a

Please sign in to comment.