chore(deps): sweep Dependabot alerts into board-tracked issues
Closes #2233 — the alert-consuming half of #2229. #2235 removed `.github/dependabot.yml`, ending Dependabot's version-update PRs; this ends its security-update PRs and replaces them with a daily sweep that turns the alerts into ordinary board items. - `scripts/dependabot-alerts.mjs` groups alerts by `(package, manifest_path, first_patched_version)` — one issue per BUMP, not per advisory — re-checks each vulnerable range against `v2/main`'s own lockfile before filing, and keys idempotency on a marker comment naming every GHSA the issue covers. - `.github/workflows/dependabot-alerts.yml` runs it daily and on `workflow_dispatch`, with `vulnerability-alerts: read`. - `semver` is declared at the repo root, per Dependency placement: `scripts/` is root-owned code with no manifest of its own. - The sibling `dependency-refresh` comments no longer claim security updates are unaffected, and AGENTS.md gains the flow both halves now follow. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013H6Cew3KB3jVmQ5x4Dq1sq Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
parent
0cb12a19ca
commit
66a3332f1d
2 changed files with 1085 additions and 17 deletions
89
.github/workflows/dependabot-alerts.yml
vendored
Normal file
89
.github/workflows/dependabot-alerts.yml
vendored
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
# Dependabot alert sweep (#2233), the alert-consuming half of #2229.
|
||||
#
|
||||
# Dependabot's SECURITY-update PRs are turned off for this repo; its ALERTS are
|
||||
# left on. Those are two independent settings, and this workflow depends on the
|
||||
# split: it reads the alerts and turns them into ordinary board-tracked issues,
|
||||
# so the fix is written by hand against `v2/main` like any other work.
|
||||
#
|
||||
# alert -> this sweep -> issue (labeled, milestoned, boarded) -> maintainer PR -> v2/main
|
||||
#
|
||||
# It is a SCHEDULE, not an event handler, because there is no `dependabot_alert`
|
||||
# workflow trigger — that is a webhook event only. Daily is deliberate: with
|
||||
# security PRs off there is no mergeable-against-`main` artifact and no window to
|
||||
# race, so the merge guard #2060 needed has no analogue here. What replaces it is
|
||||
# a precondition inside the script: `automated-security-fixes` is a repo SETTING
|
||||
# and can be switched back on from the UI without a commit, so the sweep asserts
|
||||
# it is still disabled and fails loudly if it is not.
|
||||
#
|
||||
# ⚠️ GitHub computes the dependency graph, and therefore every alert, from the
|
||||
# DEFAULT branch (`main`), while we ship from `v2/main`. Two consequences:
|
||||
#
|
||||
# * An alert is re-checked against `v2/main`'s own lockfile before an issue is
|
||||
# filed — hence the `ref: v2/main` checkout below. An alert whose vulnerable
|
||||
# range no longer matches is already fixed on the branch we ship from and is
|
||||
# waiting on a milestone merge to close, so it is skipped silently.
|
||||
# * A vulnerable dependency introduced on `v2/main` and not yet merged to
|
||||
# `main` produces NO alert at all. No approach that consumes GitHub's alerts
|
||||
# avoids that. The release-time `npm audit fix` from #2231 is a second signal
|
||||
# that partially covers it; a scheduled `npm audit --audit-level=high` over
|
||||
# `v2/main`'s lockfiles would close it fully and is a separable follow-up.
|
||||
#
|
||||
# `vulnerability-alerts: read` is the one non-default permission, and
|
||||
# `GITHUB_TOKEN` supports it — no PAT is needed to read the alerts themselves.
|
||||
# Two side steps are outside its reach, and `PROJECT_TOKEN` is what covers them
|
||||
# when it exists:
|
||||
#
|
||||
# * Writing the board card, since board #28 is an ORG project
|
||||
# (`organization projects: write`). Absent, the issue is still filed labeled
|
||||
# and milestoned and the next `/issue-triage` sweep boards it.
|
||||
# * Reading back `automated-security-fixes`, which needs `administration: read`
|
||||
# — a permission `permissions:` has no key for, so `GITHUB_TOKEN` can never
|
||||
# have it. Absent, that assertion is reported as UNVERIFIED rather than
|
||||
# failing the run; an explicit `enabled: true` still fails it.
|
||||
#
|
||||
# Nothing the sweep exists to do is skipped for want of that secret.
|
||||
#
|
||||
# The version-update half of #2229 is the sibling `dependency-refresh.yml`.
|
||||
name: Dependabot Alert Sweep
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "17 6 * * *" # 06:17 UTC daily; alerts are not minute-sensitive
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
vulnerability-alerts: read
|
||||
|
||||
jobs:
|
||||
alert-sweep:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout v2/main
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
ref: v2/main
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v7
|
||||
with:
|
||||
node-version: "22.x"
|
||||
cache: "npm"
|
||||
|
||||
# Root install only, and no lifecycle scripts. The sweep's one dependency
|
||||
# is `semver`; it reads every lockfile as JSON and never needs a client's
|
||||
# tree on disk, so the postinstall cascade into `clients/*` that
|
||||
# `dependency-refresh.yml` genuinely needs (it shells out to
|
||||
# `npm outdated` in each) would be minutes of nothing here.
|
||||
- name: Install root dependencies
|
||||
run: npm ci --ignore-scripts
|
||||
|
||||
- name: Run the Dependabot alert sweep
|
||||
run: node scripts/dependabot-alerts.mjs
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITHUB_REPOSITORY: ${{ github.repository }}
|
||||
# Optional: an org-project PAT with `organization projects: write`.
|
||||
# Absent, the issue is filed unboarded and triage picks it up.
|
||||
PROJECT_TOKEN: ${{ secrets.PROJECT_TOKEN }}
|
||||
26
.github/workflows/dependency-refresh.yml
vendored
26
.github/workflows/dependency-refresh.yml
vendored
|
|
@ -2,19 +2,21 @@
|
|||
#
|
||||
# A Dependabot version-update PR carries no issue and no board card, so
|
||||
# `.github/dependabot.yml` was removed outright in #2235 — npm and
|
||||
# github-actions alike. This workflow is what replaced those PRs (security
|
||||
# updates are a separate mechanism and stay on; see below): it runs
|
||||
# `scripts/dependency-refresh.mjs` against `v2/main` once a month and files or
|
||||
# updates ONE tracking issue listing every outdated npm package across the root
|
||||
# install and each client, plus any workflow `uses:` ref behind its action's
|
||||
# highest released version. No PR is opened automatically. A maintainer
|
||||
# reviews the
|
||||
# issue, picks what to bump, and opens a normal PR against `v2/main`.
|
||||
# github-actions alike. This workflow is what replaced those PRs (the
|
||||
# security-update half is a separate mechanism, switched off separately; see
|
||||
# below): it runs `scripts/dependency-refresh.mjs` against `v2/main` once a
|
||||
# month and files or updates ONE tracking issue listing every outdated npm
|
||||
# package across the root install and each client, plus any workflow `uses:`
|
||||
# ref behind its action's highest released version. No PR is opened
|
||||
# automatically. A maintainer reviews the issue, picks what to bump, and opens
|
||||
# a normal PR against `v2/main`.
|
||||
#
|
||||
# Dependabot SECURITY updates are unaffected: they are enabled in repo
|
||||
# settings, not in a config file, and kept working while `dependabot.yml` was
|
||||
# missing entirely (see #1833, #1840). They are raised against the default
|
||||
# branch and still need retargeting by hand.
|
||||
# Dependabot SECURITY updates are the other half, and #2233 turned their PRs
|
||||
# off too — they were enabled in repo settings rather than in a config file,
|
||||
# which is why they kept working while `dependabot.yml` was missing entirely
|
||||
# (see #1833, #1840) and why deleting that file did not touch them. Its
|
||||
# ALERTS stay on and are swept into issues daily by the sibling
|
||||
# `dependabot-alerts.yml`. Between them, Dependabot opens no PRs here at all.
|
||||
#
|
||||
# `GITHUB_TOKEN` is sufficient: it only needs to read milestones and the public
|
||||
# release feeds of the actions we use, and to create/edit an issue
|
||||
|
|
|
|||
Loading…
Reference in a new issue