| name: validate-pr |
| |
| # Default to 'contents: read', which grants actions to read commits. |
| # |
| # If any permission is set, any permission not included in the list is |
| # implicitly set to "none". |
| # |
| # see https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions |
| permissions: |
| contents: read |
| |
| on: |
| pull_request: |
| types: [opened, edited, labeled, unlabeled, synchronize] |
| |
| jobs: |
| check-labels: |
| runs-on: ubuntu-24.04 |
| timeout-minutes: 120 # guardrails timeout for the whole job |
| steps: |
| - name: Missing `area/` label |
| if: always() && contains(join(github.event.pull_request.labels.*.name, ','), 'impact/') && !contains(join(github.event.pull_request.labels.*.name, ','), 'area/') |
| run: | |
| echo "::error::Every PR with an 'impact/*' label should also have an 'area/*' label" |
| exit 1 |
| - name: Missing `kind/` label |
| if: always() && contains(join(github.event.pull_request.labels.*.name, ','), 'impact/') && !contains(join(github.event.pull_request.labels.*.name, ','), 'kind/') |
| run: | |
| echo "::error::Every PR with an 'impact/*' label should also have a 'kind/*' label" |
| exit 1 |
| - name: OK |
| run: exit 0 |
| |
| check-changelog: |
| runs-on: ubuntu-24.04 |
| timeout-minutes: 120 # guardrails timeout for the whole job |
| env: |
| HAS_IMPACT_LABEL: ${{ contains(join(github.event.pull_request.labels.*.name, ','), 'impact/') }} |
| PR_BODY: | |
| ${{ github.event.pull_request.body }} |
| steps: |
| - name: Check changelog description |
| run: | |
| # Extract the `markdown changelog` note code block |
| block=$(echo -n "$PR_BODY" | tr -d '\r' | awk '/^```markdown changelog$/{flag=1;next}/^```$/{flag=0}flag') |
| |
| # Strip empty lines |
| desc=$(echo "$block" | awk NF) |
| |
| if [ "$HAS_IMPACT_LABEL" = "true" ]; then |
| if [ -z "$desc" ]; then |
| echo "::error::Changelog section is empty. Please provide a description for the changelog." |
| exit 1 |
| fi |
| |
| len=$(echo -n "$desc" | wc -c) |
| if [[ $len -le 6 ]]; then |
| echo "::error::Description looks too short: $desc" |
| exit 1 |
| fi |
| else |
| if [ -n "$desc" ]; then |
| echo "::error::PR has a changelog description, but no changelog label" |
| echo "::error::Please add the relevant 'impact/' label to the PR or remove the changelog description" |
| exit 1 |
| fi |
| fi |
| |
| echo "This PR will be included in the release notes with the following note:" |
| echo "$desc" |
| |
| check-pr-branch: |
| runs-on: ubuntu-24.04 |
| timeout-minutes: 120 # guardrails timeout for the whole job |
| env: |
| PR_TITLE: ${{ github.event.pull_request.title }} |
| steps: |
| # Backports or PR that target a release branch directly should mention the target branch in the title, for example: |
| # [X.Y backport] Some change that needs backporting to X.Y |
| # [X.Y] Change directly targeting the X.Y branch |
| - name: Check release branch |
| id: title_branch |
| run: | |
| # get the intended major version prefix ("[27.1 backport]" -> "27.") from the PR title. |
| [[ "$PR_TITLE" =~ ^\[([0-9]*\.)[^]]*\] ]] && branch="${BASH_REMATCH[1]}" |
| |
| # get major version prefix from the release branch ("27.x -> "27.") |
| [[ "$GITHUB_BASE_REF" =~ ^([0-9]*\.) ]] && target_branch="${BASH_REMATCH[1]}" || target_branch="$GITHUB_BASE_REF" |
| |
| if [[ "$target_branch" != "$branch" ]] && ! [[ "$GITHUB_BASE_REF" == "master" && "$branch" == "" ]]; then |
| echo "::error::PR is opened against the $GITHUB_BASE_REF branch, but its title suggests otherwise." |
| exit 1 |
| fi |