Skip to content

chore: remove upstream Codespaces workflow #9

chore: remove upstream Codespaces workflow

chore: remove upstream Codespaces workflow #9

Workflow file for this run

name: Frontend CI
on:
pull_request:
merge_group:
push:
branches:
- master
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
permissions:
contents: read
pull-requests: write
actions: read
jobs:
# Job to decide if we should run frontend ci
# See https://github.com/dorny/paths-filter#conditional-execution for more details
# we skip each step individually, so they are still reported as success
# because many of them are required for CI checks to be green
changes:
runs-on: ubuntu-latest
timeout-minutes: 5
name: Determine need to run frontend checks
outputs:
frontend: ${{ steps.filter.outputs.frontend || 'true' }}
frontend_code: ${{ steps.filter.outputs.frontend_code || 'true' }}
steps:
# For pull requests it's not necessary to check out the code, but we
# also want this to run on master, so we need to check out
- uses: actions/checkout@v6
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
id: filter
if: github.event_name != 'push' # Run all tests on master push
with:
filters: |
frontend:
# Avoid running frontend tests for irrelevant changes
# NOTE: we are at risk of missing a dependency here.
- 'bin/**'
- 'frontend/**'
- 'ee/frontend/**'
- 'common/esbuilder/**'
- 'products/**/*.ts'
- 'products/**/*.tsx'
- 'products/**/*.json'
- 'playwright/**'
# Make sure we run if someone is explicitly change the workflow
- .github/workflows/ci-frontend.yml
# various JS config files
- .oxlintrc.json
- .oxfmtrc*
- babel.config.js
- package.json
- pnpm-lock.yaml
- jest.*.ts
- tsconfig.json
- tsconfig.*.json
- webpack.config.js
- stylelint*
- '**/*.md'
- '**/*.mdx'
- '**/*.yaml'
- '**/*.yml'
- .config/.markdownlint-cli2.jsonc
# Like `frontend` but excludes doc/config-only files that don't affect
# compiled output — used to skip Jest, bundle-size, and TypeScript checks
# when only markdown or YAML files change.
frontend_code:
- 'bin/**'
- 'frontend/**'
- 'ee/frontend/**'
- 'common/esbuilder/**'
- 'products/**/*.ts'
- 'products/**/*.tsx'
- 'products/**/*.json'
- 'playwright/**'
- .github/workflows/ci-frontend.yml
- .oxlintrc.json
- .oxfmtrc*
- babel.config.js
- package.json
- pnpm-lock.yaml
- jest.*.ts
- tsconfig.json
- tsconfig.*.json
- webpack.config.js
- stylelint*
frontend-format:
name: Frontend formatting
needs: changes
if: needs.changes.outputs.frontend == 'true'
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v6
- name: Install pnpm
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
- name: Fix node-gyp permissions
run: chmod +x ~/setup-pnpm/node_modules/.pnpm/pnpm@*/node_modules/pnpm/dist/node_modules/node-gyp/gyp/gyp_main.py
- name: Set up Node.js
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version-file: .nvmrc
cache: pnpm
cache-dependency-path: |
pnpm-lock.yaml
.github/workflows/ci-frontend.yml
- name: Install package.json dependencies with pnpm
run: |
pnpm --filter=@posthog/playwright... install --frozen-lockfile
bin/turbo --filter=@posthog/frontend prepare
- name: Check formatting with oxfmt
run: pnpm run format:frontend:check
- name: Lint with Stylelint
run: pnpm run lint:css
- name: Lint with Oxlint
run: pnpm exec oxlint --quiet
- name: Check markdown formatting with oxfmt
run: pnpm exec oxfmt --check "**/*.{md,mdx}"
- name: Check YAML formatting with oxfmt
run: pnpm exec oxfmt --check "**/*.{yaml,yml}"
- name: Lint markdown files
run: pnpm exec markdownlint-cli2 --config .config/.markdownlint-cli2.jsonc "**/*.{md,mdx}"
frontend-bundle-size:
name: Frontend bundle size
needs: [changes]
if: needs.changes.outputs.frontend_code == 'true' && github.event_name != 'merge_group'
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v6
with:
filter: blob:none
- name: Install pnpm
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
- name: Fix node-gyp permissions
run: chmod +x ~/setup-pnpm/node_modules/.pnpm/pnpm@*/node_modules/pnpm/dist/node_modules/node-gyp/gyp/gyp_main.py
- name: Set up Node.js
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version-file: .nvmrc
cache: pnpm
cache-dependency-path: |
pnpm-lock.yaml
.github/workflows/ci-frontend.yml
- name: Install package.json dependencies with pnpm
run: |
pnpm --filter=@posthog/playwright... install --frozen-lockfile
bin/turbo --filter=@posthog/frontend prepare
- name: Build products
run: pnpm --filter=@posthog/frontend build:products
- name: Check frontend bundle size
uses: preactjs/compressed-size-action@946a292cd35bd1088e0d7eb92b69d1a8d5b5d76a # v2
with:
build-script: '--filter=@posthog/frontend build'
install-script: 'pnpm --filter=@posthog/frontend... install'
compression: 'none'
# Check all JS bundles in the dist folder
pattern: 'frontend/dist/**/*.js'
# Exclude source maps and chunk files (chunk hashes change every build)
exclude: '{**/*.js.map,**/chunk*.js}'
# Only show large changes
minimum-change-threshold: 1000
order-by: 'Size:desc'
strip-hash: "-[A-Za-z0-9]{8}\\.js$"
- name: Check toolbar for CSP eval violations
run: pnpm --filter=@posthog/frontend check-toolbar-csp-eval
- name: Calculate dist folder size
id: dist-size
run: |
size_bytes=$(du -sb frontend/dist | cut -f1)
echo "size_bytes=${size_bytes}" >> $GITHUB_OUTPUT
echo "Frontend dist folder size: ${size_bytes} bytes ($(numfmt --to=iec-i --suffix=B ${size_bytes}))"
- name: Capture bundle size to PostHog
if: |
(github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == 'PostHog/posthog') ||
(github.event_name != 'pull_request' && github.repository == 'PostHog/posthog')
uses: PostHog/posthog-github-action@8c42e50f2c52e002eabb9bee3f69b152ee8fc1dd # v1.0.1
with:
posthog-token: ${{secrets.POSTHOG_API_TOKEN}}
event: 'posthog-ci-frontend-bundle-size'
properties: |
{
"size_bytes": ${{ steps.dist-size.outputs.size_bytes }},
"branch": ${{ toJSON(github.head_ref || github.ref_name) }},
"sha": ${{ toJSON(github.sha) }},
"pr_number": ${{ github.event.pull_request.number || 'null' }},
"event_type": ${{ toJSON(github.event_name) }}
}
frontend-typescript-checks:
name: Frontend typechecking
needs: [changes]
if: needs.changes.outputs.frontend_code == 'true'
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v6
- name: Install pnpm
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
- name: Fix node-gyp permissions
run: chmod +x ~/setup-pnpm/node_modules/.pnpm/pnpm@*/node_modules/pnpm/dist/node_modules/node-gyp/gyp/gyp_main.py
- name: Set up Node.js
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version-file: .nvmrc
cache: pnpm
cache-dependency-path: |
pnpm-lock.yaml
.github/workflows/ci-frontend.yml
- name: Install package.json dependencies with pnpm
run: |
pnpm --filter=@posthog/playwright... install --no-frozen-lockfile
bin/turbo --filter=@posthog/frontend prepare
- name: Restore .typegen cache
uses: actions/cache/restore@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
with:
path: .typegen
key: ${{ runner.os }}-typegen-${{ hashFiles('pnpm-lock.yaml') }}
restore-keys: ${{ runner.os }}-typegen-
- name: Build products
run: pnpm --filter=@posthog/frontend build:products
- name: Check if products.tsx and products.json are up to date
run: pnpm --filter=@posthog/frontend build:products && git diff --exit-code
- name: Kea typegen
run: pnpm --filter=@posthog/frontend typegen:write
- name: Re-format files after typegen
run: pnpm exec oxfmt "./{products,frontend/src}/**/*.{ts,tsx}"
- name: Save .typegen cache
if: github.ref == 'refs/heads/master'
uses: actions/cache/save@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
with:
path: .typegen
key: ${{ runner.os }}-typegen-${{ hashFiles('pnpm-lock.yaml') }}
- name: Run typescript with strict
run: pnpm --filter=@posthog/frontend typescript:check
env:
NODE_OPTIONS: --max-old-space-size=16384
- name: Check if schema.json and validators.js are up to date
run: pnpm --filter=@posthog/frontend schema:build:json && git diff --exit-code
- name: Check if mobile replay "schema.json" is up to date
run: pnpm --filter=@posthog/frontend mobile-replay:schema:build:json && git diff --exit-code
env:
NODE_OPTIONS: --max-old-space-size=8192
- name: Validate SetupTaskId completions
run: node bin/validate-setup-tasks.mjs
jest:
runs-on: ubuntu-latest
timeout-minutes: 15
needs: changes
if: needs.changes.outputs.frontend_code == 'true'
name: Jest test (${{ matrix.segment }} - ${{ matrix.chunk }})
strategy:
# If one test fails, still run the others
fail-fast: false
matrix:
segment: ['FOSS', 'EE']
chunk: [1, 2]
steps:
- uses: actions/checkout@v6
- name: Remove ee
if: matrix.segment == 'FOSS'
run: rm -rf ee
- name: Install pnpm
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
- name: Fix node-gyp permissions
run: chmod +x ~/setup-pnpm/node_modules/.pnpm/pnpm@*/node_modules/pnpm/dist/node_modules/node-gyp/gyp/gyp_main.py
- name: Set up Node.js
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version-file: .nvmrc
cache: pnpm
cache-dependency-path: |
pnpm-lock.yaml
.github/workflows/ci-frontend.yml
- name: Install package.json dependencies with pnpm
run: pnpm --filter=@posthog/frontend... install --frozen-lockfile
- name: Test with Jest
run: bin/turbo run test --filter=@posthog/frontend -- --maxWorkers=2
env:
NODE_OPTIONS: --max-old-space-size=16384
SHARD_INDEX: ${{ matrix.chunk }}
SHARD_COUNT: 2
calculate-running-time:
name: Calculate running time
needs: [jest, frontend-typescript-checks, frontend-format, frontend-bundle-size, changes]
runs-on: ubuntu-latest
timeout-minutes: 5
if: # Run on pull requests to PostHog/posthog + on PostHog/posthog outside of PRs - but never on forks or Dependabot (no secrets access)
always() && github.actor != 'dependabot[bot]' &&
needs.changes.outputs.frontend_code == 'true' && (
(github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == 'PostHog/posthog') ||
(github.event_name != 'pull_request' && github.repository == 'PostHog/posthog'))
steps:
- name: Capture running time to PostHog
uses: PostHog/posthog-github-action@eea1405eeb2d1d2259f0ee0b44d7b152869e6840 # v1.1.1
with:
posthog-token: ${{ secrets.POSTHOG_API_TOKEN }}
event: 'posthog-ci-running-time'
capture-run-duration: true
capture-job-durations: true
github-token: ${{ secrets.GITHUB_TOKEN }}
status-job: 'Frontend Tests Pass'
runner: 'github'
frontend_tests:
needs: [jest, frontend-format, frontend-bundle-size, frontend-typescript-checks]
name: Frontend Tests Pass
runs-on: ubuntu-latest
timeout-minutes: 5
if: always()
steps:
- run: exit 0
- name: Check outcomes
run: |
if [[ "${{ needs.jest.result }}" != "success" && "${{ needs.jest.result }}" != "skipped" ]]; then
echo "Frontend jest tests failed."
exit 1
fi
echo "Frontend jest tests passed."
if [[ "${{ needs.frontend-format.result }}" != "success" && "${{ needs.frontend-format.result }}" != "skipped" ]]; then
echo "Frontend linting failed."
exit 1
fi
echo "Frontend linting passed."
if [[ "${{ needs.frontend-bundle-size.result }}" != "success" && "${{ needs.frontend-bundle-size.result }}" != "skipped" ]]; then
echo "Frontend bundle size checks failed."
exit 1
fi
echo "Frontend bundle size checks passed."
if [[ "${{ needs.frontend-typescript-checks.result }}" != "success" && "${{ needs.frontend-typescript-checks.result }}" != "skipped" ]]; then
echo "Frontend TypeScript checks failed."
exit 1
fi
echo "Frontend TypeScript checks passed."