-
Notifications
You must be signed in to change notification settings - Fork 23
workflow and actions for automatically labelling PRs based on changelog fragments #165
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 1 commit
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next
Next commit
First shot at splitting off evaluator
- Loading branch information
commit 210050f21d321ea7909f8ff9059b804eb1cde9bc
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| --- | ||
| name: Changelog based PR evaluator | ||
| author: Mark Chappell (tremble) | ||
| branding: | ||
| icon: git-branch | ||
| color: gray-dark | ||
| description: | | ||
| This action evaluates the contents of changelog fragments in "changelogs/fragments/" to assess | ||
| which branches it may be appropriate to backport a change to. | ||
|
|
||
| A PR is evaluated as needing a "major release" if it includes at least one of "major_changes", | ||
| "breaking_changes", or "removed_features". | ||
|
|
||
| A PR is evaluated as needing a "minor release" if it includes at least one of "minor_changes" or | ||
| "deprecated_features". | ||
|
|
||
| A PR is evaluated as being a "bugfix" PR if it includes at least one of "bugfixes" or | ||
| "security_fixes". | ||
|
|
||
| The output values of this action are "bash-ian" booleans ("0" == True, anything else == False) | ||
|
|
||
| outputs: | ||
| major_release: | ||
| description: Whether the changelogs indicate that a major release would be needed. | ||
| value: ${{ steps.evaluate.outputs.major }} | ||
| minor_release: | ||
| description: Whether the changelogs indicate that a minor release would be needed. | ||
| value: ${{ steps.evaluate.outputs.minor }} | ||
| bugfix_release: | ||
| description: Whether the changelogs indicate that a the PR includes bugfixes. | ||
| value: ${{ steps.evaluate.outputs.bugfix }} | ||
|
|
||
| runs: | ||
| using: composite | ||
| steps: | ||
| - uses: actions/checkout@v2 | ||
| id: checkout | ||
| - name: Fetch change types from changelog fragments | ||
| id: evaluate | ||
| shell: bash {0} | ||
| run: | | ||
| gh pr -R "${GITHUB_REPOSITORY}" diff "${{ github.event.pull_request.number }}" --name-only | \ | ||
| grep -E '^changelogs/fragments/' | \ | ||
| while read -r line | ||
| do cat "${line}" | \ | ||
| python -c 'import sys, yaml; change = yaml.safe_load(sys.stdin.read()) ; print("\n".join(change.keys()));' \ | ||
| | tee -a all-changelog-types | ||
| done | ||
| # Beware, these are bash-ian booleans: "true == 0" | ||
| grep -qE '(release_summary|breaking_changes|major_changes|removed_features)' all-changelog-types ; echo "major=${?}" >>${GITHUB_OUTPUT} | ||
| grep -qE '(deprecated_features|minor_changes)' all-changelog-types ; echo "minor=${?}" >>${GITHUB_OUTPUT} | ||
| grep -qE '(bugfixes|security_fixes)' all-changelog-types ; echo "bugfix=${?}" >>${GITHUB_OUTPUT} | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| --- | ||
| name: Apply backporting labels | ||
| author: Mark Chappell (tremble) | ||
| branding: | ||
| icon: git-branch | ||
| color: gray-dark | ||
| description: | | ||
| Applies backporting labels to a PR. | ||
|
|
||
| inputs: | ||
| purge_labels: | ||
| description: Whether to purge existing labels | ||
| required: false | ||
| default: false | ||
| purge_prefix: | ||
| description: The prefix used when purging labels | ||
| required: false | ||
| default: 'backport-' | ||
| label_to_add: | ||
| description: The label(s) to be applied to the PR | ||
| required: true | ||
|
|
||
| runs: | ||
| using: composite | ||
| steps: | ||
| - name: Strip existing labels and add new labels | ||
| id: label-strip-add | ||
tremble marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| # If breaking_changes or major_changes are pushed, then we always apply do_not_backport | ||
| # and strip any existing backport-* labels | ||
| if: ${{ inputs.purge_labels }} | ||
| shell: bash {0} | ||
| run: | | ||
| # If this includes breaking changes, then set the do_not_backport label and remove all | ||
| # labels starting with "backport-". | ||
| CURRENT_LABELS=$( | ||
| gh pr -R "${GITHUB_REPOSITORY}" view "${{ github.event.pull_request.number }}" \ | ||
| --json labels \ | ||
| --jq '[.labels[] | select(.name | startswith("${{ inputs.purge_prefix }}"))] | map(.name) | join(",")' | ||
| ) | ||
| echo "Apply '${{ inputs.label_to_add }}' (remove '${CURRENT_LABELS}')" | ||
| if [[ -n ${CURRENT_LABELS} ]] ; then | ||
| gh pr -R "${GITHUB_REPOSITORY}" edit "${{ github.event.pull_request.number }}" \ | ||
| --add-label ${{ inputs.label_to_add }} \ | ||
| --remove-label "${CURRENT_LABELS}" | ||
| else | ||
| gh pr -R "${GITHUB_REPOSITORY}" edit "${{ github.event.pull_request.number }}" \ | ||
| --add-label ${{ inputs.label_to_add }} | ||
| fi | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
|
|
||
| - name: Apply labels | ||
| id: label-add | ||
tremble marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| if: ${{ ! inputs.purge_labels }} | ||
| shell: bash {0} | ||
| run: | | ||
| echo "Apply '${{ inputs.label_to_add }}'" | ||
| gh pr -R "${GITHUB_REPOSITORY}" edit "${{ github.event.pull_request.number }}" \ | ||
| --add-label ${{ inputs.label_to_add }} | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,107 @@ | ||
| --- | ||
| name: Apply labels for backporting | ||
|
|
||
| on: | ||
| workflow_call: | ||
| inputs: | ||
| label_major_release: | ||
| default: 'do_not_backport' | ||
| required: false | ||
| type: string | ||
| description: | | ||
| The label to apply if the PR includes a change that would necessitate a major release. | ||
| label_minor_release: | ||
| required: true | ||
| type: string | ||
| description: | | ||
| The label to apply if the PR only includes a change that would necessitate a minor | ||
| release. This will also be applied by default if the PR doesn't necessitate a major | ||
| release. | ||
| label_bugfix_release: | ||
| required: true | ||
| type: string | ||
| description: | | ||
| The label to apply if the PR only includes a bugfix or security release. | ||
| label_skip: | ||
| default: 'do_not_backport' | ||
| required: false | ||
| type: string | ||
| description: | | ||
| If this label has been applied, then the PR will not be re-assessed. | ||
| label_mergeit: | ||
| default: 'mergeit' | ||
| required: false | ||
| type: string | ||
| description: | | ||
| Which label will be used to trigger labelling for minor/bugfix backporting. | ||
| We look for major releases when a change is pushed, and minor/bugfixes when the PR | ||
| has been approved for merging and the mergeit label has been applied to trigger | ||
| the merge. | ||
|
|
||
| jobs: | ||
| changelog-types: | ||
| # We always skip if do_not_backport has previously been applied. | ||
| # Otherwise, if someone applies 'mergeit', opens the PR, or pushes a new commit | ||
| # we'll examine the contents of changelog fragments to try to guess the best backport strategy. | ||
| if: ${{ | ||
| ! contains(github.event.pull_request.labels.*.name, inputs.label_skip) | ||
| && ( | ||
| (github.event.action == 'labeled' && github.event.label.name == inputs.label_mergeit) | ||
| || (github.event.action == 'synchronize') | ||
| || (github.event.action == 'opened') | ||
| ) | ||
| }} | ||
| permissions: | ||
| pull-requests: read | ||
| runs-on: ubuntu-latest | ||
| outputs: | ||
| no_backport: ${{ steps.evaluate.outputs.major_release }} | ||
| bugfix: ${{ steps.evaluate.outputs.bugfix_release }} | ||
| minor_only: ${{ steps.evaluate.outputs.minor_release }} | ||
| steps: | ||
| - name: Evaluate change types | ||
| id: evaluate | ||
| uses: ansible-network/github_actions/.github/actions/changelog_evaluator@main | ||
|
|
||
| changelog-labeling: | ||
| permissions: | ||
| pull-requests: write | ||
| runs-on: ubuntu-latest | ||
| needs: | ||
| - changelog-types | ||
| steps: | ||
| - name: Strip tags for backporting and apply do_not_backport | ||
| id: no-backport | ||
tremble marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| # If breaking_changes or major_changes are pushed, then we always apply do_not_backport | ||
| # and strip any existing backport-* labels | ||
| if: ${{ needs.changelog-types.outputs.no_backport == '0' }} | ||
| uses: ansible-network/github_actions/.github/actions/changelog_labeller@main | ||
| with: | ||
| purge_labels: true | ||
| label_to_add: ${{ inputs.label_major_release }} | ||
|
|
||
| - name: Apply tag for backporting to at least the most recent major release | ||
| id: minor-only | ||
tremble marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| if: ${{ | ||
| (github.event.action == 'labeled' && github.event.label.name == inputs.label_mergeit ) | ||
| && ! ( needs.changelog-types.outputs.no_backport == '0' ) | ||
| && ( | ||
| ( needs.changelog-types.outputs.minor_only == '0' ) | ||
| || ! (needs.changelog-types.outputs.bugfix == '0' ) | ||
| ) | ||
| }} | ||
| uses: ansible-network/github_actions/.github/actions/changelog_labeller@main | ||
| with: | ||
| label_to_add: ${{ inputs.label_minor_release }} | ||
|
|
||
| - name: Apply tag for backporting to at least the two most recent major releases | ||
| id: security-or-bugfix | ||
tremble marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| if: ${{ | ||
| (github.event.action == 'labeled' && github.event.label.name == inputs.label_mergeit ) | ||
| && ! ( needs.changelog-types.outputs.no_backport == '0' ) | ||
| && ! ( needs.changelog-types.outputs.minor_only == '0' ) | ||
| && ( needs.changelog-types.outputs.bugfix == '0' ) | ||
| }} | ||
| uses: ansible-network/github_actions/.github/actions/changelog_labeller@main | ||
| with: | ||
| label_to_add: ${{ inputs.label_minor_release }},${{ inputs.label_bugfix_release }} | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.