MetaMask / MetaMask/metamask-extension
[P2] CI rebuilds work that already exists when the run listing comes back stale
- Dominant language
- TypeScript
- Stars
- 13.2k
- Forks
- 5.6k
- Avg merge
- 2d 5h
- Merged PRs (30d)
- 451
Description
**Parent Epic:** [#6944 Performance Quality Gates](https://github.com/MetaMask/MetaMask-planning/issues/6944) → [#7182 Benchmarks: Reliability](https://github.com/MetaMask/MetaMask-planning/issues/7182) → [#7206 CI Reliability Improvements](https://github.com/MetaMask/MetaMask-planning/issues/7206)
**File:** `.github/workflows/get-requirements.yml`
**Size:** S | **Hours:** 2
---
## Problem
CI rebuilds work that already exists and runs a full benchmark suite against it, because a reusable build was there and the lookup didn't see it.
`find-reusable-builds` takes the 10 most recent `main.yml` runs and uses whatever the API returns (confirmed still `per_page: 10` with a single request, no retry, on `main` at `b3a1226`, 2026-06-25), and that listing intermittently serves a stale page.
Two cases in the 250 most recent PRs, both read from the `get-requirements` job logs:
These are CI runs on https://github.com/MetaMask/metamask-extension/pull/45412:
- [Attempt 1](https://github.com/MetaMask/metamask-extension/actions/runs/31507480239/job/93832657904#step:9:1) got ten `main` runs all created 2026-07-15, and [ran the benchmarks](https://github.com/MetaMask/metamask-extension/actions/runs/31507480239/job/93834301133) across 19 jobs. Those ten are exactly the ten `main.yml` runs in that window, with several hundred newer ones already in existence, so it was page 1 of a frozen listing rather than a filter.
- [Attempt 3](https://github.com/MetaMask/metamask-extension/actions/runs/31507480239/job/93856676795#step:9:1) found a matching build hash and [skipped them](https://github.com/MetaMask/metamask-extension/actions/runs/31507480239/job/93856848116).
And on https://github.com/MetaMask/metamask-extension/pull/45172:
- [Attempt 1](https://github.com/MetaMask/metamask-extension/actions/runs/31365356027/job/93382451828#step:9:1) got ten runs from 2026-03-24/25, every one recording `hash not found` because they predate the `build-source-hash` status, and [ran benchmarks](https://github.com/MetaMask/metamask-extension/actions/runs/31365356027/job/93383446960) across 17 jobs.
- [Attempt 4](https://github.com/MetaMask/metamask-extension/actions/runs/31365356027/job/93413164147#step:9:1) got current runs and [skipped them](https://github.com/MetaMask/metamask-extension/actions/runs/31365356027/job/93413322640).
`build-source-hash` was identical across attempts in both, so the input never changed — only what the listing returned.
When `build-source-hash` matches a base build the build output is identical, so skipping is the intended outcome — the later attempt had the correct answer and the earlier one had missed it. Staleness also only ever causes a **miss**, never a spurious match, since a match still requires hash equality and every required artifact to be present.
So the cost is a wasted build-and-benchmark cycle, not a bypass. The skip that would genuinely be wrong is a PR touching only benchmark-owned files, where the build hash matches and the change goes unmeasured — that is #45460, tracked separately (open, unmerged, stacked on this ticket's fix PR #45352).
---
## Solution
Re-request the listing once when the scan finds no reusable build, and rescan only if it came back different. Hanging the retry off the miss costs an extra call only where CI had already decided to rebuild.
This is implemented in #45352 (open, unmerged): the diff adds exactly this — a single retry on a miss, with its own `try`/`catch` so a failed retry can't discard a first listing that succeeded. #45352's own PR description also records that an earlier revision tried triggering the retry off a `repository.pushed_at` freshness comparison instead, and dropped that approach because it fired on nearly every base-branch lookup.
---
## Acceptance Criteria
- [ ] The lookup re-requests the listing when the scan finds no reusable build, and rescans only on a changed response.
- [ ] A stale first response followed by a fresh retry is visible in the job log.
- [ ] No behavior change when the first response is already current (one extra API call only on the stale path).
- [ ] Rate of unnecessary rebuilds re-measured over the following 250 PRs and compared against the 2 of 250 baseline.
---
## Labels
`team-extension-platform`, `area-ci`
---
## Dependencies
**Addressed by, not yet merged:** #45352 (open — see Solution above)
**Related:** #45460 (open, unmerged, stacked on #45352 — covers the case where a matching build hash should still not skip)
Contributor guide
Research direction
Start in .github/workflows/get-requirements.yml at find-reusable-builds, then review the implementation in PR #45352 and its job logs. Verify the retry and changed-response rescan against the acceptance criteria, including log visibility and the follow-up measurement across 250 PRs.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- github-actions
- Domain
- ci-cd
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 20/100