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
4 changes: 4 additions & 0 deletions .changeset/ci-cache-tier1-optimizations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
---

CI-only: turbo cache for the Release job, console-dist cache keyed on the objectui pin, restore-only turbo caches on PRs (main seeds them), CodeQL off pull_request (main push + weekly schedule), spec coverage moved to a nightly workflow. Releases nothing.
76 changes: 52 additions & 24 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,13 @@ jobs:
restore-keys: |
${{ runner.os }}-pnpm-store-v3-

- name: Setup Turbo cache
uses: actions/cache@v6
# Restore-only on PRs: PR-side saves (~5 turbo entries per push) churned
# the repo's 10 GB Actions cache pool and evicted the main-branch seeds —
# observed as sudden cold-cache spikes (Build Core 51s → 4m30s). PRs fall
# back to main's entries via the prefix restore-keys; only main pushes
# save (the "Save Turbo cache" step at the end of the job).
- name: Restore Turbo cache
uses: actions/cache/restore@v6
with:
path: .turbo/cache
key: ${{ runner.os }}-turbo-${{ github.job }}-${{ github.ref_name }}-${{ github.sha }}
Expand Down Expand Up @@ -142,25 +147,25 @@ jobs:
TURBO_SCM_BASE: ${{ github.event.pull_request.base.sha }}
run: pnpm turbo run test --affected --filter=!@objectstack/dogfood --concurrency=4

# Push to main: full run, but exclude spec's plain test task — the
# coverage step below executes the exact same 250-file spec suite once,
# with coverage. Previously the spec suite ran twice per push. Dogfood is
# excluded for the same reason as the PR step: the Dogfood job runs it.
# Push to main: full run. Spec's suite runs here plain (uninstrumented);
# the coverage-instrumented pass moved to the nightly Spec Coverage
# workflow (coverage-nightly.yml) — instrumentation added minutes to
# every main push for a trend artifact that is consulted occasionally at
# best. Dogfood is excluded for the same reason as the PR step: the
# Dogfood job runs it.
- name: Run all tests (push)
if: github.event_name == 'push'
run: pnpm turbo run test --filter=!@objectstack/spec --filter=!@objectstack/dogfood --concurrency=4

- name: Generate coverage report
if: github.event_name == 'push'
run: pnpm --filter @objectstack/spec test:coverage

- name: Upload coverage reports
if: github.event_name == 'push'
uses: actions/upload-artifact@v7
run: pnpm turbo run test --filter=!@objectstack/dogfood --concurrency=4

# Seed the shared Turbo cache from main only (see the restore step
# above). always(): keep the seed fresh even when a test fails, matching
# the old actions/cache post-step behavior.
- name: Save Turbo cache (main only)
if: always() && github.event_name == 'push'
uses: actions/cache/save@v6
with:
name: coverage-report
path: packages/spec/coverage/
retention-days: 30
path: .turbo/cache
key: ${{ runner.os }}-turbo-${{ github.job }}-${{ github.ref_name }}-${{ github.sha }}

dogfood:
# Sharded 2-way: the suite is ~60 independent test files, each booting its
Expand Down Expand Up @@ -209,10 +214,11 @@ jobs:
${{ runner.os }}-pnpm-store-v3-

# Shard-scoped key: the turbo test hash differs per shard (pass-through
# args are part of the task hash), and two same-named matrix jobs would
# otherwise race to save one cache entry per sha.
- name: Setup Turbo cache
uses: actions/cache@v6
# args are part of the task hash). Restore-only on PRs — see the Restore
# Turbo cache comment in the test job; the save step at the end of this
# job seeds from main only.
- name: Restore Turbo cache
uses: actions/cache/restore@v6
with:
path: .turbo/cache
key: ${{ runner.os }}-turbo-${{ github.job }}-${{ matrix.shard }}-${{ github.ref_name }}-${{ github.sha }}
Expand Down Expand Up @@ -247,6 +253,15 @@ jobs:
echo "::endgroup::"
done

