mirror of
https://github.com/BillyOutlast/posthog.git
synced 2026-02-04 03:01:23 +01:00
368 lines
16 KiB
YAML
368 lines
16 KiB
YAML
name: Frontend CI
|
|
on:
|
|
pull_request:
|
|
push:
|
|
branches:
|
|
- master
|
|
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
|
cancel-in-progress: true
|
|
|
|
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: depot-ubuntu-24.04-small
|
|
timeout-minutes: 5
|
|
name: Determine need to run frontend checks
|
|
outputs:
|
|
frontend: ${{ steps.filter.outputs.frontend }}
|
|
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@v4
|
|
|
|
- uses: dorny/paths-filter@4512585405083f25c027a35db413c2b3b9006d50 # v2
|
|
id: filter
|
|
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'
|
|
- 'playwright/**'
|
|
# Make sure we run if someone is explicitly change the workflow
|
|
- .github/workflows/ci-frontend.yml
|
|
# various JS config files
|
|
- .oxlintrc.json
|
|
- .prettier*
|
|
- 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
|
|
runs-on: depot-ubuntu-24.04
|
|
steps:
|
|
- name: Skip frontend checks
|
|
if: ${{ needs.changes.outputs.frontend == 'false' }}
|
|
run: |
|
|
echo "Skipping frontend checks - no frontend changes detected"
|
|
exit 0
|
|
|
|
# we need at least one thing to run to make sure we include everything for required jobs
|
|
- uses: actions/checkout@v4
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
|
|
- name: Install pnpm
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4
|
|
|
|
- name: Set up Node.js
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 22.17.1
|
|
cache: 'pnpm'
|
|
|
|
- name: Get pnpm cache directory path
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
id: pnpm-cache-dir
|
|
run: echo "PNPM_STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
|
|
|
- uses: actions/cache@v4
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
id: pnpm-cache
|
|
with:
|
|
path: ${{ steps.pnpm-cache-dir.outputs.PNPM_STORE_PATH }}
|
|
key: ${{ runner.os }}-pnpm-frontend-${{ hashFiles('pnpm-lock.yaml') }}
|
|
restore-keys: ${{ runner.os }}-pnpm-frontend-
|
|
|
|
- name: Install package.json dependencies with pnpm
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
run: |
|
|
pnpm --filter=@posthog/playwright... install --frozen-lockfile
|
|
bin/turbo --filter=@posthog/frontend prepare
|
|
|
|
- name: Check formatting with prettier
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
run: pnpm --filter=@posthog/frontend prettier:check
|
|
|
|
- name: Lint with Stylelint
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
run: pnpm --filter=@posthog/frontend lint:css
|
|
|
|
- name: Lint with Oxlint
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
run: pnpm --filter=@posthog/frontend lint:js -f github
|
|
|
|
frontend-toolbar-checks:
|
|
name: Frontend toolbar checks
|
|
needs: [changes]
|
|
runs-on: depot-ubuntu-24.04
|
|
steps:
|
|
- name: Skip frontend checks
|
|
if: ${{ needs.changes.outputs.frontend == 'false' }}
|
|
run: |
|
|
echo "Skipping frontend checks - no frontend changes detected"
|
|
exit 0
|
|
|
|
- uses: actions/checkout@v4
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
- name: Install pnpm
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4
|
|
|
|
- name: Set up Node.js
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 22.17.1
|
|
cache: 'pnpm'
|
|
|
|
- name: Get pnpm cache directory path
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
id: pnpm-cache-dir
|
|
run: echo "PNPM_STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
|
|
|
- uses: actions/cache@v4
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
id: pnpm-cache
|
|
with:
|
|
path: ${{ steps.pnpm-cache-dir.outputs.PNPM_STORE_PATH }}
|
|
key: ${{ runner.os }}-pnpm-frontend-${{ hashFiles('pnpm-lock.yaml') }}
|
|
restore-keys: ${{ runner.os }}-pnpm-frontend-
|
|
|
|
- name: Install package.json dependencies with pnpm
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
run: |
|
|
pnpm --filter=@posthog/playwright... install --frozen-lockfile
|
|
bin/turbo --filter=@posthog/frontend prepare
|
|
|
|
- name: Build products
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
run: pnpm --filter=@posthog/frontend build:products
|
|
|
|
- name: Check toolbar bundle size
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
uses: preactjs/compressed-size-action@946a292cd35bd1088e0d7eb92b69d1a8d5b5d76a # v2
|
|
with:
|
|
build-script: '--filter=@posthog/frontend build'
|
|
install-script: 'pnpm --filter=@posthog/frontend... install'
|
|
compression: 'none'
|
|
pattern: 'frontend/dist/toolbar.js'
|
|
# we only care if the toolbar will increase a lot
|
|
minimum-change-threshold: 1000
|
|
|
|
- name: Check toolbar for CSP eval violations
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
run: pnpm --filter=@posthog/frontend check-toolbar-csp-eval
|
|
|
|
frontend-typescript-checks:
|
|
name: Frontend typechecking
|
|
needs: [changes]
|
|
runs-on: depot-ubuntu-24.04-8
|
|
steps:
|
|
- name: Skip frontend checks
|
|
if: ${{ needs.changes.outputs.frontend == 'false' }}
|
|
run: |
|
|
echo "Skipping frontend checks - no frontend changes detected"
|
|
exit 0
|
|
|
|
- uses: actions/checkout@v4
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
|
|
- name: Install pnpm
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4
|
|
|
|
- name: Set up Node.js
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 22.17.1
|
|
cache: 'pnpm'
|
|
|
|
- name: Get pnpm cache directory path
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
id: pnpm-cache-dir
|
|
run: echo "PNPM_STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
|
|
|
- uses: actions/cache@v4
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
id: pnpm-cache
|
|
with:
|
|
path: ${{ steps.pnpm-cache-dir.outputs.PNPM_STORE_PATH }}
|
|
key: ${{ runner.os }}-pnpm-frontend-${{ hashFiles('pnpm-lock.yaml') }}
|
|
restore-keys: ${{ runner.os }}-pnpm-frontend-
|
|
|
|
- name: Install package.json dependencies with pnpm
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
run: |
|
|
pnpm --filter=@posthog/playwright... install --frozen-lockfile
|
|
bin/turbo --filter=@posthog/frontend prepare
|
|
|
|
- name: Cache .typegen
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: .typegen
|
|
key: ${{ runner.os }}-typegen-${{ hashFiles('pnpm-lock.yaml') }}
|
|
restore-keys: ${{ runner.os }}-typegen-
|
|
|
|
- name: Build products
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
run: pnpm --filter=@posthog/frontend build:products
|
|
|
|
- name: Kea typegen
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
run: pnpm --filter=@posthog/frontend typegen:write
|
|
|
|
- name: Run typescript with strict
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
run: pnpm --filter=@posthog/frontend typescript:check
|
|
env:
|
|
NODE_OPTIONS: --max-old-space-size=16384
|
|
|
|
- name: Check if "schema.json" is up to date
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
run: pnpm --filter=@posthog/frontend schema:build:json && git diff --exit-code
|
|
|
|
- name: Check if mobile replay "schema.json" is up to date
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
run: pnpm --filter=@posthog/ee mobile-replay:schema:build:json && git diff --exit-code
|
|
|
|
jest:
|
|
runs-on: depot-ubuntu-24.04
|
|
needs: changes
|
|
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, 3]
|
|
|
|
steps:
|
|
# we need at least one thing to run to make sure we include everything for required jobs
|
|
- name: Skip frontend checks
|
|
if: ${{ needs.changes.outputs.frontend == 'false' }}
|
|
run: |
|
|
echo "Skipping frontend checks - no frontend changes detected"
|
|
exit 0
|
|
|
|
- uses: actions/checkout@v4
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
|
|
- name: Remove ee
|
|
if: needs.changes.outputs.frontend == 'true' && matrix.segment == 'FOSS'
|
|
run: rm -rf ee
|
|
|
|
- name: Install pnpm
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4
|
|
|
|
- name: Set up Node.js
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 22.17.1
|
|
cache: pnpm
|
|
|
|
- name: Install package.json dependencies with pnpm
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
run: pnpm --filter=@posthog/frontend... install --frozen-lockfile
|
|
|
|
- name: Test with Jest
|
|
run: bin/turbo run test --filter=@posthog/frontend
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
env:
|
|
NODE_OPTIONS: --max-old-space-size=16384
|
|
SHARD_INDEX: ${{ matrix.chunk }}
|
|
SHARD_COUNT: 3
|
|
|
|
calculate-running-time:
|
|
name: Calculate running time
|
|
needs: [jest, frontend-typescript-checks, frontend-format, frontend-toolbar-checks, changes]
|
|
runs-on: depot-ubuntu-24.04
|
|
if: # Run on pull requests to PostHog/posthog + on PostHog/posthog outside of PRs - but never on forks
|
|
needs.changes.outputs.frontend == '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: Calculate running time
|
|
run: |
|
|
echo "${{ secrets.GITHUB_TOKEN }}" | gh auth login --with-token
|
|
run_id=${GITHUB_RUN_ID}
|
|
repo=${GITHUB_REPOSITORY}
|
|
run_info=$(gh api repos/${repo}/actions/runs/${run_id})
|
|
echo run_info: ${run_info}
|
|
# name is the name of the workflow file
|
|
# run_started_at is the start time of the workflow
|
|
# we want to get the number of seconds between the start time and now
|
|
name=$(echo ${run_info} | jq -r '.name')
|
|
run_url=$(echo ${run_info} | jq -r '.url')
|
|
run_started_at=$(echo ${run_info} | jq -r '.run_started_at')
|
|
run_attempt=$(echo ${run_info} | jq -r '.run_attempt')
|
|
start_seconds=$(date -d "${run_started_at}" +%s)
|
|
now_seconds=$(date +%s)
|
|
duration=$((now_seconds-start_seconds))
|
|
echo running_time_duration_seconds=${duration} >> $GITHUB_ENV
|
|
echo running_time_run_url=${run_url} >> $GITHUB_ENV
|
|
echo running_time_run_attempt=${run_attempt} >> $GITHUB_ENV
|
|
echo running_time_run_id=${run_id} >> $GITHUB_ENV
|
|
echo running_time_run_started_at=${run_started_at} >> $GITHUB_ENV
|
|
|
|
- name: Capture running time to PostHog
|
|
if: needs.changes.outputs.frontend == 'true'
|
|
uses: PostHog/posthog-github-action@v0.1
|
|
with:
|
|
posthog-token: ${{secrets.POSTHOG_API_TOKEN}}
|
|
event: 'posthog-ci-running-time'
|
|
properties: '{"runner": "depot", "duration_seconds": ${{ env.running_time_duration_seconds }}, "run_url": "${{ env.running_time_run_url }}", "run_attempt": "${{ env.running_time_run_attempt }}", "run_id": "${{ env.running_time_run_id }}", "run_started_at": "${{ env.running_time_run_started_at }}"}'
|
|
|
|
frontend_tests:
|
|
needs: [jest, frontend-format, frontend-toolbar-checks, frontend-typescript-checks]
|
|
name: Frontend Tests Pass
|
|
runs-on: ubuntu-latest
|
|
if: always()
|
|
steps:
|
|
- run: exit 0
|
|
- name: Check outcomes
|
|
run: |
|
|
if [[ "${{ needs.jest.result }}" != "success" ]]; then
|
|
echo "Frontend jest tests failed."
|
|
exit 1
|
|
fi
|
|
echo "Frontend jest tests passed."
|
|
if [[ "${{ needs.frontend-format.result }}" != "success" ]]; then
|
|
echo "Frontend linting failed."
|
|
exit 1
|
|
fi
|
|
echo "Frontend linting passed."
|
|
if [[ "${{ needs.frontend-toolbar-checks.result }}" != "success" ]]; then
|
|
echo "Frontend toolbar checks failed."
|
|
exit 1
|
|
fi
|
|
echo "Frontend toolbar checks passed."
|
|
if [[ "${{ needs.frontend-typescript-checks.result }}" != "success" ]]; then
|
|
echo "Frontend TypeScript checks failed."
|
|
exit 1
|
|
fi
|
|
echo "Frontend TypeScript checks passed."
|