ci/workflows: add build automation, release pipeline, and branch protection rules #2
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: Protect Develop Branch | |
| # Enforces that all PRs targeting `develop` meet contribution standards. | |
| # This workflow acts as the mandatory status check that must pass before | |
| # any PR can be merged into the develop branch. | |
| on: | |
| pull_request: | |
| branches: | |
| - develop | |
| types: | |
| - opened | |
| - reopened | |
| - synchronize | |
| - edited | |
| permissions: | |
| pull-requests: write | |
| contents: read | |
| jobs: | |
| # ── 1. Verify the PR originates from a personal fork ────────────────────── | |
| verify-fork-origin: | |
| name: Verify Fork Origin | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check that PR comes from a fork | |
| env: | |
| HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name }} | |
| BASE_REPO: ${{ github.event.pull_request.base.repo.full_name }} | |
| run: | | |
| echo "Head repository : $HEAD_REPO" | |
| echo "Base repository : $BASE_REPO" | |
| if [ "$HEAD_REPO" = "$BASE_REPO" ]; then | |
| echo "::error::PRs must be submitted from a personal fork, not from a branch in the upstream repository." | |
| echo "::error::Please fork the repository, push your changes there, and open a PR from your fork." | |
| exit 1 | |
| fi | |
| echo "PR originates from a fork — OK" | |
| # ── 2. Validate PR title follows Conventional Commits ───────────────────── | |
| validate-pr-title: | |
| name: Validate PR Title | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check PR title format | |
| env: | |
| PR_TITLE: ${{ github.event.pull_request.title }} | |
| run: | | |
| echo "PR Title: $PR_TITLE" | |
| # Conventional Commits pattern: | |
| # <type>(optional scope): <description> | |
| PATTERN='^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\([a-zA-Z0-9_\-]+\))?: .{1,100}$' | |
| if ! echo "$PR_TITLE" | grep -qE "$PATTERN"; then | |
| echo "::error::PR title does not follow Conventional Commits format." | |
| echo "::error::Expected: <type>(scope): <description>" | |
| echo "::error::Valid types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert" | |
| echo "::error::Example: fix(qcom_usb): resolve null pointer dereference on disconnect" | |
| exit 1 | |
| fi | |
| echo "PR title format is valid — OK" | |
| # ── 3. Validate PR description is not empty ─────────────────────────────── | |
| validate-pr-description: | |
| name: Validate PR Description | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check PR body is present | |
| env: | |
| PR_BODY: ${{ github.event.pull_request.body }} | |
| run: | | |
| if [ -z "$(echo "$PR_BODY" | tr -d '[:space:]')" ]; then | |
| echo "::error::PR description is empty." | |
| echo "::error::Please describe what this PR changes and why." | |
| exit 1 | |
| fi | |
| WORD_COUNT=$(echo "$PR_BODY" | wc -w) | |
| if [ "$WORD_COUNT" -lt 10 ]; then | |
| echo "::error::PR description is too short ($WORD_COUNT words). Please provide a meaningful description." | |
| exit 1 | |
| fi | |
| echo "PR description is present — OK" | |
| # ── 4. Validate source branch naming convention ─────────────────────────── | |
| validate-branch-name: | |
| name: Validate Branch Name | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check branch naming convention | |
| env: | |
| BRANCH: ${{ github.head_ref }} | |
| run: | | |
| echo "Source branch: $BRANCH" | |
| # Allowed patterns: | |
| # feat/<description> | |
| # fix/<description> | |
| # docs/<description> | |
| # refactor/<description> | |
| # test/<description> | |
| # chore/<description> | |
| # ci/<description> | |
| PATTERN='^(feat|fix|docs|refactor|test|chore|ci|perf|build|revert)\/[a-zA-Z0-9._\-]+$' | |
| if ! echo "$BRANCH" | grep -qE "$PATTERN"; then | |
| echo "::error::Branch name '$BRANCH' does not follow the required naming convention." | |
| echo "::error::Expected format: <type>/<description>" | |
| echo "::error::Valid types: feat, fix, docs, refactor, test, chore, ci, perf, build, revert" | |
| echo "::error::Example: fix/qcom-usb-null-deref" | |
| exit 1 | |
| fi | |
| echo "Branch name is valid — OK" | |
| # ── 5. Summary gate — all checks must pass ──────────────────────────────── | |
| all-checks-passed: | |
| name: All Develop Branch Checks Passed | |
| runs-on: ubuntu-latest | |
| needs: | |
| - verify-fork-origin | |
| - validate-pr-title | |
| - validate-pr-description | |
| - validate-branch-name | |
| steps: | |
| - name: Confirm all checks passed | |
| run: | | |
| echo "All mandatory checks passed. This PR is eligible for review and merge into develop." |