Skip to content

fix(ci): fix stale cache key and add full data sync to build-container.yml#111

Open
castrojo wants to merge 3 commits into
mainfrom
feature/fix-build-container-data-parity
Open

fix(ci): fix stale cache key and add full data sync to build-container.yml#111
castrojo wants to merge 3 commits into
mainfrom
feature/fix-build-container-data-parity

Conversation

@castrojo

@castrojo castrojo commented Apr 9, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes two critical data correctness bugs and one performance issue in the Go stats pipeline (from SO-5 bootc-ecosystem tech assessment).

SO-35: Stale cache key (Critical G1)

build-container.yml was using cache key tap-history-v1 while daily-build.yml uses tap-history-v4. This meant the GHCR OCI image build always got a cold/stale cache — the container image had no homebrew trend history at all.

Fix: Update both key and restore-keys from tap-history-v1- to tap-history-v4-.

SO-36: Missing data sync steps (Critical G2)

build-container.yml only synced homebrew data. The GHCR OCI image was missing testhub, countme, releases, supply-chain, scorecard, and brewfile analytics — a degraded subset of what the Pages site shows.

Fix: Add sync steps for:

  • fetch-brewfile-taps
  • fetch-testhub (with testhub-history-v1 cache restore + save)
  • fetch-countme
  • fetch-releases
  • fetch-supply-chain
  • fetch-scorecard

All steps use continue-on-error: true consistent with daily-build.yml pattern, so partial API failures don't block the container push. Cache save steps added so trend history accumulates over time.

SO-38: Fix computeArchStatus O(N×S log S) sort-per-call pattern (Medium/P1)

computeArchStatus and computeLastStatus were both sorting store.Snapshots on every call — an O(N×S log S) pattern that degrades with scale.

Root cause: Both functions internally sorted the snapshot slice before iterating, meaning S×N sorts (once per app per function call) instead of one.

Fix: Pre-sort store.Snapshots newest-first once before the two app-loops in runFetchTesthub(). Both computeArchStatus and computeLastStatus now receive a pre-sorted slice and iterate directly. The contract is documented in each function's godoc.

Regression tests added (cmd/stats/main_test.go):

  • TestComputeArchStatus_BothKnown — both arches resolved from newest snapshot
  • TestComputeArchStatus_NewestWins — newest data takes precedence over older failures
  • TestComputeArchStatus_Failing — failing result propagated correctly
  • TestComputeArchStatus_UnknownApp — missing app returns unknown/unknown
  • TestComputeArchStatus_EmptySnapshots — nil input returns unknown/unknown
  • TestComputeArchStatus_DoesNotMutateInput — input slice order is not modified by the function
  • TestComputeArchStatus_ArmOnlyResolvesFromOlderSnapshot — arch independence: each arch resolved independently from its most-recent snapshot

Testing

  • go test ./... passes: all 16 packages pass
  • actionlint passes on the updated workflow
  • Pattern matches daily-build.yml structure exactly

…r.yml

SO-35: Update cache key from tap-history-v1 to tap-history-v4, matching
the key used by daily-build.yml. The stale v1 key meant the GHCR container
image built with a cold cache every day, producing no homebrew trend history.

SO-36: Add missing data sync steps (testhub, countme, releases, supply-chain,
scorecard, brewfile-taps) with continue-on-error: true so partial failures
don't block the container image push. Also add save steps for both
tap-history-v4 and testhub-history-v1 caches so the container build
accumulates trend history over time.

The GHCR OCI image now produces a full-data dashboard matching the
GitHub Pages site.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude Sonnet 4.6 via GitHub Copilot
@gemini-code-assist

Copy link
Copy Markdown

Note

Gemini is unable to generate a review for this pull request due to the file types involved not being currently supported.

@coderabbitai

coderabbitai Bot commented Apr 9, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

CI workflow restructured: cache keys bumped for tap history (v1→v4), separate testhub/builds history caches added, the single "Sync tap data" step replaced by building the stats binary and many targeted stats fetch-* commands (each often continue-on-error), and cache restore/save steps split and versioned.

Changes

