From a13b83a2dcec8b28757a55b55ef229779ec64687 Mon Sep 17 00:00:00 2001 From: DJ Date: Wed, 15 Apr 2026 19:03:06 -0700 Subject: [PATCH 1/4] fix(dependabot): use correct ecosystem value github_actions (underscore) fetch-metadata outputs package-ecosystem as "github_actions" with an underscore, not "github-actions" with a hyphen. The condition was never matching, so major GitHub Actions updates were still being skipped. Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/dependabot-automerge-reusable.yml | 2 +- .github/workflows/dependabot-automerge.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dependabot-automerge-reusable.yml b/.github/workflows/dependabot-automerge-reusable.yml index 93ab6df8..e6fd6002 100644 --- a/.github/workflows/dependabot-automerge-reusable.yml +++ b/.github/workflows/dependabot-automerge-reusable.yml @@ -56,7 +56,7 @@ jobs: # so all version bumps (including major) are eligible. # App ecosystem PRs can only exist as security updates (limit: 0) # and must be patch/minor/indirect — major requires human review. - if [[ "$ECOSYSTEM" != "github-actions" && \ + if [[ "$ECOSYSTEM" != "github_actions" && \ "$UPDATE_TYPE" != "version-update:semver-patch" && \ "$UPDATE_TYPE" != "version-update:semver-minor" && \ "$DEP_TYPE" != "indirect" ]]; then diff --git a/.github/workflows/dependabot-automerge.yml b/.github/workflows/dependabot-automerge.yml index 491de69e..53317fc5 100644 --- a/.github/workflows/dependabot-automerge.yml +++ b/.github/workflows/dependabot-automerge.yml @@ -51,7 +51,7 @@ jobs: # so all version bumps (including major) are eligible. # App ecosystem PRs can only exist as security updates (limit: 0) # and must be patch/minor/indirect — major requires human review. - if [[ "$ECOSYSTEM" != "github-actions" && \ + if [[ "$ECOSYSTEM" != "github_actions" && \ "$UPDATE_TYPE" != "version-update:semver-patch" && \ "$UPDATE_TYPE" != "version-update:semver-minor" && \ "$DEP_TYPE" != "indirect" ]]; then From 85e258040c18c0e1f6c8b3dcdb76c10ed7ac948a Mon Sep 17 00:00:00 2001 From: DJ Date: Wed, 15 Apr 2026 19:47:12 -0700 Subject: [PATCH 2/4] fix(dependabot): add rebase workflow to enable App-token bypass of CODEOWNERS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GitHub's auto-merge mechanism does not apply ruleset bypass actors at merge time, so gh pr merge --auto cannot bypass the CODEOWNERS review requirement even when the App has bypass_mode:always. The rebase workflow's direct gh api .../merge call uses the App token directly and does apply the bypass, allowing Dependabot PRs to merge without a human CODEOWNERS review. Also updates dependabot-policy.md to document this nuance — the rebase workflow is now required for repos with CODEOWNERS review requirements, not only for repos with strict required-status-checks. Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/dependabot-rebase.yml | 43 +++++++++++++++++++++++++ standards/dependabot-policy.md | 18 +++++++---- 2 files changed, 54 insertions(+), 7 deletions(-) create mode 100644 .github/workflows/dependabot-rebase.yml diff --git a/.github/workflows/dependabot-rebase.yml b/.github/workflows/dependabot-rebase.yml new file mode 100644 index 00000000..b58dbb15 --- /dev/null +++ b/.github/workflows/dependabot-rebase.yml @@ -0,0 +1,43 @@ +# ───────────────────────────────────────────────────────────────────────────── +# SOURCE OF TRUTH: petry-projects/.github/standards/workflows/dependabot-rebase.yml +# Standard: petry-projects/.github/standards/dependabot-policy.md +# Reusable: petry-projects/.github/.github/workflows/dependabot-rebase-reusable.yml +# +# AGENTS — READ BEFORE EDITING: +# • This file is a THIN CALLER STUB. All rebase/merge serialization logic +# lives in the reusable workflow above. +# • You MAY change: nothing in this file in normal use. Adopt verbatim. +# • You MUST NOT change: trigger event, the concurrency group name, +# the `uses:` line, `secrets: inherit`, or the job-level `permissions:` +# block — reusable workflows can be granted no more permissions than the +# calling job has, so removing the stanza breaks the reusable's gh API +# calls. +# • If you need different behaviour, open a PR against the reusable in the +# central repo. +# ───────────────────────────────────────────────────────────────────────────── +# +# Dependabot update-and-merge — thin caller for the org-level reusable. +# To adopt: copy this file to .github/workflows/dependabot-rebase.yml in your repo. +# Required org/repo secrets (inherited): +# APP_ID — GitHub App ID with contents:write and pull-requests:write +# APP_PRIVATE_KEY — GitHub App private key +name: Dependabot update and merge + +on: + push: + branches: + - main + +concurrency: + group: dependabot-update-and-merge + cancel-in-progress: false + +permissions: {} + +jobs: + dependabot-rebase: + permissions: + contents: read + pull-requests: read + uses: petry-projects/.github/.github/workflows/dependabot-rebase-reusable.yml@v1 + secrets: inherit diff --git a/standards/dependabot-policy.md b/standards/dependabot-policy.md index bae08eaf..361e9aa8 100644 --- a/standards/dependabot-policy.md +++ b/standards/dependabot-policy.md @@ -204,13 +204,17 @@ The workflow fails if any known vulnerability is found, blocking the PR from mer 1. Copy the appropriate `dependabot.yml` template to `.github/dependabot.yml`, adjusting `directory` paths as needed. 2. Add `workflows/dependabot-automerge.yml` to `.github/workflows/`. -3. Add `workflows/dependabot-rebase.yml` to `.github/workflows/` **only if the - repo enforces strict required-status-checks** (i.e., "branches must be up - to date before merging" is on, either via the new ruleset system's - `strict_required_status_checks_policy: true` or classic branch protection's - `required_status_checks.strict: true`). If strict checks are off, the - rebase workflow is unnecessary because Dependabot PRs that fall behind can - merge as-is — adding it just creates churn and failure noise. +3. Add `workflows/dependabot-rebase.yml` to `.github/workflows/` if the repo + enforces **either** of the following: + - **Strict required-status-checks** (`strict_required_status_checks_policy: true` + or classic branch protection `required_status_checks.strict: true`) — without + this workflow, Dependabot PRs fall behind after each merge and stall. + - **CODEOWNERS review requirement** (`require_code_owner_review: true`) — GitHub's + auto-merge mechanism does not apply ruleset bypass actors at merge time, so the + App token approval does not satisfy the CODEOWNERS gate. The rebase workflow's + direct `gh api .../merge` call does apply the bypass, allowing the App to merge + without a human CODEOWNERS review. + If neither condition applies, the rebase workflow is unnecessary. 4. Add `workflows/dependency-audit.yml` to `.github/workflows/`. 5. **GitHub App secrets** — `APP_ID` and `APP_PRIVATE_KEY` are managed at the **organization level** (`gh secret set --org petry-projects --visibility all`), From 98a20fa1076fcc6cb00fe9b3684d7aec5c0ebe5a Mon Sep 17 00:00:00 2001 From: DJ Date: Wed, 15 Apr 2026 19:50:05 -0700 Subject: [PATCH 3/4] fix(sonar): pin rebase workflow SHA and pass secrets explicitly Address SonarCloud hotspots S7637 and S7635: - S7637: pin reusable workflow to full commit SHA instead of @v1 tag - S7635: pass APP_ID and APP_PRIVATE_KEY explicitly instead of secrets: inherit Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/dependabot-rebase.yml | 14 ++++++++------ standards/workflows/dependabot-rebase.yml | 14 ++++++++------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/.github/workflows/dependabot-rebase.yml b/.github/workflows/dependabot-rebase.yml index b58dbb15..cf80dd94 100644 --- a/.github/workflows/dependabot-rebase.yml +++ b/.github/workflows/dependabot-rebase.yml @@ -8,10 +8,10 @@ # lives in the reusable workflow above. # • You MAY change: nothing in this file in normal use. Adopt verbatim. # • You MUST NOT change: trigger event, the concurrency group name, -# the `uses:` line, `secrets: inherit`, or the job-level `permissions:` -# block — reusable workflows can be granted no more permissions than the -# calling job has, so removing the stanza breaks the reusable's gh API -# calls. +# the `uses:` line, the explicit secrets block, or the job-level +# `permissions:` block — reusable workflows can be granted no more +# permissions than the calling job has, so removing the stanza breaks +# the reusable's gh API calls. # • If you need different behaviour, open a PR against the reusable in the # central repo. # ───────────────────────────────────────────────────────────────────────────── @@ -39,5 +39,7 @@ jobs: permissions: contents: read pull-requests: read - uses: petry-projects/.github/.github/workflows/dependabot-rebase-reusable.yml@v1 - secrets: inherit + uses: petry-projects/.github/.github/workflows/dependabot-rebase-reusable.yml@ae9709f4466dec60a5733c9e7487f69dcd004e05 # v1 + secrets: + APP_ID: ${{ secrets.APP_ID }} + APP_PRIVATE_KEY: ${{ secrets.APP_PRIVATE_KEY }} diff --git a/standards/workflows/dependabot-rebase.yml b/standards/workflows/dependabot-rebase.yml index b58dbb15..cf80dd94 100644 --- a/standards/workflows/dependabot-rebase.yml +++ b/standards/workflows/dependabot-rebase.yml @@ -8,10 +8,10 @@ # lives in the reusable workflow above. # • You MAY change: nothing in this file in normal use. Adopt verbatim. # • You MUST NOT change: trigger event, the concurrency group name, -# the `uses:` line, `secrets: inherit`, or the job-level `permissions:` -# block — reusable workflows can be granted no more permissions than the -# calling job has, so removing the stanza breaks the reusable's gh API -# calls. +# the `uses:` line, the explicit secrets block, or the job-level +# `permissions:` block — reusable workflows can be granted no more +# permissions than the calling job has, so removing the stanza breaks +# the reusable's gh API calls. # • If you need different behaviour, open a PR against the reusable in the # central repo. # ───────────────────────────────────────────────────────────────────────────── @@ -39,5 +39,7 @@ jobs: permissions: contents: read pull-requests: read - uses: petry-projects/.github/.github/workflows/dependabot-rebase-reusable.yml@v1 - secrets: inherit + uses: petry-projects/.github/.github/workflows/dependabot-rebase-reusable.yml@ae9709f4466dec60a5733c9e7487f69dcd004e05 # v1 + secrets: + APP_ID: ${{ secrets.APP_ID }} + APP_PRIVATE_KEY: ${{ secrets.APP_PRIVATE_KEY }} From 04de6969ce2aba9f5b640ae336443bfc32d8b685 Mon Sep 17 00:00:00 2001 From: DJ Date: Wed, 15 Apr 2026 19:50:47 -0700 Subject: [PATCH 4/4] docs(dependabot-policy): align config table with conditional rebase workflow The "Each repository must have" table listed dependabot-rebase.yml as universally required, contradicting the conditional wording added in the Applying to a Repository section. Split the table into baseline (always required) and conditional (when strict checks or CODEOWNERS review applies) to eliminate the inconsistency. Co-Authored-By: Claude Opus 4.6 (1M context) --- standards/dependabot-policy.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/standards/dependabot-policy.md b/standards/dependabot-policy.md index 361e9aa8..80bcca93 100644 --- a/standards/dependabot-policy.md +++ b/standards/dependabot-policy.md @@ -35,15 +35,20 @@ security posture than chasing every minor/patch release. ## Configuration Files -Each repository must have: +Each repository must have the following baseline files: | File | Purpose | |------|---------| | `.github/dependabot.yml` | Dependabot config scoped to the repo's ecosystems | | `.github/workflows/dependabot-automerge.yml` | Auto-approve + squash-merge security PRs | -| `.github/workflows/dependabot-rebase.yml` | Rebase behind Dependabot PRs after merges | | `.github/workflows/dependency-audit.yml` | CI check — fail on known vulnerabilities | +The following file is conditional: + +| File | When required | +|------|--------------| +| `.github/workflows/dependabot-rebase.yml` | Required when strict required-status-checks (`strict_required_status_checks_policy: true`) or CODEOWNERS review enforcement (`require_code_owner_review: true`) applies. See [Applying to a Repository](#applying-to-a-repository) for details. | + ## Dependabot Templates Use the template matching your repository type.