Skip to content

[security](deps): bump the npm_and_yarn group across 1 directory with 7 updates #887

[security](deps): bump the npm_and_yarn group across 1 directory with 7 updates

[security](deps): bump the npm_and_yarn group across 1 directory with 7 updates #887

Workflow file for this run

name: CI
on:
push:
branches: ["main", "master"]
pull_request:
permissions:
contents: read
jobs:
# Multi-platform build matrix
build:
permissions:
contents: read
actions: read
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
include:
- os: ubuntu-latest
platform: web
- os: macos-latest
platform: macos
runs-on: ${{ matrix.os }}
env:
SNAPSHOT_TESTS: ${{ matrix.platform == 'macos' && '1' || '0' }}
SNAPSHOT_RECORD: "0"
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
fetch-depth: 0
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
- name: Setup Node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
with:
node-version: 20
- name: Setup pnpm
uses: pnpm/action-setup@08c4be7e2e672a47d11bd04269e27e5f3e8529cb # v4
with:
version: 10.33.0
- name: Get pnpm store directory
shell: bash
run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: Setup pnpm cache
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Setup Swift (macOS only)
if: matrix.os == 'macos-latest'
run: |
swift --version
xcrun --find swift
- name: Install deps
run: pnpm install --frozen-lockfile --prod=false
- name: Check version synchronization
run: pnpm sync:versions:check
- name: Fetch base ref (PR only)
if: github.event_name == 'pull_request'
run: git fetch origin ${{ github.base_ref }} --depth=1
- name: Detect apps-sdk-ui version change
id: apps-sdk-change
run: node scripts/check-apps-sdk-ui-version.mjs
- name: Agent design prepare evidence (web platform PR only)
if: github.event_name == 'pull_request' && matrix.platform == 'web'
env:
AGENT_DESIGN_PREPARE_BASE: origin/${{ github.base_ref }}
run: pnpm agent-design:prepare:changed
- name: Run Apps SDK UI drift tests
if: steps.apps-sdk-change.outputs.changed == 'true'
run: pnpm test:drift
- name: Stamp upstream alignment log
if: steps.apps-sdk-change.outputs.changed == 'true'
run: pnpm ds:alignment:stamp
- name: Ensure alignment stamp committed
if: steps.apps-sdk-change.outputs.changed == 'true'
run: git diff --exit-code docs/design-system/UPSTREAM_ALIGNMENT.md
- name: Lint (web platform only)
if: matrix.platform == 'web'
run: pnpm lint
- name: Policy checks (web platform only)
if: matrix.platform == 'web'
run: pnpm test:policy
- name: Design system coverage matrix check (web platform only)
if: matrix.platform == 'web'
run: pnpm ds:matrix:check
- name: Quality debt check (warn-first, web platform only)
if: matrix.platform == 'web'
continue-on-error: true
run: pnpm quality-debt:check
- name: Quality debt report (warn-first, web platform only)
if: matrix.platform == 'web'
continue-on-error: true
run: pnpm quality-debt:report -- --output reports/qa/quality-debt-burndown-ci.md
- name: Format check (web platform only)
if: matrix.platform == 'web'
run: pnpm format:check
- name: Compliance checks (web platform only)
if: matrix.platform == 'web'
run: pnpm lint:compliance
- name: Onboarding parity + outcome checks (web platform only)
if: matrix.platform == 'web'
run: pnpm onboarding:check
- name: Type-check packages (web platform only)
if: matrix.platform == 'web'
run: |
pnpm -C packages/ui type-check
pnpm -C packages/runtime type-check
pnpm -C packages/tokens type-check
- name: Strict type-check (informational — tracks migration to noUncheckedIndexedAccess)
if: matrix.platform == 'web'
continue-on-error: true
run: |
set +e
pnpm exec tsc -p tsconfig.strict.json --noEmit > /tmp/strict-typecheck.log 2>&1
strict_status=$?
if [ "$strict_status" -ne 0 ]; then
echo "Strict type-check remains informational; see sanitized tail below."
tail -20 /tmp/strict-typecheck.log | sed -E 's/^([^()]+)\(([0-9]+),([0-9]+)\): error TS/strict-typecheck \1:\2:\3 TS/'
fi
exit "$strict_status"
- name: Icon generation property tests (web platform only)
if: matrix.platform == 'web'
run: pnpm test:astudio-icons
- name: Runtime host adapter contract tests (web platform only)
if: matrix.platform == 'web'
run: pnpm test:runtime
- name: MCP tool contract tests (web platform only)
if: matrix.platform == 'web'
run: pnpm test:mcp-contract
- name: Install Playwright (web + macOS exemplar lanes)
if: matrix.platform == 'web' || matrix.platform == 'macos'
run: |
if [ "${{ runner.os }}" = "Linux" ]; then
pnpm exec playwright install --with-deps chromium
else
pnpm exec playwright install chromium
fi
- name: Exemplar evaluation (macOS baseline lane)
if: matrix.platform == 'macos'
run: pnpm test:exemplar-evaluation
- name: Enhanced build pipeline
run: node scripts/build-pipeline.mjs --platforms ${{ matrix.platform }}
- name: Bundle size budgets (web platform only)
if: matrix.platform == 'web'
run: pnpm bundle:monitor:strict
- name: Upload build artifacts
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: build-artifacts-${{ matrix.platform }}
path: |
packages/*/dist/
swift/*/.build/
swift/**/__Snapshots__/
.build-cache/
reports/qa/quality-debt-burndown-ci.md
retention-days: 7
a11y:
permissions:
contents: read
actions: read
runs-on: ubuntu-latest
needs: build
outputs:
storybook_changed: ${{ steps.storybook_changes.outputs.changed || 'false' }}
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
fetch-depth: 0
- name: Setup Node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
with:
node-version: 20
- name: Setup pnpm
uses: pnpm/action-setup@08c4be7e2e672a47d11bd04269e27e5f3e8529cb # v4
with:
version: 10.33.0
- name: Get pnpm store directory
shell: bash
run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: Setup pnpm cache
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install deps
run: pnpm install --frozen-lockfile --prod=false
- name: Download build artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
name: build-artifacts-web
path: .
- name: Install Playwright
run: pnpm exec playwright install --with-deps chromium
- name: Detect Storybook-related changes (PR only)
if: github.event_name == 'pull_request'
id: storybook_changes
shell: bash
run: |
git fetch origin "${{ github.base_ref }}" --depth=1
if git diff --name-only "origin/${{ github.base_ref }}...HEAD" | rg -q '^(platforms/web/apps/storybook/|\.storybook/|.*\.stories\.(ts|tsx|js|jsx|mdx)$)'; then
echo "changed=true" >> "$GITHUB_OUTPUT"
else
echo "changed=false" >> "$GITHUB_OUTPUT"
fi
- name: Cache UI dist
id: ui-dist-cache
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
with:
path: packages/ui/dist
key: ${{ runner.os }}-ui-dist-${{ hashFiles('packages/ui/src/**', 'packages/ui/package.json', 'pnpm-lock.yaml') }}
- name: Build UI (if cache miss)
if: steps.ui-dist-cache.outputs.cache-hit != 'true'
run: pnpm -C packages/ui build
- name: Build Storybook
if: github.event_name != 'pull_request' || steps.storybook_changes.outputs.changed == 'true'
run: pnpm storybook:build
- name: Run Storybook tests (a11y + interactions)
if: github.event_name != 'pull_request' || steps.storybook_changes.outputs.changed == 'true'
run: pnpm storybook:test
- name: Upload Storybook static output
if: github.event_name != 'pull_request' || steps.storybook_changes.outputs.changed == 'true'
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: storybook-static
path: platforms/web/apps/storybook/storybook-static/
retention-days: 7
- name: Run widget a11y audit
run: pnpm test:a11y:widgets:ci
env:
A11Y_STRICT: "1"
visual:
permissions:
contents: read
actions: read
issues: write
pull-requests: write
runs-on: ubuntu-latest
needs: build
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Setup Node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
with:
node-version: 20
- name: Setup pnpm
uses: pnpm/action-setup@08c4be7e2e672a47d11bd04269e27e5f3e8529cb # v4
with:
version: 10.33.0
- name: Get pnpm store directory
shell: bash
run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: Setup pnpm cache
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install deps
run: pnpm install --frozen-lockfile --prod=false
- name: Download build artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
name: build-artifacts-web
path: .
- name: Install Playwright
run: pnpm exec playwright install --with-deps chromium
- name: Run visual regression (Playwright)
run: pnpm test:visual:web
continue-on-error: true
- name: Upload screenshot artifacts (on failure)
if: failure()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: visual-screenshots-diff
path: |
apps/web/tests/visual/__snapshots__/
apps/web/playwright-report/visual/
retention-days: 7
- name: Fail job if visual tests failed
if: failure()
run: exit 1
- name: Comment PR with visual diff results
if: failure() && github.event_name == 'pull_request'
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const botComment = comments.find(comment =>
comment.user.type === 'Bot' &&
comment.body.includes('Visual Regression Tests')
);
const body = `## Visual Regression Tests Failed
Screenshots have changed and may require review.
### Steps to review:
1. Download the [visual-screenshots-diff artifact](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})
2. Compare images in \`__snapshots__\` with the actual results
3. If changes are intentional, run \`pnpm test:visual:update\` locally
\`${{ github.sha }}\``;
if (botComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: body,
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: body,
});
}
smoke-agent-browser:
permissions:
contents: read
actions: read
if: ${{ github.event_name != 'pull_request' }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Setup Node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
with:
node-version: 20
- name: Setup pnpm
uses: pnpm/action-setup@08c4be7e2e672a47d11bd04269e27e5f3e8529cb # v4
with:
version: 10.33.0
- name: Get pnpm store directory
shell: bash
run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: Setup pnpm cache
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install deps
run: pnpm install --frozen-lockfile --prod=false
- name: Download build artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
name: build-artifacts-web
path: .
- name: Build web app
run: pnpm -C platforms/web/apps/web build
env:
VITE_WIDGETS_BASE: http://127.0.0.1:4173
- name: Install Chromium
run: pnpm exec agent-browser install
- name: Install Playwright browser (smoke prereq)
run: pnpm exec playwright install --with-deps chromium
- name: Run smoke tests
run: pnpm test:agent-browser:ci
- name: Upload smoke test artifacts (on failure)
if: failure()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: smoke-test-agent-browser
path: test-results/agent-browser/**
retention-days: 7
# ─── Deploy Storybook to Cloudflare Pages ─────────────────────────────────
# Runs on every push to main (production deployment) and on PRs that touch
# stories (preview deployment with a unique URL per branch).
#
# Required secrets:
# CLOUDFLARE_API_TOKEN — Pages deployment token (Edit Pages permission)
# CLOUDFLARE_ACCOUNT_ID — Cloudflare account ID
#
# After first deploy, the production URL will be:
# https://design-system-storybook.pages.dev
deploy-storybook:
name: Deploy Storybook → Cloudflare Pages
runs-on: ubuntu-latest
needs: [a11y]
# Deploy on main push always; on PRs only if stories changed
if: |
github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master')
|| github.event_name == 'pull_request' && needs.a11y.outputs.storybook_changed == 'true'
permissions:
contents: read
deployments: write
pull-requests: write
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Download Storybook static output
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: storybook-static
path: storybook-static/
# If the a11y job skipped the build (no story changes on PR), this
# artifact won't exist. Continue so we can gate below.
continue-on-error: true
- name: Check artifact exists
id: artifact_check
run: |
if [ -d "storybook-static" ] && [ "$(ls -A storybook-static)" ]; then
echo "exists=true" >> "$GITHUB_OUTPUT"
else
echo "exists=false" >> "$GITHUB_OUTPUT"
fi
- name: Deploy to Cloudflare Pages
if: steps.artifact_check.outputs.exists == 'true'
id: cf_deploy
uses: cloudflare/wrangler-action@9acf94ace14e7dc412b076f2c5c20b8ce93c79cd # v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: pages deploy storybook-static --project-name=design-system-storybook --branch=${{ github.head_ref || github.ref_name }}
- name: Comment preview URL on PR
if: |
github.event_name == 'pull_request' &&
steps.artifact_check.outputs.exists == 'true' &&
steps.cf_deploy.outputs.deployment-url != ''
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const url = '${{ steps.cf_deploy.outputs.deployment-url }}';
const sha = context.sha.substring(0, 7);
const body = `## 📚 Storybook Preview\n\n| | |\n|---|---|\n| **URL** | ${url} |\n| **Commit** | \`${sha}\` |\n| **Branch** | \`${{ github.head_ref }}\` |\n\nBrowse components, run interaction tests, and check accessibility in the deployed Storybook.`;
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const existing = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Storybook Preview')
);
if (existing) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: existing.id,
body,
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body,
});
}