Skip to content

ci(gh-aw): bump apm-action v1.5.0 -> v1.6.0 for plugin-bundle defenses #743

ci(gh-aw): bump apm-action v1.5.0 -> v1.6.0 for plugin-bundle defenses

ci(gh-aw): bump apm-action v1.5.0 -> v1.6.0 for plugin-bundle defenses #743

Workflow file for this run

# Merge Gate -- single-authority orchestrator that aggregates ALL required
# checks into one verdict for BOTH PR-time and merge-queue contexts.
# Branch protection / merge-queue ruleset requires only this check; this
# workflow polls the Checks API for all underlying checks.
#
# Why this file exists:
# GitHub's required-status-checks model is name-based, not workflow-based.
# Without this gate, every required check would need to be listed in the
# ruleset (and listed again for the merge-queue ruleset) -- adding or
# renaming a check meant editing rulesets. With this gate, the ruleset
# requires only 'gate' and the gate aggregates whatever underlying checks
# we declare in EXPECTED_CHECKS for each event context.
#
# Why both pull_request and merge_group triggers:
# The merge-queue ruleset also requires 'gate'. Without a merge_group
# trigger, the gate check would never fire against the merge-queue temp
# branch SHA and PRs would sit in the queue with 'gate' stuck in
# "Expected -- Waiting for status to be reported" indefinitely
# (observed on PR #899). The merge_group trigger fires the same gate
# logic against the temp branch SHA and aggregates the merge-queue-time
# checks (ci.yml + ci-integration.yml).
#
# Why no pull_request_target dual trigger:
# We tried dual-trigger redundancy in PR #865 to harden against rare
# dropped 'pull_request' webhook deliveries (observed once on PR #856).
# It backfired: 'concurrency: cancel-in-progress' produced TWO check-runs
# per SHA -- one SUCCESS and one CANCELLED -- which poisons branch
# protection's status-check rollup ('CANCELLED' counts as failure ->
# PR BLOCKED). pull_request and merge_group are different event channels
# that target different SHAs, so they don't collide.
#
# Recovery if a webhook is dropped:
# pull_request context:
# - Push an empty commit: git commit --allow-empty -m 'retrigger' && git push
# - Or trigger manually: gh workflow run merge-gate.yml -f pr_number=NNN
# - Or close + reopen the PR.
# merge_group context (NB: pushing a commit will not retrigger the
# merge_group event, only pull_request):
# - Remove the PR from the merge queue and re-add it.
name: Merge Gate
on:
pull_request:
branches: [ main ]
merge_group:
branches: [ main ]
types: [ checks_requested ]
workflow_dispatch:
inputs:
pr_number:
description: 'PR number to re-run the gate against'
required: true
type: string
# Dedup pushes to the same PR / merge-queue entry: cancel any older
# in-flight gate run on the same head. In merge_group context, github.ref
# is refs/heads/gh-readonly-queue/main/pr-N-<sha>, which is unique per
# queue entry -- so cancel-in-progress only cancels rapid push-after-push
# on the same temp branch, never across PR <-> merge_group channels.
concurrency:
group: merge-gate-${{ github.event.pull_request.number || inputs.pr_number || github.ref }}
cancel-in-progress: true
permissions:
contents: read
checks: read
pull-requests: read
jobs:
gate:
name: gate
runs-on: ubuntu-24.04
# Job timeout sized above the poll budget (TIMEOUT_MIN below) to leave
# headroom for setup/teardown without false-failing the gate.
timeout-minutes: 60
steps:
- name: Resolve head SHA
id: sha
env:
GH_TOKEN: ${{ github.token }}
run: |
case "${{ github.event_name }}" in
workflow_dispatch)
sha=$(gh api "repos/${{ github.repository }}/pulls/${{ inputs.pr_number }}" --jq '.head.sha')
;;
merge_group)
# Temp merge commit on the merge-queue temp branch; check
# runs from ci.yml/ci-integration.yml are reported here, NOT
# against the PR head SHA.
sha="${{ github.event.merge_group.head_sha }}"
;;
*)
sha="${{ github.event.pull_request.head.sha }}"
;;
esac
if [ -z "$sha" ]; then
echo "::error::Could not resolve head SHA for event ${{ github.event_name }}"
exit 1
fi
echo "sha=$sha" >> "$GITHUB_OUTPUT"
echo "[merge-gate] event=${{ github.event_name }} resolved head SHA: $sha"
- name: Checkout head
uses: actions/checkout@v4
with:
ref: ${{ steps.sha.outputs.sha }}
sparse-checkout: |
.github/scripts/ci
- name: Wait for all required checks
env:
GH_TOKEN: ${{ github.token }}
REPO: ${{ github.repository }}
SHA: ${{ steps.sha.outputs.sha }}
EVENT_NAME: ${{ github.event_name }}
# All required checks the gate aggregates, branched by event:
# pull_request / workflow_dispatch -> only ci.yml runs at PR time
# merge_group -> ci.yml AND ci-integration.yml run
# Keep this in sync with the underlying workflows.
# NOTE: 'gate' (this job) MUST NOT appear here -- it would
# deadlock waiting for itself.
EXPECTED_CHECKS: ${{ github.event_name == 'merge_group' && 'Build & Test (Linux),APM Self-Check,NOTICE Drift Check,Build (Linux),Smoke Test (Linux),Integration Tests (Linux),Release Validation (Linux)' || 'Build & Test (Linux),APM Self-Check,NOTICE Drift Check' }}
# Poll budget: ci-integration.yml chains Build -> Smoke ->
# Integration (timeout 20m) -> Release Validation (timeout 20m).
# Theoretical worst case ~50m; observed today ~5m end-to-end.
# Sized at 55m to absorb growth without false-failing the gate.
TIMEOUT_MIN: '55'
POLL_SEC: '30'
run: |
chmod +x .github/scripts/ci/merge_gate_wait.sh
.github/scripts/ci/merge_gate_wait.sh