Skip to content

fix(storage): prune redundant intermediate message_update frames #3215

fix(storage): prune redundant intermediate message_update frames

fix(storage): prune redundant intermediate message_update frames #3215

Workflow file for this run

name: CI
on:
push:
# Integration branches are listed here as well as below: a pull_request run
# only ever proves one part merged into the branch, so without a push
# trigger the accumulated state of the branch that eventually reaches main
# is never built on its own.
branches: [main, integration/kv-asset-server-backend, integration/agent-workbench]
pull_request:
branches:
[
main,
feat/maic-editor-v0,
feat/maic-editor-v1,
runtime-server-backend,
integration/kv-asset-server-backend,
integration/agent-workbench,
]
concurrency:
group: ci-${{ github.ref }}
# Never cancel a main run. Each main run validates only its own push range, so
# a superseded run takes the range that contained a package change with it and
# the replacement, comparing against the cancelled tip, sees nothing.
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
check:
name: Lint, Typecheck & Unit Tests
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
# Cheap bash-only check so a broken helper fails before pnpm install.
# Quiet annotations: the expected-failure case would otherwise paint
# the check with a fake ::error::.
- name: Parallel runner self-test
env:
CI_PARALLEL_ANNOTATE: '0'
run: |
set -euo pipefail
scripts/ci-run-parallel.sh ok 'true' ok2 'true'
if scripts/ci-run-parallel.sh ok 'true' bad 'exit 7'; then
echo 'ci-run-parallel.sh should have failed'
exit 1
fi
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- name: Package version bumps
if: github.event_name == 'pull_request'
run: node scripts/check-package-version-bumps.mjs "$BASE_SHA"
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
# A branch creation or a force push reports an unusable `before`. Fail
# rather than substituting HEAD^: a force push can replace many commits at
# once, so the previous commit is not the range that needs checking, and
# publishing requires this run to be green.
- name: Package version bumps (main push)
if: github.event_name == 'push'
run: |
set -euo pipefail
base="$BEFORE_SHA"
if [ -z "$base" ] || ! git rev-parse --verify --quiet "$base^{commit}" >/dev/null; then
echo "::error::Push range base ${base:-<empty>} is unavailable, so this push cannot be checked."
echo "Re-run after the branch has an ordinary push range, or verify the versions by hand."
exit 1
fi
node scripts/check-package-version-bumps.mjs "$base"
env:
BEFORE_SHA: ${{ github.event.before }}
# The tarball smoke test proves this about the bytes that would actually
# be published, but it installs five package tarballs, so it runs only on
# the release path. This is the cheap source-level form, here so that a
# pull request restoring `workspace:*` fails at review time rather than at
# release time, after a version number has already been spent.
- name: Internal dependency ranges
run: node scripts/check-internal-dependency-ranges.mjs
- run: pnpm install --frozen-lockfile
# `postinstall` builds all five @openmaic packages, and some of them
# generate tracked, publishable files (renderer's fonts.css and its KaTeX
# font snapshot). The publish workflow refuses to release when the build
# rewrites one; catching it here means a stale generated file is a pull
# request failure instead of a release failure.
#
# Against GITHUB_SHA, not the index or HEAD: a bare `git diff` misses
# staged changes, while install code can create a commit and move HEAD.
# This check exists precisely because code ran before it, so its reference
# point must be something that code cannot move. Disabling replacement
# objects also prevents a local replace ref from redirecting the commit.
- name: Verify the install did not rewrite tracked package files
run: |
set -euo pipefail
actual_head="$(git --no-replace-objects rev-parse HEAD)"
if [ "$actual_head" != "$GITHUB_SHA" ]; then
echo "::error::HEAD moved from $GITHUB_SHA to $actual_head during installation."
exit 1
fi
if ! git --no-replace-objects diff --quiet "$GITHUB_SHA" -- packages/@openmaic; then
echo "::error::Installing rewrote tracked files under packages/@openmaic."
echo "Regenerate them and commit the result."
git --no-replace-objects --no-pager diff --stat "$GITHUB_SHA" -- packages/@openmaic
exit 1
fi
echo "Tracked package files match the commit under test."
# These four do not share state. Sequential they were ~2 minutes; the
# slowest (ESLint) is the new bound.
- name: Prettier, ESLint, TypeScript, i18n
run: |
scripts/ci-run-parallel.sh \
'prettier' 'pnpm check' \
'eslint' 'pnpm lint' \
'tsc' 'npx tsc --noEmit' \
'i18n' 'pnpm check:i18n-keys'
# Keep these sequential. Running root vitest alongside the storage
# package on a 4-core runner made 5s-timeout tests flake (CPU
# contention, not a product regression).
- name: Unit Tests
run: pnpm test
- name: Unit Tests (importer)
run: pnpm --filter @openmaic/importer test
- name: Unit Tests (dsl)
run: pnpm --filter @openmaic/dsl test
- name: TypeScript (generation)
run: pnpm --filter @openmaic/generation run typecheck
- name: Unit Tests (generation)
run: pnpm --filter @openmaic/generation test
- name: Node consumer smoke (generation scene)
shell: bash
run: |
set -euo pipefail
port=43127
node scripts/generation-node-smoke-server.mjs --port "$port" >"$RUNNER_TEMP/generation-smoke-server.log" 2>&1 &
server_pid=$!
cleanup() {
kill "$server_pid" 2>/dev/null || true
wait "$server_pid" 2>/dev/null || true
}
trap cleanup EXIT
for attempt in {1..50}; do
if node -e "fetch('http://127.0.0.1:$port/health').then(r => { if (!r.ok) process.exit(1) }).catch(() => process.exit(1))"; then
break
fi
if [ "$attempt" -eq 50 ]; then
cat "$RUNNER_TEMP/generation-smoke-server.log"
exit 1
fi
sleep 0.1
done
output="$(node scripts/generation-node-smoke.mjs \
--requirement "Explain dependency injection" \
--endpoint "http://127.0.0.1:$port" \
--model smoke-model)"
printf '%s\n' "$output"
node -e 'const value = JSON.parse(process.argv[1]); if (!Array.isArray(value.outlines) || value.outlines.length === 0 || !value.scene || value.sceneValidation?.valid !== true) process.exit(1)' "$output"
# Covers the package's own test tree, which the root tsc reaches only by an
# incidental glob. The device-scope guard is written as `@ts-expect-error`
# probes in those tests, and a probe nothing type-checks proves nothing.
- name: TypeScript (storage, incl. tests)
run: pnpm --filter @openmaic/storage run typecheck
- name: Unit Tests (storage)
run: pnpm --filter @openmaic/storage test
render-service:
name: Render Service (typecheck + tests)
runs-on: ubuntu-latest
timeout-minutes: 10
# The producer dep bundles puppeteer; skip its Chromium download — the unit
# tests exercise the service's boundaries (unzip, admission, body caps) and
# never launch a browser.
env:
PUPPETEER_SKIP_DOWNLOAD: "true"
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
# render-service is its own npm package (own lockfile, Node-only deps),
# excluded from the root eslint/tsc/pnpm workspace — so it gets its own
# install + quality gate here rather than riding on the `check` job.
cache: npm
cache-dependency-path: render-service/package-lock.json
- name: Install
working-directory: render-service
run: npm ci
- name: TypeScript
working-directory: render-service
run: npm run typecheck
- name: Unit Tests
working-directory: render-service
run: npm test
- name: Build container image
run: docker build --tag openmaic-render-service:ci render-service
e2e:
name: E2E Tests
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile
# Browser tarballs live under ~/.cache/ms-playwright. A cold download of
# Chromium from the Playwright CDN has sat for 20+ minutes on this runner
# fleet; a lockfile-keyed cache turns that into a restore.
- name: Cache Playwright browsers
id: playwright-cache
uses: actions/cache@v4
with:
path: ~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ hashFiles('pnpm-lock.yaml') }}
# Browser tarball only. `install-deps` talks to Ubuntu apt; on this
# runner fleet that mirror has sat through the whole 15-minute job
# budget. ubuntu-latest already ships the libraries Chromium needs.
# Bound the Microsoft CDN download so a stall retries instead of hanging.
- name: Install Playwright Chromium
run: |
set -euo pipefail
for attempt in 1 2 3; do
if timeout -k 10 240 pnpm exec playwright install chromium; then
exit 0
fi
echo "Playwright Chromium download attempt ${attempt} failed, retrying..."
sleep 5
done
echo "::error::Playwright Chromium download failed after 3 attempts."
exit 1
# Measures the emitted cover cards in Chromium. Lives with the unit tests
# (it needs the compiler), but only this job has a browser, so it runs
# here with the flag that turns a missing one into a failure.
- name: Cover-card layout guardrail
run: pnpm exec vitest run tests/video-export/cover-card-layout.browser.test.ts
env:
COVER_LAYOUT_BROWSER: '1'
- name: Interactive static HTML Chromium smoke
run: pnpm exec vitest run tests/video-export/interactive-static-html.browser.test.ts
env:
INTERACTIVE_STATIC_BROWSER: '1'
# runner.* is only valid in step contexts (not job-level env).
- name: Materialize Hyperframes lint samples
run: pnpm exec vitest run tests/video-export/e2e-materialize.test.ts
env:
HF_E2E_DIR: ${{ runner.temp }}/openmaic-hyperframes-samples
# Hyperframes 0.7.60 reports warning-only lint with exit status zero, so
# require its plain clean summary as well as a successful process.
- name: Lint Hyperframes samples
shell: bash
env:
HF_E2E_DIR: ${{ runner.temp }}/openmaic-hyperframes-samples
run: |
set -euo pipefail
for sample in quiz pbl-v2 pbl-legacy pbl-dense mixed arabic interactive-static; do
dir="$HF_E2E_DIR/$sample"
if output="$(pnpm exec hyperframes lint "$dir" 2>&1)"; then
status=0
else
status=$?
fi
printf '%s\n' "$output"
if [ "$status" -ne 0 ]; then
echo "::error::Hyperframes lint failed for $sample (exit $status)."
exit "$status"
fi
if ! grep -Fq -- '0 errors, 0 warnings' <<<"$output"; then
echo "::error::Hyperframes lint for $sample did not report zero errors and zero warnings."
exit 1
fi
done
# Incremental compilation artifacts only. Keyed on the lockfile plus
# next.config.ts so a dependency or webpack-rule change misses; source
# edits still reuse the restore-key prefix.
- name: Cache Next.js build
uses: actions/cache@v4
with:
path: .next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('pnpm-lock.yaml') }}-${{ hashFiles('next.config.ts') }}
restore-keys: |
${{ runner.os }}-nextjs-${{ hashFiles('pnpm-lock.yaml') }}-
# Dedicated so a cold `next build` is not charged against Playwright's
# webServer readiness budget (120s). NEXT_PUBLIC_MAIC_EDITOR_ENABLED is a
# build-time flag and must be set here, not only on `pnpm start`.
- name: Build
run: pnpm build
env:
NEXT_PUBLIC_MAIC_EDITOR_ENABLED: 'true'
- name: Run e2e tests
run: pnpm exec playwright test
- uses: actions/upload-artifact@v4
if: failure()
with:
name: playwright-report
path: playwright-report/
retention-days: 7