# Seed the shared Turbo cache from main only (see the restore step
# above); shard-scoped key so the two matrix jobs don't collide.
- name: Save Turbo cache (main only)
if: always() && github.event_name == 'push'
uses: actions/cache/save@v6
with:
path: .turbo/cache
key: ${{ runner.os }}-turbo-${{ github.job }}-${{ matrix.shard }}-${{ github.ref_name }}-${{ github.sha }}

dogfood-gate:
# Stable required-check name for a SHARDED job (#3622 follow-up).
#
Expand Down Expand Up @@ -312,8 +327,13 @@ jobs:
restore-keys: |
${{ runner.os }}-pnpm-store-v3-

- name: Setup Turbo cache
uses: actions/cache@v6
# Restore-only on PRs: PR-side saves (~5 turbo entries per push) churned
# the repo's 10 GB Actions cache pool and evicted the main-branch seeds —
# observed as sudden cold-cache spikes (Build Core 51s → 4m30s). PRs fall
# back to main's entries via the prefix restore-keys; only main pushes
# save (the "Save Turbo cache" step at the end of the job).
- name: Restore Turbo cache
uses: actions/cache/restore@v6
with:
path: .turbo/cache
key: ${{ runner.os }}-turbo-${{ github.job }}-${{ github.ref_name }}-${{ github.sha }}
Expand Down Expand Up @@ -377,6 +397,14 @@ jobs:
packages/spec/json-schema/
retention-days: 30

# Seed the shared Turbo cache from main only (see the restore step above).
- name: Save Turbo cache (main only)
if: always() && github.event_name == 'push'
uses: actions/cache/save@v6
with:
path: .turbo/cache
key: ${{ runner.os }}-turbo-${{ github.job }}-${{ github.ref_name }}-${{ github.sha }}

build-docs:
name: Build Docs
needs: filter
Expand Down
17 changes: 10 additions & 7 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
name: CodeQL Security Analysis

# Deliberately NOT on pull_request: the analysis took ~4½ runner-minutes per
# PR sync, and everything a PR introduces is analyzed on main within minutes
# of the merge anyway (multi-agent merge cadence). Alerts surface on main's
# runs + the weekly deep pass instead of blocking/occupying PR runners.
# If branch protection ever required the "Analyze (javascript)" check, that
# requirement must be dropped along with this trigger.
on:
push:
branches:
- main
pull_request:
branches:
- main
schedule:
# Run at 02:00 UTC every Monday
- cron: '0 2 * * 1'

# A superseded analysis of an outdated commit has no value — cancel it. PR runs
# group by PR number; push/schedule runs group by ref, so a newer main push
# cancels only an in-flight main analysis (the newer commit gets analyzed).
# A superseded analysis of an outdated commit has no value — cancel it. A newer
# main push cancels only an in-flight main analysis (the newer commit still
# gets analyzed).
concurrency:
group: codeql-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
group: codeql-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
Expand Down
63 changes: 63 additions & 0 deletions .github/workflows/coverage-nightly.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Spec coverage, nightly. Moved off the per-push path: the coverage-
# instrumented spec suite added minutes of instrumentation overhead to every
# main push (ci.yml previously excluded spec's plain test task and ran this
# instead), for a trend artifact that is consulted occasionally at best. The
# plain (uninstrumented) spec suite still runs on every main push in ci.yml's
# Test Core; this workflow owns the coverage report.
name: Spec Coverage

on:
workflow_dispatch:
schedule:
- cron: '0 5 * * *' # 05:00 UTC nightly

permissions:
contents: read

jobs:
coverage:
name: Spec coverage report
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout repository
uses: actions/checkout@v7

- name: Setup Node.js
uses: actions/setup-node@v7
with:
node-version: '20'

- name: Enable Corepack
run: corepack enable

- name: Get pnpm store directory
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV

# Restore-only: scheduled runs read main's store cache; the per-push
# workflows own saving it.
- name: Restore pnpm cache
uses: actions/cache/restore@v6
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-v3-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-v3-

- name: Install dependencies
run: pnpm install --frozen-lockfile

# The spec package sits at the root of the workspace graph (no workspace
# deps) and its suite reads src/ directly, so no build step is needed —
# same reason lint.yml's typecheck gates run pre-build.
- name: Generate coverage report
run: pnpm --filter @objectstack/spec test:coverage