Cohort / File(s) Summary
GitHub Actions: workflow orchestration & caches
.github/workflows/build-container.yml
Increased job timeout; changed tap-history cache key from tap-history-v1-...tap-history-v4-...; added multiple .sync-cache restore steps for contributor/build/testhub histories; replaced single sync invocation with explicit go build of stats and many stats fetch-* steps (many with continue-on-error and some step timeouts); split save into three actions/cache/save steps guarded by if: always().
Docs: stats pipeline and CI docs
skills/SKILL.md
Expanded documented stats subcommands (many new fetch-* entries: brewfile taps, releases, contributors, scorecard, supply-chain, multiple fetch-builds-*, multiple fetch-quay-*), updated outputs to list specific src/data/*.json and .sync-cache/*-history.json, adjusted chart-empty selector and added an extra Playwright E2E step.
Stats CLI: snapshot sorting / compute helpers
stats-go/cmd/stats/main.go
runFetchTesthub now sorts store.Snapshots newest-first once; computeArchStatus and computeLastStatus changed to assume pre-sorted newest-first input and iterate without re-sorting (doc comments updated).
Unit tests: computeArchStatus coverage
stats-go/cmd/stats/main_test.go
Added extensive tests for computeArchStatus covering newest-first precedence, failure/unknown cases, non-mutation of input slice, and architecture independence.
E2E tests: selector & status markers
tests/e2e/smoke.spec.ts
Adjusted smoke test to assert Build Status column (td:nth-child(2)), switched known-status markers to /, and updated failure message text.

Sequence Diagram(s)

sequenceDiagram
  participant Runner as GitHub Runner
  participant Actions as Actions Steps
  participant Repo as Repository (src/.sync-cache)
  participant Cache as Actions Cache
  participant Stats as stats binary

  Runner->>Actions: start job (timeout=120m)
  Actions->>Cache: restore `tap-history-v4-${{ github.run_id }}` & other versioned caches
  Actions->>Repo: ensure .sync-cache files available
  Actions->>Runner: `go build` stats -> Stats
  Runner->>Stats: run `stats fetch-*` (multiple commands, many continue-on-error)
  Stats->>Repo: write `src/data/*.json` and `.sync-cache/*-history.json`
  Actions->>Cache: save `.sync-cache` -> `tap-history-v4-${{ github.run_id }}` (if: always())
  Actions->>Cache: save `testhub-history.json` (if: always())
  Actions->>Cache: save builds-history cache (if: always())
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

Possibly related PRs

Poem

🐰
I built the stats with careful paws,
Caches hopped from old to new, applause!
Fetches scurry, tests take flight,
Histories saved through day and night.
A carrot-cheer for CI delight! 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the two main fixes: stale cache key and missing data sync steps in the build-container.yml workflow.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description check ✅ Passed The pull request description clearly relates to the changeset, providing specific details about cache key fixes and missing data sync steps in CI workflows, which aligns with the file changes across build-container.yml, SKILL.md, and test files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
.github/workflows/build-container.yml (1)

63-87: Standardize timeouts across remaining fetch steps.

fetch-countme, fetch-supply-chain, and fetch-scorecard currently have no timeout, so a hung network call can stall the job. Add explicit timeout-minutes like the testhub/releases steps for consistency.

Suggested diff
       - name: Fetch countme active-user stats
         continue-on-error: true
+        timeout-minutes: 5
         env:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
         run: ./stats-go/stats fetch-countme

       - name: Fetch supply chain data
         continue-on-error: true
+        timeout-minutes: 5
         env:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
         run: ./stats-go/stats fetch-supply-chain

       - name: Fetch Scorecard data
         continue-on-error: true
+        timeout-minutes: 5
         env:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
         run: ./stats-go/stats fetch-scorecard
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/build-container.yml around lines 63 - 87, The three GitHub
Actions steps "Fetch countme active-user stats", "Fetch supply chain data", and
"Fetch Scorecard data" lack timeouts and can hang; add a timeout-minutes entry
(e.g., timeout-minutes: 5 to match the "Fetch release frequency data" step) to
each of those steps so they abort after the configured time and keep behavior
consistent with the existing "fetch-releases" step.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In @.github/workflows/build-container.yml:
- Around line 63-87: The three GitHub Actions steps "Fetch countme active-user
stats", "Fetch supply chain data", and "Fetch Scorecard data" lack timeouts and
can hang; add a timeout-minutes entry (e.g., timeout-minutes: 5 to match the
"Fetch release frequency data" step) to each of those steps so they abort after
the configured time and keep behavior consistent with the existing
"fetch-releases" step.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7022ed5f-b41d-4ef1-b681-6cb45f808bdf

📥 Commits

Reviewing files that changed from the base of the PR and between f1a6579 and 3c21d09.

📒 Files selected for processing (1)
  • .github/workflows/build-container.yml

castrojo and others added 2 commits April 9, 2026 02:53
SO-38: computeArchStatus and computeLastStatus both sorted their input
slice on every call (O(N×S log S) across all app loops). Pre-sort
store.Snapshots once before the app loops in runFetchTesthub() instead.
Both functions now receive pre-sorted newest-first input and iterate
directly. Add 7 regression tests for computeArchStatus covering: both
known, newest-wins, failing, unknown app, empty snapshots, no mutation,
and arch-independent resolution from older snapshots.

SO-40: Expand the skills/SKILL.md subcommand table from 3 entries to all
19 implemented subcommands (fetch-brewfile-taps, fetch-releases,
fetch-contributors, fetch-scorecard, fetch-supply-chain,
fetch-builds-{bluefin,aurora,bazzite,universal-blue,ucore,zirconium,
bootcrew,blue-build}, fetch-quay-{fedora,centos,almalinux}). Update the
daily-build.yml CI step list to reflect the full 15-step pipeline.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Assisted-by: Claude Sonnet 4.6 via GitHub Copilot
…test column

- Add restore/save caches for contributor-history and builds-history
- Add fetch steps for all 8 build pipeline targets (bluefin/aurora/bazzite/etc)
- Add fetch-quay steps for fedora/centos/almalinux
- Add job-level timeout-minutes: 120
- Fix smoke test: testhub status is column 2, uses ✅/❌ not 🟢/🔴

Assisted-by: Claude Sonnet 4.6 via GitHub Copilot
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant