Skip to content

Commit 159cd3a

Browse files
authored
Merge pull request #9064 from BitGo/HSM-410-nightshift-iyarc-automation
feat(root): configure nightshift with iyarc-prune task
2 parents a5353fa + f295762 commit 159cd3a

3 files changed

Lines changed: 207 additions & 0 deletions

File tree

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: nightshift-scheduler
2+
run-name: 'nightshift scheduler'
3+
4+
on:
5+
schedule:
6+
- cron: '0 6 * * 1-5' # weekdays 06:00 UTC (168h cooldown gates to ~weekly)
7+
workflow_dispatch:
8+
inputs:
9+
dry_run:
10+
description: 'List tasks that would run without executing them'
11+
required: false
12+
default: false
13+
type: boolean
14+
15+
jobs:
16+
schedule:
17+
uses: BitGo/nightshift-actions/.github/workflows/nightshift-scheduler.yaml@v1
18+
with:
19+
dry_run: ${{ inputs.dry_run || false }}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: nightshift-task
2+
run-name: 'nightshift: ${{ inputs.task_type }}'
3+
4+
on:
5+
workflow_dispatch:
6+
inputs:
7+
task_type:
8+
description: 'Task type to run'
9+
required: true
10+
type: string
11+
12+
jobs:
13+
run:
14+
uses: BitGo/nightshift-actions/.github/workflows/nightshift-task.yaml@v1
15+
with:
16+
task_type: ${{ inputs.task_type }}
17+
provider: bedrock
18+
sign_commits: true
19+
secrets:
20+
VAULT_CF_ACCESS_CLIENT_SECRET: ${{ secrets.VAULT_CF_ACCESS_CLIENT_SECRET }}