- name: Upload coverage report
uses: actions/upload-artifact@v7
with:
name: coverage-report
path: packages/spec/coverage/
retention-days: 30
15 changes: 13 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,11 @@ jobs:
# package from scratch on every run (~4½ min) while ci.yml's jobs — which
# do carry this cache — finished the same build in under a minute. Same
# key scheme as ci.yml so the fallback prefix can also hit main's caches.
- name: Setup Turbo cache
uses: actions/cache@v6
# Restore-only on PRs (same policy as ci.yml): PR-side saves churned the
# 10 GB Actions cache pool and evicted the main seeds; only main pushes
# save (the "Save Turbo cache" step at the end of the job).
- name: Restore Turbo cache
uses: actions/cache/restore@v6
with:
path: .turbo/cache
key: ${{ runner.os }}-turbo-${{ github.job }}-${{ github.ref_name }}-${{ github.sha }}
Expand Down Expand Up @@ -243,3 +246,11 @@ jobs:
# so it runs after the build step alongside the other consumer gates.
- name: Check skills TypeScript examples compile
run: pnpm --filter @objectstack/spec run check:skill-examples

# Seed the shared Turbo cache from main only (see the restore step above).
- name: Save Turbo cache (main only)
if: always() && github.event_name == 'push'
uses: actions/cache/save@v6
with:
path: .turbo/cache
key: ${{ runner.os }}-turbo-${{ github.job }}-${{ github.ref_name }}-${{ github.sha }}
36 changes: 35 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,19 @@ jobs:
restore-keys: |
${{ runner.os }}-pnpm-store-v3-

# This job ran the full workspace build cold on every main push (~4½
# min) — the same omission lint.yml's typecheck job had. Same key scheme
# as ci.yml. Runs only on main pushes, so plain save+restore is right
# here (this job is one of the cache seeders).
- name: Setup Turbo cache
uses: actions/cache@v6
with:
path: .turbo/cache
key: ${{ runner.os }}-turbo-${{ github.job }}-${{ github.ref_name }}-${{ github.sha }}
restore-keys: |
${{ runner.os }}-turbo-${{ github.job }}-${{ github.ref_name }}-
${{ runner.os }}-turbo-${{ github.job }}-

- name: Install dependencies
run: pnpm install --frozen-lockfile

Expand All @@ -57,13 +70,34 @@ jobs:
- name: Build
run: pnpm run build

# The vendored Console dist is a pure function of the objectui pin (and
# of the build script itself) — yet it was cloned + vite-built from
# scratch on every main push (~3 min). Cache the finished dist keyed on
# exactly those inputs; the stamp check below still verifies whatever
# dist ends up in place, restored or fresh.
- name: Cache vendored Console dist (keyed on the objectui pin)
id: console-dist-cache
uses: actions/cache@v6
with:
path: packages/console/dist
key: ${{ runner.os }}-console-dist-${{ hashFiles('.objectui-sha', 'scripts/build-console.sh') }}

- name: Build vendored @objectstack/console SPA
# Clones objectstack-ai/objectui at the SHA pinned in .objectui-sha,
# builds @object-ui/console, and copies dist/ into
# packages/console/dist/. Must run before publish so the
# prepublishOnly guard in @objectstack/console passes.
# prepublishOnly guard in @objectstack/console passes. Skipped when the
# cache above restored a dist built from the same pin.
if: steps.console-dist-cache.outputs.cache-hit != 'true'
run: bash scripts/build-console.sh

# Belt-and-suspenders for the cache path: build-console.sh stamps the
# objectui SHA it built from into dist/.objectui-sha; check:console-sha
# fails loudly if the dist in place (restored or fresh) drifts from the
# pin.
- name: Verify Console dist stamp matches pin
run: pnpm check:console-sha

- name: Downstream backward-compat smoke (live hotcrm)
# Pre-publish gate (#2035): the about-to-publish @objectstack/spec must
# not break a real third-party consumer pinned to a published release.
Expand Down
Loading