Skip to content

fix(deps): force undici >=7.28.0 via pnpm override (TAB-1090) (#593) #851

fix(deps): force undici >=7.28.0 via pnpm override (TAB-1090) (#593)

fix(deps): force undici >=7.28.0 via pnpm override (TAB-1090) (#593) #851

Workflow file for this run

name: Build & Test
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read
pull-requests: read
jobs:
detect-changes:
runs-on: ubuntu-latest
outputs:
core: ${{ steps.filter.outputs.core }}
cli: ${{ steps.filter.outputs.cli }}
server: ${{ steps.filter.outputs.server }}
extension: ${{ steps.filter.outputs.extension }}
workflows: ${{ steps.filter.outputs.workflows }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Detect file changes
uses: dorny/paths-filter@v3
id: filter
with:
filters: |
core:
- 'packages/core/**'
- 'pnpm-lock.yaml'
- 'package.json'
cli:
- 'packages/cli/**'
- 'pnpm-lock.yaml'
- 'package.json'
server:
- 'packages/server/**'
- 'pnpm-lock.yaml'
- 'package.json'
extension:
- 'packages/extension/**'
- 'pnpm-lock.yaml'
- 'package.json'
workflows:
- '.github/workflows/**'
# Reports which secret-backed credentials are available to this run.
# The `secrets` context cannot be read in a job-level `if:`, so downstream
# jobs that need a secret gate on these outputs instead. Secrets are not
# passed to workflows triggered from forks or Dependabot, so the
# corresponding output is 'false' on those runs and the dependent job is
# cleanly skipped rather than hard-failing. Add one line per secret as more
# jobs come to need credentials.
check-secrets:
name: Check secret availability
runs-on: ubuntu-latest
outputs:
gcp_smoke_eval: ${{ steps.check.outputs.gcp_smoke_eval }}
steps:
- name: Check which secrets are available
id: check
run: |
echo "gcp_smoke_eval=${{ secrets.GCP_SMOKE_EVAL_SA_KEY != '' }}" >> "$GITHUB_OUTPUT"
setup:
runs-on: ubuntu-latest
needs: [detect-changes]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "22"
- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: 9
- name: Get pnpm store directory
shell: bash
run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: Cache pnpm store
uses: actions/cache@v4
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build core package
run: pnpm --filter pilo-core build
- name: Re-link workspace dependencies
run: pnpm install
# pnpm resolves package exports at install time. Because dist/ is
# created by the build step above (after the initial install), a
# second install is required so that downstream packages can resolve
# the pilo-core exports correctly.
- name: Cache core build
uses: actions/cache@v4
with:
path: |
packages/core/dist
packages/core/src/browser/ariaTree/bundle.ts
key: ${{ runner.os }}-core-dist-${{ github.sha }}
- name: Check formatting
run: pnpm format:check
core:
runs-on: ubuntu-latest
needs: [detect-changes, setup]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "22"
- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: 9
- name: Get pnpm store directory
shell: bash
run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: Cache pnpm store
uses: actions/cache@v4
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Cache core build
uses: actions/cache@v4
with:
path: |
packages/core/dist
packages/core/src/browser/ariaTree/bundle.ts
key: ${{ runner.os }}-core-dist-${{ github.sha }}
- name: Typecheck core
run: pnpm --filter pilo-core run typecheck
- name: Check schema artifacts are up-to-date
# Regenerates schemas/ and fails if the committed artifact drifts
# from what the generator produces. If this fails, run
# `pnpm --filter pilo-core run generate:schemas` locally and commit.
if: needs.detect-changes.outputs.core == 'true' || needs.detect-changes.outputs.workflows == 'true'
run: pnpm --filter pilo-core run check:schemas
- name: Test core
if: needs.detect-changes.outputs.core == 'true' || needs.detect-changes.outputs.workflows == 'true'
run: pnpm --filter pilo-core run test
cli:
runs-on: ubuntu-latest
needs: [detect-changes, setup]
if: needs.detect-changes.outputs.cli == 'true' || needs.detect-changes.outputs.core == 'true' || needs.detect-changes.outputs.workflows == 'true'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "22"
- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: 9
- name: Get pnpm store directory
shell: bash
run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: Cache pnpm store
uses: actions/cache@v4
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Cache core build
uses: actions/cache@v4
with:
path: |
packages/core/dist
packages/core/src/browser/ariaTree/bundle.ts
key: ${{ runner.os }}-core-dist-${{ github.sha }}
- name: Typecheck CLI
run: pnpm --filter pilo-cli run typecheck
- name: Test CLI
run: pnpm --filter pilo-cli run test
- name: Build CLI
run: pnpm --filter pilo-cli run build
server:
runs-on: ubuntu-latest
needs: [detect-changes, setup]
if: needs.detect-changes.outputs.server == 'true' || needs.detect-changes.outputs.core == 'true' || needs.detect-changes.outputs.workflows == 'true'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "22"
- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: 9
- name: Get pnpm store directory
shell: bash
run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: Cache pnpm store
uses: actions/cache@v4
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Cache core build
uses: actions/cache@v4
with:
path: |
packages/core/dist
packages/core/src/browser/ariaTree/bundle.ts
key: ${{ runner.os }}-core-dist-${{ github.sha }}
- name: Typecheck server
run: pnpm --filter pilo-server run typecheck
- name: Test server
run: pnpm --filter pilo-server run test
- name: Build server
run: pnpm --filter pilo-server run build:deploy
extension:
runs-on: ubuntu-latest
needs: [detect-changes, setup]
if: needs.detect-changes.outputs.extension == 'true' || needs.detect-changes.outputs.core == 'true' || needs.detect-changes.outputs.workflows == 'true'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "22"
- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: 9
- name: Get pnpm store directory
shell: bash
run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: Cache pnpm store
uses: actions/cache@v4
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Cache core build
uses: actions/cache@v4
with:
path: |
packages/core/dist
packages/core/src/browser/ariaTree/bundle.ts
key: ${{ runner.os }}-core-dist-${{ github.sha }}
- name: Typecheck extension
run: pnpm --filter pilo-extension run typecheck
- name: Test extension
run: pnpm --filter pilo-extension run test
- name: Build extension for Firefox
run: pnpm --filter pilo-extension run build:firefox
- name: Build extension for Chrome
run: pnpm --filter pilo-extension run build:chrome
- name: Get Playwright version
id: playwright-version
run: |
set -euo pipefail
if [ ! -f packages/extension/package.json ]; then
echo "Error: packages/extension/package.json not found" >&2
exit 1
fi
version=$(jq -re '.devDependencies["@playwright/test"] // empty' packages/extension/package.json)
if [ -z "$version" ]; then
echo "Error: @playwright/test devDependency not found in packages/extension/package.json" >&2
exit 1
fi
echo "version=$version" >> "$GITHUB_OUTPUT"
- name: Cache Playwright browsers
uses: actions/cache@v4
id: playwright-cache
with:
path: ~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ steps.playwright-version.outputs.version }}
- name: Install Playwright browsers
if: steps.playwright-cache.outputs.cache-hit != 'true'
run: pnpm --filter pilo-extension exec playwright install --with-deps chromium
- name: Install Playwright system dependencies
if: steps.playwright-cache.outputs.cache-hit == 'true'
run: pnpm --filter pilo-extension exec playwright install-deps chromium
- name: Run extension e2e tests
run: pnpm --filter pilo-extension run test:e2e:headless:chrome
- name: Upload Playwright report
uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:
name: playwright-report
path: packages/extension/playwright-report/
retention-days: 30
- name: Upload Playwright test results
uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:
name: playwright-test-results
path: packages/extension/test-results/
retention-days: 30
if-no-files-found: ignore
smoke-eval:
name: Smoke eval (Pilo agent on example.com)
runs-on: ubuntu-latest
needs: [detect-changes, setup, check-secrets]
# Skip (rather than fail) when the GCP credentials are unavailable — e.g.
# on fork or Dependabot PRs, where secrets are not provided. Note `&&`
# binds tighter than `||`, so the change-detection clause is parenthesized.
if: >
needs.check-secrets.outputs.gcp_smoke_eval == 'true' &&
(needs.detect-changes.outputs.cli == 'true' ||
needs.detect-changes.outputs.core == 'true' ||
needs.detect-changes.outputs.workflows == 'true')
# id-token: write is required if/when this job is switched to Workload
# Identity Federation (see the auth step below).
permissions:
contents: read
id-token: write
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "22"
- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: 9
- name: Get pnpm store directory
shell: bash
run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: Cache pnpm store
uses: actions/cache@v4
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Cache core build
uses: actions/cache@v4
with:
path: |
packages/core/dist
packages/core/src/browser/ariaTree/bundle.ts
key: ${{ runner.os }}-core-dist-${{ github.sha }}
- name: Build CLI
run: pnpm --filter pilo-cli run build
- name: Get Playwright version
id: playwright-version
run: |
set -euo pipefail
version=$(jq -re '.dependencies["playwright"] // empty' package.json)
if [ -z "$version" ]; then
echo "Error: playwright dependency not found in root package.json" >&2
exit 1
fi
echo "version=$version" >> "$GITHUB_OUTPUT"
- name: Cache Playwright browsers
uses: actions/cache@v4
id: playwright-cache
with:
path: ~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ steps.playwright-version.outputs.version }}
- name: Install Playwright browsers
if: steps.playwright-cache.outputs.cache-hit != 'true'
run: pnpm exec playwright install --with-deps chromium
- name: Install Playwright system dependencies
if: steps.playwright-cache.outputs.cache-hit == 'true'
run: pnpm exec playwright install-deps chromium
# GCP auth for Vertex AI (Gemini). Default path uses a service-account
# JSON secret; once Workload Identity Federation is provisioned for
# nonprod Vertex access, swap `credentials_json` for the WIF inputs
# shown in the commented block below.
- name: Authenticate to Google Cloud
uses: google-github-actions/auth@v2
with:
credentials_json: ${{ secrets.GCP_SMOKE_EVAL_SA_KEY }}
# workload_identity_provider: ${{ vars.GCP_SMOKE_EVAL_WIF_PROVIDER }}
# service_account: ${{ vars.GCP_SMOKE_EVAL_SERVICE_ACCOUNT }}
- name: Run smoke eval
env:
GOOGLE_CLOUD_PROJECT: moz-fx-tabs-nonprod
GOOGLE_CLOUD_REGION: us-central1
SMOKE_EVAL_PROVIDER: vertex
SMOKE_EVAL_MODEL: gemini-2.5-flash
SMOKE_EVAL_TIMEOUT_MS: "180000"
run: pnpm smoke-eval
- name: Upload smoke-eval log
if: always()
uses: actions/upload-artifact@v4
with:
name: smoke-eval-log
path: .smoke-eval-output/
retention-days: 14
if-no-files-found: warn