Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,8 @@ jobs:
!cancelled() && github.actor == 'github-actions[bot]' &&
(startsWith(github.head_ref || github.ref_name, 'dependabot/') ||
startsWith(github.head_ref || github.ref_name, 'toolchain/') ||
startsWith(github.head_ref || github.ref_name, 'patched/'))
startsWith(github.head_ref || github.ref_name, 'patched/') ||
startsWith(github.head_ref || github.ref_name, 'security/'))
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
Expand Down
656 changes: 648 additions & 8 deletions .github/workflows/security-alerts.yml

Large diffs are not rendered by default.

35 changes: 25 additions & 10 deletions .github/workflows/update-prs.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
name: Update PRs

# Reports on an update pull request once CI has run on it, and never merges it. The update
# pull requests come from Dependabot (dependabot/*), toolchain-updates.yml (toolchain/*)
# and patched-libraries.yml (patched/*). (Upstream sync pull requests ended on 2026-10-09:
# pull requests come from Dependabot (dependabot/*), toolchain-updates.yml (toolchain/*),
# patched-libraries.yml (patched/*) and security-alerts.yml (security/overrides: override
# floors for alerts Dependabot cannot fix; only pnpm-workspace.yaml and pnpm-lock.yaml may
# change, its dependency review must pass, and a security fix waits no 3 days). (Upstream sync pull requests ended on 2026-10-09:
# the fork no longer merges upstream; upstream-watch.yml reports its commits.) Before this,
# each sat until the owner looked; a red one told nobody, since GitHub emails a failed run
# only to whoever started it, and that was a bot.
Expand Down Expand Up @@ -109,7 +111,8 @@ jobs:
github.event.workflow_run.actor.login != 'github-actions[bot]' &&
(startsWith(github.event.workflow_run.head_branch, 'dependabot/') ||
startsWith(github.event.workflow_run.head_branch, 'toolchain/') ||
startsWith(github.event.workflow_run.head_branch, 'patched/')))
startsWith(github.event.workflow_run.head_branch, 'patched/') ||
startsWith(github.event.workflow_run.head_branch, 'security/')))
runs-on: ubuntu-latest
# UPDATE_PRS_TOKEN is a secret of the "update-prs" environment, which only main may use
# (Settings, Environments): a workflow file on any other branch cannot read it (#163).
Expand Down Expand Up @@ -156,7 +159,7 @@ jobs:
if ! jq -e --arg repo "$GH_REPO" --arg branch "$BRANCH" '
(.path | split("@")[0]) == ".github/workflows/ci.yml" and
.head_repository.full_name == $repo and .head_branch == $branch and
(.head_branch | test("^(dependabot|toolchain|patched)/"))' \
(.head_branch | test("^(dependabot|toolchain|patched|security)/"))' \
"$RUNNER_TEMP/run.json" > /dev/null; then
echo "Run $RUN_ID is not a CI run of this repository's update branch $BRANCH." >&2
exit 1
Expand Down Expand Up @@ -231,6 +234,7 @@ jobs:
toolchain/node-*) kind=node ;;
toolchain/ublock-origin-*) kind=ublock ;;
toolchain/player-libraries) kind=players ;;
security/overrides) kind=security ;;
patched/*) kind=patched ;;
*) kind=other ;;
esac
Expand All @@ -257,6 +261,7 @@ jobs:
docker) printf 'Dependabot moves the tag and the digest in the Dockerfile together. `@dependabot ignore this minor version` (or `this major version`) skips it.\n' ;;
pnpm|node|ublock) printf 'Closing this pull request skips this version for good; toolchain-updates.yml raises the next one.\n' ;;
players) printf 'toolchain-updates.yml rebuilds this pull request in place when a newer release comes. Closing it skips this set of versions; the next set comes as a pull request of its own.\n' ;;
security) printf 'security-alerts.yml rebuilds this pull request in place every day from the open alerts. Closing it without merging hands its alerts back to you as "Security alert" issues.\n' ;;
patched) printf 'How to take it by hand: `docs/updating-patched-libraries.md`. Closing this pull request skips this version for good.\n' ;;
*) ;;
esac
Expand Down Expand Up @@ -352,7 +357,7 @@ jobs:
migrate() {
local what slug updates count group list park take rerun found
case $kind in
pnpm|node|ublock|players|patched)
pnpm|node|ublock|players|security|patched)
# The title less its prefix: "pnpm 12.15.0", "Node.js 26", "hls.js 1.7.4".
what=$(jq -r '.title | sub("^(Toolchain update|Patched library update): "; "")' <<< "$pr")
slug=$what
Expand All @@ -365,6 +370,10 @@ jobs:
park="closing #$number skips this set of versions; the next set comes as a pull request of its own"
take="toolchain-updates.yml rebuilds #$number on it at its next run"
fi
if [ "$kind" = security ]; then
park="closing #$number without merging hands its alerts back to you as issues"
take="security-alerts.yml rebuilds #$number on it at its next daily run"
fi
;;
*)
# What Dependabot's newest commit updates, "<name> <version>" a line, from the
Expand Down Expand Up @@ -505,7 +514,7 @@ jobs:
fi
case $kind in
dependabot|actions|docker) bot='dependabot[bot]' ;;
pnpm|node|ublock|players|patched) bot='github-actions[bot]' ;;
pnpm|node|ublock|players|security|patched) bot='github-actions[bot]' ;;
*) reasons+=("branch $BRANCH is not one this workflow checks") ;;
esac
if [ "$kind" = actions ] && [ -z "${MERGE_TOKEN:-}" ]; then
Expand Down Expand Up @@ -548,10 +557,11 @@ jobs:
reasons+=("main has $library $current already")
fi
fi
# A patched-library pull request changes the lockfile, and its own pull_request runs
# wait for an approval, so patched-libraries.yml starts the dependency review on the
# branch, next to CI. A review that did not pass is named.
if [ "$kind" = patched ]; then
# A patched-library or override pull request changes the lockfile, and its own
# pull_request runs wait for an approval, so patched-libraries.yml and
# security-alerts.yml start the dependency review on the branch, next to CI. A review
# that did not pass is named.
if [ "$kind" = patched ] || [ "$kind" = security ]; then
review=$(review_of "$SHA")
if [ "$review" != success ]; then reasons+=("its dependency review (\"Review dependency changes\", started on this branch) is $review"); fi
fi
Expand Down Expand Up @@ -601,6 +611,9 @@ jobs:
players)
files=$(jq -r '.files[].path | select(. != "tests/e2e/live-specs/player-libraries.json")' "$RUNNER_TEMP/pr.json")
only='tests/e2e/live-specs/player-libraries.json' ;;
security)
files=$(jq -r '.files[].path | select(. != "pnpm-workspace.yaml" and . != "pnpm-lock.yaml")' "$RUNNER_TEMP/pr.json")
only='pnpm-workspace.yaml and pnpm-lock.yaml' ;;
actions)
files=$(jq -r '.files[].path | select((startswith(".github/workflows/") or startswith(".github/actions/")) | not)' "$RUNNER_TEMP/pr.json")
only='workflow and action files' ;;
Expand Down Expand Up @@ -859,6 +872,8 @@ jobs:
if [ "$update_token" = "$GH_TOKEN" ]; then gh workflow run ci.yml --ref "$BRANCH"; fi
# Nothing starts the live suite on a push: it is started here whoever pushed.
if [ "$kind" = players ]; then gh workflow run live-streams.yml --ref "$BRANCH"; fi
# Nor the dependency review that decides an override pull request.
if [ "$kind" = security ]; then gh workflow run dependency-review.yml --ref "$BRANCH"; fi
exit 0
fi
fi
Expand Down
1 change: 1 addition & 0 deletions docs/maintenance.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ merged themselves.
| actionlint and zizmor images | a Dependabot PR (docker, weekly) changing the tag and digest in `.github/actionlint/Dockerfile` or `.github/zizmor/Dockerfile` (or only the digest, when the same tag was pushed again: dependabot/dependabot-core#15081), which `ci.yml`'s workflows job and the WSL verify read | "ready to merge" when it changes only those files: CI ran every workflow file through the new checks | the PR |
| Firefox stable, beta | `firefox-stable.yml` (daily) and `firefox-beta.yml` (Mon, Thu) run the e2e suites on that Firefox | a stable version is recorded as tested, so later days skip it | nothing; an issue on failure, closed by the next green run |
| security alerts | a Dependabot alert on the Security tab, and a Dependabot PR that fixes it (the rows above), skipping both 3-day waits; `security-alerts.yml` (daily) watches for an alert with no such PR | as the PR's row says | GitHub's alert email; for an alert over 6 hours old with no Dependabot PR, an issue per package, "Security alert: <package>", closed once its alerts are fixed on `main` or dismissed |
| security alerts Dependabot cannot fix, when an override floor fixes them | ONE rolling PR from `security-alerts.yml` (daily) on `security/overrides`, "Security fixes: override floors": a floor per package and major in `pnpm-workspace.yaml`'s `overrides` (raised, or added with a comment), and `pnpm-lock.yaml` rewritten for it (`--lockfile-only --ignore-scripts`, in a job with no write token), checked to fix every alert it takes and to move nothing else; CI and the dependency review are started on it | "ready to merge" when CI and the dependency review pass and it changes only those two files; no 3-day wait (a security fix). An alert it cannot take (no patched version, the fix a new major, a floor `main` has already, a parent-scoped override) gets the issue above, with the reason. Closing the PR unmerged hands its alerts to you as issues | the PR |

Dependabot proposes a release once it is 3 days old (`cooldown` in `.github/dependabot.yml`;
your call of 2026-10-20, after none from 2026-10-11). Green CI cannot see a compromised
Expand Down
21 changes: 21 additions & 0 deletions docs/notes/workflows.md
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,27 @@
swapped in too. Since 2026-10-20 a second job, `watch` (daily and by hand, not on a push),
looks after the update pull requests: see "Update guards" above. Each job asks for its own
permissions (zizmor flags a workflow-wide `issues: write` once there are two jobs).
Since 2026-10-24 it tries the fix itself where an override floor makes it, as #564 did by
hand (`tools/security-overrides.mjs`, its plan replayed on the state before #564 writes the
same four floors, and its lockfile came out the same, the order of two keys in its overrides
copy aside). Three jobs: `check` plans the floors (`plan`: a floor per package and major the
lockfile holds vulnerable, `^` the newest first patched version; declined, with the reason in
the issue, when there is no patched version, the fix is a new major, the package is pnpm-
patched, a parent-scoped or unreadable override governs it, or `main` has the floor already
while the lockfile is still vulnerable) and keeps the alerts it takes out of the issues (out
of both `$new` and `$list`: a listed alert is never raised again); `install` (only
`contents: read`, no token in it) runs `pnpm install --lockfile-only --ignore-scripts
--no-frozen-lockfile` with the floors and `verify`: every alert taken is fixed, every floor
holds, and nothing but the floored packages moved; `publish`, the only writer, builds the
commit through the API on the planned main (main moved meanwhile: the next day), keeps ONE
rolling PR on `security/overrides` and starts CI and the dependency review on it (not when
a run that ran covers its head: a `pull_request` run of a PR this token opened waits for an
approval, `action_required`). A PR closed unmerged by hand declines its alerts (issues);
this workflow's own closes carry `<!-- security-overrides: closed-by-run -->`. pnpm saying no
version fits (`ERR_PNPM_NO_MATCHING_VERSION`, `ETARGET`) demotes those alerts to issues;
any other install failure fails the run (the report job opens "Security override route
failed"). The fsaunpack lockfile stays on the issue route. `update-prs.yml` reports on the
PR as the kind `security`.
- **The Security tab's count also holds CodeQL code scanning** (2026-10-03). GitHub's
default setup runs it on every push to `main` (Actions shows it as "CodeQL",
`dynamic/github-code-scanning/codeql`; there is no workflow file), JavaScript and
Expand Down
Loading
Loading