Sync main into dev after v1.1.41 release (#1574) #2567
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
| name: PR Validation | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| on: | |
| pull_request: | |
| branches: | |
| - main | |
| - dev | |
| types: [opened, edited, synchronize, reopened] | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| validate-pr-title: | |
| name: Validate PR Title Format | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Check PR title format | |
| env: | |
| PR_TITLE: "${{ github.event.pull_request.title }}" | |
| run: | | |
| echo "Checking PR title: $PR_TITLE" | |
| # Check for issue reference (#number) | |
| if ! echo "$PR_TITLE" | grep -qE '\(#[0-9]+\)$'; then | |
| echo "ERROR: PR title must end with issue reference '(#<number>)'" | |
| echo "Expected format: '<description> (#<number>)'" | |
| echo "Current title: $PR_TITLE" | |
| exit 1 | |
| fi | |
| # Check for colons in title (not allowed) | |
| if echo "$PR_TITLE" | grep -qE '^[^:]+:'; then | |
| echo "ERROR: PR title should not contain colons before the issue reference" | |
| echo "Expected format: '<description> (#<number>)' (NO colons)" | |
| exit 1 | |
| fi | |
| echo "PR title format is valid" | |
| validate-pr-assignee: | |
| name: Validate PR Assignee | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Check PR has assignee | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| PR_NUMBER: ${{ github.event.pull_request.number }} | |
| REPO: ${{ github.repository }} | |
| run: | | |
| set -euo pipefail | |
| # Fetch live PR state via API — event payload may not reflect assignees | |
| # set immediately after creation (webhook fires before GitHub processes mutations) | |
| count=$(gh api "repos/$REPO/pulls/$PR_NUMBER" --jq '.assignees | length') | |
| if [[ "$count" -gt 0 ]]; then | |
| echo "PR has $count assignee(s):" | |
| gh api "repos/$REPO/pulls/$PR_NUMBER" --jq '.assignees[].login' | |
| exit 0 | |
| fi | |
| echo "ERROR: PR must have at least one assignee" | |
| exit 1 | |
| validate-pr-labels: | |
| name: Validate PR Labels | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Check PR has component label | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| PR_NUMBER: ${{ github.event.pull_request.number }} | |
| REPO: ${{ github.repository }} | |
| run: | | |
| set -euo pipefail | |
| # Fetch live PR state via API — event payload may not reflect labels | |
| # set immediately after creation (webhook fires before GitHub processes mutations) | |
| labels=$(gh api "repos/$REPO/pulls/$PR_NUMBER" --jq '.labels[].name') | |
| if echo "$labels" | grep -q "component:"; then | |
| echo "PR has component label: $(echo "$labels" | grep "component:" | head -1)" | |
| exit 0 | |
| fi | |
| echo "ERROR: PR must have at least one component label (component:*)" | |
| echo "Available component labels: component:cli, component:infrastructure, component:runtime-core, etc." | |
| exit 1 | |
| validate-pr-body-references: | |
| name: Validate PR Body Reference List Style | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| - name: Check for comma-packed issue references | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| PR_NUMBER: ${{ github.event.pull_request.number }} | |
| REPO: ${{ github.repository }} | |
| run: | | |
| set -euo pipefail | |
| body=$(gh api "repos/$REPO/pulls/$PR_NUMBER" --jq '.body // ""') | |
| echo "$body" | bash scripts/checks/check-pr-references.sh |