Pull Request Convention Checks #20945
Workflow file for this run
This file contains 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
name: Pull Request Convention Checks | |
on: | |
# This is a dangerous event trigger as it causes the workflow to run in the | |
# context of the target repository. | |
# Avoid checking out the head of the pull request or building code from the | |
# pull request whenever this trigger is used. | |
# Since we do not have a checkout step in this workflow, this is an | |
# acceptable use of this trigger. | |
pull_request_target: | |
types: | |
- opened | |
- edited | |
- reopened | |
- ready_for_review | |
- synchronize | |
merge_group: | |
types: | |
- checks_requested | |
env: | |
# Allow more retries for network requests in cargo (downloading crates) and | |
# rustup (installing toolchains). This should help to reduce flaky CI failures | |
# from transient network timeouts or other issues. | |
CARGO_NET_RETRY: 10 | |
RUSTUP_MAX_RETRIES: 10 | |
jobs: | |
pr_title_conventional_commit_check: | |
name: Verify PR title follows conventional commit standards | |
runs-on: ubuntu-latest | |
steps: | |
- name: Install Rust | |
uses: dtolnay/rust-toolchain@master | |
with: | |
toolchain: stable | |
- uses: baptiste0928/[email protected] | |
with: | |
crate: cocogitto | |
- name: Verify PR title follows conventional commit standards | |
if: ${{ github.event_name == 'pull_request_target' }} | |
shell: bash | |
env: | |
TITLE: ${{ github.event.pull_request.title }} | |
run: cog verify "$TITLE" | |
- name: Verify commit message follows conventional commit standards | |
if: ${{ github.event_name == 'merge_group' }} | |
shell: bash | |
env: | |
COMMIT_MESSAGE: ${{ github.event.merge_group.head_commit.message }} | |
run: cog verify "$COMMIT_MESSAGE" | |
pr_linked_issues_check: | |
name: Verify PR contains one or more linked issues | |
runs-on: ubuntu-latest | |
steps: | |
- name: Skip check for merge queue | |
if: ${{ github.event_name == 'merge_group' }} | |
shell: bash | |
run: echo "Skipping PR linked issues check for merge queue" | |
- name: Generate GitHub app token | |
id: generate_app_token | |
if: ${{ github.event_name == 'pull_request_target' }} | |
uses: actions/create-github-app-token@v1 | |
with: | |
app-id: ${{ secrets.HYPERSWITCH_BOT_APP_ID }} | |
private-key: ${{ secrets.HYPERSWITCH_BOT_APP_PRIVATE_KEY }} | |
owner: ${{ github.event.repository.owner.login }} | |
- name: Verify PR contains one or more linked issues | |
if: ${{ github.event_name == 'pull_request_target' }} | |
shell: bash | |
env: | |
GH_TOKEN: ${{ steps.generate_app_token.outputs.token }} | |
run: | | |
# GitHub does not provide information about linked issues for a pull request via the REST API. | |
# This information is available only within the GraphQL API. | |
# Obtain issue number and repository name with owner (in the `owner/repo` format) for all linked issues | |
query='query ($owner: String!, $repository: String!, $prNumber: Int!) { | |
repository(owner: $owner, name: $repository) { | |
pullRequest(number: $prNumber) { | |
closingIssuesReferences(first: 10) { | |
nodes { | |
number | |
repository { | |
nameWithOwner | |
} | |
} | |
} | |
} | |
} | |
}' | |
# Obtain linked issues in the `owner/repo#issue_number` format, one issue per line. | |
# The variable contains an empty string if the pull request has no linked issues. | |
linked_issues="$( | |
gh api graphql \ | |
--raw-field "query=${query}" \ | |
--field 'owner=${{ github.event.repository.owner.login }}' \ | |
--field 'repository=${{ github.event.repository.name }}' \ | |
--field 'prNumber=${{ github.event.pull_request.number }}' \ | |
--jq '.data.repository.pullRequest.closingIssuesReferences.nodes[] | "\(.repository.nameWithOwner)#\(.number)"' | |
)" | |
if [[ -z "${linked_issues}" ]]; then | |
echo "::error::PR does not contain any linked issues" | |
exit 1 | |
else | |
echo "PR contains at least one linked issue" | |
fi | |
while IFS= read -r issue; do | |
# Split `${issue}` by `#` to obtain repository with owner (in `owner/repository` format) and issue number | |
IFS='#' read -r repository_with_owner issue_number <<< "${issue}" | |
issue_state="$(gh issue view --repo "${repository_with_owner}" --json 'state' "${issue_number}" --jq '.state')" | |
# Transform `${issue_state}` to lowercase for comparison | |
if [[ "${issue_state,,}" != 'open' ]]; then | |
echo "::error::At least one of the linked issues is not open" | |
exit 1 | |
fi | |
done <<< "${linked_issues}" | |
pr_labeler: | |
name: Attach suitable labels to PR | |
if: ${{ github.event_name == 'pull_request_target' }} | |
runs-on: ubuntu-latest | |
steps: | |
- name: Generate GitHub app token | |
id: generate_app_token | |
uses: actions/create-github-app-token@v1 | |
with: | |
app-id: ${{ secrets.HYPERSWITCH_BOT_APP_ID }} | |
private-key: ${{ secrets.HYPERSWITCH_BOT_APP_PRIVATE_KEY }} | |
owner: ${{ github.event.repository.owner.login }} | |
- name: Get files changed | |
env: | |
GH_TOKEN: ${{ steps.generate_app_token.outputs.token }} | |
shell: bash | |
run: | | |
migration_and_schema_changes=false | |
openapi_changes=false | |
files_changed="$(gh api --header "Accept: application/vnd.github+json" --header "X-GitHub-Api-Version: 2022-11-28" --paginate https://api.github.com/repos/juspay/hyperswitch/pulls/${{ github.event.pull_request.number }}/files --jq '.[] | .filename')" | |
if echo "${files_changed}" | grep --quiet --extended-regexp '(^(migrations|v2_migrations)/.*/(up|down)\.sql$|^crates/diesel_models/src/(schema|schema_v2).rs$)' ; then | |
migration_and_schema_changes='true' | |
fi | |
if echo "${files_changed}" | grep --quiet --extended-regexp '^(api-reference|api-reference-v2)/openapi_spec.json$'; then | |
openapi_changes='true' | |
fi | |
echo "migration_and_schema_changes=${migration_and_schema_changes}" >> "${GITHUB_ENV}" | |
echo "openapi_changes=${openapi_changes}" >> "${GITHUB_ENV}" | |
- name: Add/Remove 'M-database-changes' based on Migration or Schema changes | |
shell: bash | |
env: | |
GH_TOKEN: ${{ steps.generate_app_token.outputs.token }} | |
run: | | |
if ${{ env.migration_and_schema_changes == 'true' }}; then | |
gh --repo ${{ github.event.repository.full_name }} pr edit --add-label 'M-database-changes' ${{ github.event.pull_request.number }} | |
else | |
gh --repo ${{ github.event.repository.full_name }} pr edit --remove-label 'M-database-changes' ${{ github.event.pull_request.number }} | |
fi | |
- name: Add/Remove 'M-api-contract-changes' based on OpenAPI Spec changes | |
shell: bash | |
env: | |
GH_TOKEN: ${{ steps.generate_app_token.outputs.token }} | |
run: | | |
if ${{ env.openapi_changes == 'true' }}; then | |
gh --repo ${{ github.event.repository.full_name }} pr edit --add-label 'M-api-contract-changes' ${{ github.event.pull_request.number }} | |
else | |
gh --repo ${{ github.event.repository.full_name }} pr edit --remove-label 'M-api-contract-changes' ${{ github.event.pull_request.number }} | |
fi |