feat(ci): bridge fop/local-ci/pr status for Dependabot PRs (unblock 8 stuck PRs)#511
Merged
Merged
Conversation
… 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)
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
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|failurevia 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 |
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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/pris a required PAT-posted commit status set by a developer running./scripts/fop-local-ci.shlocally — which runs lefthook pre-push gates + posts the result.Dependabot bots commit from GitHub-side; no local developer means no
fop-local-ci.shinvocation means nofop/local-ci/pr: successstatus. 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.ymlthat:github.event.pull_request.user.login == 'dependabot[bot]'make ci: composer-audit hard + npm-audit advisory + gitleaks (scoped to PR range) hard + osv-scanner advisory + typos advisoryfop/local-ci/pr: success|failurecommit status viagh api POST /repos/.../statuses/{sha}matching the local-ci-attestation convention (noactions/github-script, no new third-party action SHAs)statuses: write(scoped to job, not top-level — minimum privilege)github.event.*values flow throughenv:vars (no injection surface)SOTA-2026 discipline notes
.github/workflows/dependabot-local-ci-bridge.yml(GHA) +.gitea/workflows/dependabot-local-ci-bridge.yaml(Gitea mirror) committed per workflow-drift requirement.security.yml+ci.yml(zero new pin surface).Verification
FOP_LOCAL_CI_DIRECT=1 make ciclean exit-0 on the rebased HEAD. All lefthook pre-push gates green (no--no-verifybypass — 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.