.nightshift.yaml

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
max_tasks_per_run: 1
2+
3+
tasks:
4+
enabled:
5+
- iyarc-prune
6+
7+
priorities:
8+
iyarc-prune: 8
9+
10+
cooldowns:
11+
iyarc-prune: '168h'
12+
13+
custom:
14+
- type: iyarc-prune
15+
name: Audit Exclusion (.iyarc) Pruner
16+
category: pr
17+
cooldown: '168h'
18+
priority: 8
19+
prompt: |
20+
You are a nightshift automated maintenance agent for the BitGoJS
21+
monorepo. BitGoJS is the client SDK that BitGo and external clients
22+
install directly into their applications (wallets, signing, transaction
23+
building). As a security posture, BitGo does not release packages with
24+
known vulnerabilities. The release pipeline runs an `improved-yarn-audit`
25+
gate; advisories that do not actually apply to us are suppressed in the
26+
`.iyarc` ignore file at the repo root, each with a justification comment.
27+
28+
Over time `.iyarc` accumulates exclusions that are no longer needed
29+
because upstream shipped a fix. Nobody prunes them, so the suppressed
30+
audit surface silently grows. Your job, once per cycle, is to find
31+
exclusions that can now be safely removed, bump the relevant dependency,
32+
prove the fix passes the release audit gate plus build/test, and open a
33+
single pull request. Most cycles will legitimately produce NO PR — a
34+
"nothing prunable this cycle" result is healthy and strongly preferred
35+
over an unsafe or unverified bump.
36+
37+
## Environment notes
38+
39+
- This is a Lerna + Yarn (v1, `1.22.22`) workspaces monorepo with ~116
40+
packages under `modules/`. Node is pinned via `.nvmrc`.
41+
- The release audit gate is `yarn run audit-high`
42+
(= `improved-yarn-audit --min-severity high`). It auto-reads `.iyarc`
43+
from the repo root — no flag needed. This is the EXACT command the
44+
release pipeline runs, so it is your source of truth for "fixed".
45+
- IMPORTANT: nearly every entry in `.iyarc` is a TRANSITIVE dependency
46+
(e.g. tar, minimatch, ws, form-data, protobufjs, tmp, sjcl,
47+
sanitize-html, esbuild), pinned in the root `package.json`
48+
`resolutions` block — NOT a direct dependency in a module
49+
`package.json`. So editing the root `resolutions` pin is the dominant
50+
fix path; direct-dependency bumps are the exception.
51+
- The repo provides `yarn upgrade-dep -p <pkg> -v <version>` (see
52+
`scripts/upgrade-workspace-dependency.ts`). It ONLY scans module
53+
manifests for DIRECT deps, so for a transitive dep it will print
54+
"No packages found" and do nothing — that is expected; fall back to a
55+
root `resolutions` edit. Also note `upgrade-dep` runs a plain
56+
`yarn install` (full `postinstall` monorepo build) UNLESS you pass
57+
`--ignore-scripts`; always pass `--ignore-scripts` to stay within the
58+
runner time budget.
59+
60+
## Early exit (do this first)
61+
62+
If an open PR already exists on a branch matching
63+
`nightshift/iyarc-prune-*`, stop and report — do not open a second:
64+
65+
gh pr list --state open --search "head:nightshift/iyarc-prune"
66+
67+
## Read context first
68+
69+
Before changing anything, read:
70+
1. `.iyarc` — the full ignore list and every justification comment.
71+
2. The root `package.json` `resolutions` block.
72+
3. `scripts/upgrade-workspace-dependency.ts` (the `yarn upgrade-dep` tool).
73+
4. `CLAUDE.md` and `commitlint.config.js` (commit conventions).
74+
75+
## Per-exclusion evaluation
76+
77+
For each `GHSA-*` entry in `.iyarc`:
78+
79+
1. Identify the affected package and the path that pulls it in. The
80+
justification comment usually names both; confirm with `yarn why <pkg>`.
81+
2. Determine whether a PATCHED version now exists and is reachable for us
82+
(`yarn info <pkg> versions`, the GitHub advisory's first-patched
83+
version, registry metadata).
84+
3. Decide whether to attempt a fix:
85+
- SKIP if the justification is "no upstream fix exists" / patched
86+
range is `<0.0.0` (e.g. `sanitize-html` GHSA-rpr9-rxv7-x643, `sjcl`
87+
GHSA-2w8x-224x-785m) UNLESS a real fix has since shipped.
88+
- SKIP if the only available fix requires a major bump of a pinning
89+
parent (e.g. `tar` / `minimatch` pinned by `lerna` /
90+
`yeoman-generator`) AND that bump is incompatible. Record it under
91+
"Still blocked" in the report.
92+
- Otherwise, attempt the bump.
93+
94+
## Attempt a fix (per removable exclusion)
95+
96+
1. Bump compatibly:
97+
- Transitive dep controlled by root `resolutions` (the common case):
98+
update the pin in the root `package.json` `resolutions` block.
99+
- Direct dependency (rare here): `yarn upgrade-dep -p <pkg>
100+
-v <patched-version> --ignore-scripts`.
101+
2. Refresh the lockfile without triggering a full monorepo build:
102+
`NOYARNPOSTINSTALL=1 yarn install`.
103+
3. Remove the satisfied exclusion from `.iyarc` — delete the `GHSA-*`
104+
line AND its preceding `# Excluded because:` comment block.
105+
106+
## Feedback loop / proof (abandon on failure)
107+
108+
After each attempted fix, run the SAME gates the release pipeline runs,
109+
in this order:
110+
1. Run the release gate: `yarn run audit-high`. It MUST pass with the
111+
exclusion removed. Capture the output.
112+
2. Run `yarn check-deps`. It MUST pass — a `resolutions` change can break
113+
cross-workspace version consistency. This is both a release-job step
114+
(it runs immediately after audit in the release workflow) and a PR-CI
115+
gate, so a failure here means the PR would be rejected anyway.
116+
3. Build and unit-test the affected module(s) only (keep within the
117+
runner time budget — do NOT build/test the whole monorepo):
118+
`yarn lerna run build --scope <pkg>` and
119+
`yarn lerna run unit-test --scope <pkg>`.
120+
4. If ANY step fails — no compatible fix, audit still flags the advisory,
121+
check-deps fails, build breaks, or tests fail — revert that
122+
dependency's changes and restore its exclusion in `.iyarc`. Never open
123+
a PR with a red feedback loop. The full test suite still runs in PR CI
124+
as a backstop.
125+
126+
## Commit and pull request (only if at least one exclusion was removed
127+
with a fully green feedback loop)
128+
129+
- Branch: `nightshift/iyarc-prune-YYYY-MM-DD` (use today's date).
130+
- Conventional commit (commitlint extends `@commitlint/config-conventional`;
131+
`deps` and `root` are valid scopes), e.g.:
132+
`chore(deps): bump <pkg> to <version>, drop <GHSA> from .iyarc`.
133+
commitlint enforces `references-empty: never`, so the commit MUST carry
134+
an issue reference: include `Ticket: HSM-410` in the footer.
135+
- Open a single NON-draft PR. Labels: `nightshift`, `automated`,
136+
`dependencies`.
137+
- Assign the PR to `gokulhost` so it does not get lost:
138+
`gh pr edit --add-assignee gokulhost`. CODEOWNERS reviewers are
139+
assigned automatically and separately.
140+
- PR body must contain:
141+
- A table of each removed exclusion: GHSA id, package, old -> new
142+
version, the advisory it resolves.
143+
- The pasted `yarn run audit-high` and `yarn check-deps` output showing
144+
they now pass.
145+
- Build/test results for the affected module(s).
146+
- A "Still blocked" section listing every exclusion that could NOT be
147+
removed and the reason (no upstream fix / incompatible parent pin).
148+
149+
## Output rules
150+
151+
- If nothing is safely prunable this cycle, open no PR and report
152+
"no exclusions prunable this cycle" in the job summary, including the
153+
"Still blocked" breakdown so reviewers see what was evaluated.
154+
- Only ever modify `.iyarc`, dependency manifests (`package.json`),
155+
and `yarn.lock`. Do not modify product/source code.
156+
157+
labels:
158+
- nightshift
159+
- automated
160+
- dependencies
161+
162+
pull_requests:
163+
draft: false
164+
branch_prefix: 'nightshift/'
165+
labels:
166+
- nightshift
167+
- automated
168+
- dependencies

0 commit comments

Comments
 (0)