Skip to content

feat(ci): bridge fop/local-ci/pr status for Dependabot PRs (unblock 8 stuck PRs)#511

Merged
nash87 merged 1 commit into
mainfrom
t-dependabot-local-ci-bridge-v2
May 19, 2026
Merged

feat(ci): bridge fop/local-ci/pr status for Dependabot PRs (unblock 8 stuck PRs)#511
nash87 merged 1 commit into
mainfrom
t-dependabot-local-ci-bridge-v2

Conversation

@nash87
Copy link
Copy Markdown
Owner

@nash87 nash87 commented May 19, 2026

Closes task #11 (Dependabot fop/local-ci/pr gate architectural fix). Authored 2026-05-19 ~07:00 as part of the parkhub E2E fan-out. Initially staged behind the devalue 5.6.4 image-scan blocker (RESUME.md); now unblocked since PR #510 landed the devalue 5.8.1 fix on main.

Architectural rationale

fop/local-ci/pr is a required PAT-posted commit status set by a developer running ./scripts/fop-local-ci.sh locally — which runs lefthook pre-push gates + posts the result.

Dependabot bots commit from GitHub-side; no local developer means no fop-local-ci.sh invocation means no fop/local-ci/pr: success status. Result: PR sits MERGEABLE+BLOCKED indefinitely. 8 Dependabot PRs are stuck right now by this exact gap: parkhub-php #493/#496/#498 + parkhub-rust #638/#639/#640/#641/#642.

What this bridge does

New GHA + Gitea-Actions workflow dependabot-local-ci-bridge.yml that:

  1. Triggers only on PRs where github.event.pull_request.user.login == 'dependabot[bot]'
  2. Runs the headless equivalent of make ci: composer-audit hard + npm-audit advisory + gitleaks (scoped to PR range) hard + osv-scanner advisory + typos advisory
  3. Posts fop/local-ci/pr: success|failure commit status via gh api POST /repos/.../statuses/{sha} matching the local-ci-attestation convention (no actions/github-script, no new third-party action SHAs)
  4. Job permission statuses: write (scoped to job, not top-level — minimum privilege)
  5. All github.event.* values flow through env: vars (no injection surface)

SOTA-2026 discipline notes

  • Advisory adoption initially — not yet promoted to required gate; verify it runs cleanly over a few Dependabot cycles first.
  • Both .github/workflows/dependabot-local-ci-bridge.yml (GHA) + .gitea/workflows/dependabot-local-ci-bridge.yaml (Gitea mirror) committed per workflow-drift requirement.
  • All actions SHA-pinned, reusing the same SHAs as security.yml + ci.yml (zero new pin surface).
  • The bridge does NOT replace the human-developer path — both can post the status; whichever fires first wins. This means the existing developer workflow keeps working.

Verification

FOP_LOCAL_CI_DIRECT=1 make ci clean exit-0 on the rebased HEAD. All lefthook pre-push gates green (no --no-verify bypass — discipline held per CLAUDE.md L237 and 2026-05-19 E4 incident memory).

Follow-up

A parallel PR will mirror this workflow to parkhub-rust (task #11.2). Once landed and validated, the 8 stuck PRs above can proceed through their auto-merge paths.

… stuck PRs)

Adds `.github/workflows/dependabot-local-ci-bridge.yml` (+ Gitea mirror at
`.gitea/workflows/dependabot-local-ci-bridge.yaml`) to close the architectural
gap where Dependabot-authored PRs can never receive the `fop/local-ci/pr:
success` commit status that the `local-ci-attestation` gate in ci.yml polls
for.

**Root cause**: `fop/local-ci/pr` is posted by a developer running
`.github/scripts/fop-local-ci.sh --profile pr --post-status` locally.
Dependabot pushes from GitHub-side; no local developer → no invocation →
`local-ci-attestation` blocks for its full 30-minute polling window, then
fails. Result: PR stays MERGEABLE+BLOCKED indefinitely.

**Unblocks**:
- parkhub-php #493, #496, #498
- parkhub-rust #638, #639, #640, #641, #642
  (parkhub-rust port tracked as follow-up task #19)

**What the bridge runs** (all tools + SHAs already in security.yml):
- `composer audit --locked --no-dev` (hard gate)
- `npm audit` root + parkhub-web (advisory, continue-on-error)
- `gitleaks` secret scan on the PR range (hard gate)
- `osv-scanner` composer + npm lockfiles (advisory)
- `crate-ci/typos` (advisory)

**Status posting**: uses `gh api POST /repos/.../statuses/{sha}` (same
tooling as `local-ci-attestation` in ci.yml) in an `if: always()` final
step, so the status is posted regardless of gate outcome. All
`github.event.*` values are passed through `env:` vars to prevent expression
injection in the run shell.

**Advisory mode**: this workflow is NOT yet a required check. Monitor over a
few Dependabot cycles before promoting in branch protection. The existing
developer path (fop-local-ci.sh + local-ci-attestation) is unchanged.

Action SHAs reused from security.yml / ci.yml — no new third-party action
pinnings introduced:
- actions/checkout@de0fac2 (v6, ci.yml)
- shivammathur/setup-php@accd612 (v2, security.yml)
- actions/setup-node@48b55a0 (v6, ci.yml)
- crate-ci/typos@cf5f1c2 (v1.45.1, security.yml)
Copilot AI review requested due to automatic review settings May 19, 2026 07:39
@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@github-actions github-actions Bot added the ci CI/CD pipeline label May 19, 2026
@nash87 nash87 enabled auto-merge (squash) May 19, 2026 07:40
@nash87 nash87 merged commit 4ebd9d5 into main May 19, 2026
26 of 27 checks passed
@nash87 nash87 deleted the t-dependabot-local-ci-bridge-v2 branch May 19, 2026 07:40
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds a CI “bridge” workflow to post the required fop/local-ci/pr commit status for Dependabot-authored PRs, unblocking Dependabot PRs that can’t run the developer-local fop-local-ci.sh attestation.

Changes:

  • Added a GitHub Actions workflow to run a headless gate suite for Dependabot PRs and post fop/local-ci/pr: success|failure via the commit status API.
  • Added a mirrored Gitea Actions workflow with equivalent behavior and pinned action refs.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
.github/workflows/dependabot-local-ci-bridge.yml Runs headless audits/scans on Dependabot PRs and posts fop/local-ci/pr commit status to satisfy required status checks.
.gitea/workflows/dependabot-local-ci-bridge.yaml Mirrors the GitHub workflow for Gitea Actions runners to prevent workflow drift and keep the same fop/local-ci/pr status semantics.

- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
persist-credentials: false
- name: Checkout
uses: https://192.168.178.233/actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
persist-credentials: false
Comment on lines +145 to +159
live_sha="$(
gh pr view "${PR_NUMBER}" \
--repo "${REPO}" --json headRefOid --jq .headRefOid 2>/dev/null || true
)"
if [[ "${live_sha}" =~ ^[0-9a-f]{40}$ ]]; then
SHA="${live_sha}"
fi

gh api \
--method POST \
"repos/${REPO}/statuses/${SHA}" \
-f state="${STATE}" \
-f context="fop/local-ci/pr" \
-f description="${DESC}" \
-f target_url="${SERVER_URL}/${REPO}/actions/runs/${RUN_ID}"
-L composer.lock \
-L package-lock.json \
-L parkhub-web/package-lock.json \
--format=table || true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci CI/CD pipeline

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants