entry-pr-change-orchestrate.ymlΒΆ

name: "πŸ”€ Pull Request"
run-name: >-
  ${{ github.event_name }} / PR #${{ github.event.pull_request.number }} / ${{ github.event.action }} / ${{ github.event.pull_request.head.label }}

on:
  pull_request:
    types:
      - opened
      - synchronize
      - reopened
      - ready_for_review
      - labeled
  pull_request_target:
    types:
      - opened
      - synchronize
      - reopened
      - ready_for_review
      - labeled

concurrency:
  group: pr-ci-${{ github.repository }}-${{ github.event_name }}-pr-${{ github.event.pull_request.number }}
  cancel-in-progress: true

permissions:
  contents: read

jobs:
  detect-pr-scope:
    name: πŸ”Ž Detect PR scope
    if: ${{ github.event.pull_request.draft == false && (github.event_name == 'pull_request' || github.event.pull_request.head.repo.full_name != github.repository) }}
    runs-on: ubuntu-26.04
    outputs:
      scope: ${{ steps.resolve.outputs.scope }}
      run_ci_orchestrator: ${{ steps.resolve.outputs.run_ci_orchestrator }}
    steps:
      - name: ⬇️ Checkout
        uses: actions/checkout@v7.0.0

      - name: πŸ” Resolve PR scope
        id: resolve
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          REPOSITORY: ${{ github.repository }}
          PR_NUMBER: ${{ github.event.pull_request.number }}
        run: ./scripts/meta/resolve/pr/scope.sh

  validation:
    name: 🧭 PR scope
    needs: detect-pr-scope
    if: ${{ github.event_name == 'pull_request' || github.event.pull_request.head.repo.full_name != github.repository }}
    uses: ./.github/workflows/call-validation.yml
    with:
      pr_scope: ${{ needs.detect-pr-scope.outputs.scope }}

  pr-scope-gate:
    name: 🚦 Gate PR scope
    needs:
      - detect-pr-scope
      - validation
    if: ${{ needs.detect-pr-scope.outputs.run_ci_orchestrator == 'false' }}
    runs-on: ubuntu-26.04
    steps:
      - name: βœ… Confirm lightweight PR scope
        shell: bash
        run: |
          set -euo pipefail
          echo "Lightweight PR scope '${{ needs.detect-pr-scope.outputs.scope }}' passed."

  detect-affected-roles:
    name: 🧭 Detect affected roles
    needs:
      - detect-pr-scope
      - validation
    if: ${{ needs.detect-pr-scope.outputs.run_ci_orchestrator == 'true' }}
    runs-on: ubuntu-26.04
    outputs:
      whitelist: ${{ steps.resolve.outputs.whitelist }}
    steps:
      - name: ⬇️ Checkout
        uses: actions/checkout@v7.0.0
        with:
          fetch-depth: 0

      - name: πŸ”§ Set up Python
        uses: actions/setup-python@v6
        with:
          python-version: "3.12"
          cache: pip
          cache-dependency-path: pyproject.toml

      - name: πŸ“¦ Install project (host venv)
        shell: bash
        run: make install

      - name: πŸ” Resolve affected roles
        id: resolve
        shell: bash
        env:
          SUBSET_LABELED: ${{ contains(github.event.pull_request.labels.*.name, '🧩 Subset') }}
          PR_BODY: ${{ github.event.pull_request.body }}
        run: bash scripts/github/resolve/pr_affected_roles.sh

  ci-orchestrator:
    needs:
      - detect-pr-scope
      - validation
      - detect-affected-roles
    if: ${{ github.event_name == 'pull_request' && needs.detect-pr-scope.outputs.run_ci_orchestrator == 'true' }}
    permissions:
      actions: read
      contents: read
      packages: write
      security-events: write
      issues: write
    uses: ./.github/workflows/call-orchestrator.yml
    with:
      distros: "arch debian ubuntu fedora centos"
      whitelist: ${{ needs.detect-affected-roles.outputs.whitelist }}
      trusted_pr: ${{ contains(github.event.pull_request.labels.*.name, 'πŸ›‘οΈ Trusted') }}

  prepare-fork-merge-ref:
    needs:
      - detect-pr-scope
      - validation
    if: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.head.repo.full_name != github.repository && needs.detect-pr-scope.outputs.run_ci_orchestrator == 'true' }}
    runs-on: ubuntu-26.04
    outputs:
      checkout_ref: ${{ steps.out.outputs.checkout_ref }}
      image_tag: ${{ steps.out.outputs.image_tag }}
      trusted: ${{ contains(github.event.pull_request.labels.*.name, 'πŸ›‘οΈ Trusted') }}
    steps:
      - name: ⬇️ Checkout
        uses: actions/checkout@v7.0.0

      - name: πŸ” Resolve merge ref and image tag
        id: out
        env:
          PR_NUMBER: ${{ github.event.pull_request.number }}
          PR_MERGE_SHA: ${{ github.event.pull_request.merge_commit_sha || '' }}
        run: ./scripts/meta/resolve/pr/merge_ref.sh

  build-ci-images-fork:
    needs: prepare-fork-merge-ref
    permissions:
      contents: read
      packages: write
    uses: ./.github/workflows/call-images-build-ci.yml
    with:
      distros: "arch debian ubuntu fedora centos"
      checkout_ref: ${{ needs.prepare-fork-merge-ref.outputs.trusted == 'true' && github.event.pull_request.head.sha || needs.prepare-fork-merge-ref.outputs.checkout_ref }}
      source_repository: ${{ needs.prepare-fork-merge-ref.outputs.trusted == 'true' && github.event.pull_request.head.repo.full_name || github.repository }}
      image_tag: ${{ needs.prepare-fork-merge-ref.outputs.image_tag }}
      concurrency_channel: pr-target-build-producer
      allow_unsafe_checkout: true

  images-mirror-missing-fork:
    needs: prepare-fork-merge-ref
    permissions:
      contents: read
      packages: write
    uses: ./.github/workflows/call-images-mirror-missing.yml
    with:
      repo_root: _pr_source
      source_repository: ${{ github.repository }}
      source_ref: ${{ needs.prepare-fork-merge-ref.outputs.checkout_ref }}
      source_path: _pr_source
      concurrency_channel: pr-target-mirror-producer
      concurrency_key: pr-${{ github.event.pull_request.number }}
      allow_unsafe_checkout: true
    secrets: inherit