Skip to content

🤖 refactor: simplify CI and tests folder structure #5771

🤖 refactor: simplify CI and tests folder structure

🤖 refactor: simplify CI and tests folder structure #5771

Workflow file for this run

name: CI
on:
pull_request:
branches: ["**"]
merge_group:
workflow_dispatch:
inputs:
test_filter:
description: 'Optional test filter (e.g., "workspace", "tests/file.test.ts", or "-t pattern")'
required: false
type: string
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
# Detect what files changed to enable selective test execution
changes:
name: Detect Changes
runs-on: ubuntu-latest
outputs:
# True if ONLY docs changed (nothing else)
docs-only: ${{ steps.filter.outputs.docs == 'true' && steps.filter.outputs.src == 'false' && steps.filter.outputs.config == 'false' }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: filter
with:
filters: |
docs:
- 'docs/**'
- '*.md'
- 'LICENSE'
- '.vscode/**'
src:
- 'src/**'
- 'tests/**'
config:
- '.github/**'
- 'jest.config.cjs'
- 'babel.config.cjs'
- 'package.json'
- 'bun.lockb'
- 'tsconfig*.json'
- 'vite*.ts'
- 'Makefile'
static-check:
name: Static Checks
runs-on: ${{ github.repository_owner == 'coder' && 'depot-ubuntu-22.04-16' || 'ubuntu-latest' }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: ./.github/actions/setup-mux
- run: ./scripts/generate-version.sh
- uses: actions/cache@v4
with:
path: ~/.local/bin/shfmt
key: ${{ runner.os }}-shfmt-latest
- name: Install shfmt
run: |
if [[ ! -f "$HOME/.local/bin/shfmt" ]] || ! "$HOME/.local/bin/shfmt" --version >/dev/null 2>&1; then
curl -sS https://webinstall.dev/shfmt | bash
fi
echo "$HOME/.local/bin" >> $GITHUB_PATH
- uses: cachix/install-nix-action@v27
with:
extra_nix_config: |
experimental-features = nix-command flakes
- run: curl -LsSf https://astral.sh/uv/install.sh | sh
- run: echo "$HOME/.local/bin" >> $GITHUB_PATH
- run: make -j3 static-check
test:
name: Unit Tests
needs: [changes]
if: ${{ needs.changes.outputs.docs-only != 'true' }}
runs-on: ${{ github.repository_owner == 'coder' && 'depot-ubuntu-22.04-16' || 'ubuntu-latest' }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: ./.github/actions/setup-mux
- run: make build-main
- run: bun test --coverage --coverage-reporter=lcov ${{ github.event.inputs.test_filter || 'src' }}
- uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./coverage/lcov.info
flags: unit-tests
fail_ci_if_error: false
integration-test:
name: Integration Tests
needs: [changes]
if: ${{ needs.changes.outputs.docs-only != 'true' }}
timeout-minutes: 10
runs-on: ${{ github.repository_owner == 'coder' && 'depot-ubuntu-22.04-16' || 'ubuntu-latest' }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: ./.github/actions/setup-mux
- run: make build-main
- name: Run integration tests
run: TEST_INTEGRATION=1 bun x jest --coverage --maxWorkers=100% --silent ${{ github.event.inputs.test_filter || 'tests' }}
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
- uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./coverage/lcov.info
flags: integration-tests
fail_ci_if_error: false
storybook-test:
name: Storybook Tests
needs: [changes]
if: ${{ needs.changes.outputs.docs-only != 'true' && github.event.inputs.test_filter == '' }}
runs-on: ${{ github.repository_owner == 'coder' && 'depot-ubuntu-22.04-16' || 'ubuntu-latest' }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: ./.github/actions/setup-mux
- uses: ./.github/actions/setup-playwright
- run: make storybook-build
- run: |
bun x http-server storybook-static -p 6006 &
sleep 5
- run: make test-storybook
e2e-test:
name: E2E Tests (${{ matrix.os }})
needs: [changes]
if: ${{ needs.changes.outputs.docs-only != 'true' && github.event.inputs.test_filter == '' }}
strategy:
fail-fast: false
matrix:
include:
- os: linux
runner: ${{ github.repository_owner == 'coder' && 'depot-ubuntu-22.04-16' || 'ubuntu-latest' }}
- os: macos
runner: ${{ github.repository_owner == 'coder' && 'depot-macos-latest' || 'macos-latest' }}
runs-on: ${{ matrix.runner }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: ./.github/actions/setup-mux
- name: Install xvfb (Linux)
if: matrix.os == 'linux'
run: |
sudo apt-get update
sudo apt-get install -y xvfb
- uses: ./.github/actions/setup-playwright
- name: Run e2e tests (Linux)
if: matrix.os == 'linux'
run: xvfb-run -a make test-e2e
env:
ELECTRON_DISABLE_SANDBOX: 1
- name: Run e2e tests (macOS)
if: matrix.os == 'macos'
run: make test-e2e PLAYWRIGHT_ARGS="tests/e2e/scenarios/windowLifecycle.spec.ts"
mux-server-smoke-test:
name: Mux Server Smoke Test
needs: [changes]
if: ${{ needs.changes.outputs.docs-only != 'true' }}
runs-on: ${{ github.repository_owner == 'coder' && 'depot-ubuntu-22.04-16' || 'ubuntu-latest' }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: ./.github/actions/setup-mux
- run: make build
- run: npm pack
- name: Run smoke test
env:
SERVER_PORT: 3001
SERVER_HOST: localhost
STARTUP_TIMEOUT: 30
run: |
TARBALL=$(ls mux-*.tgz | head -1)
PACKAGE_TARBALL="$TARBALL" ./scripts/smoke-test.sh
- uses: actions/upload-artifact@v4
if: failure()
with:
name: mux-server-smoke-test-logs
path: /tmp/tmp.*/server.log
if-no-files-found: warn
retention-days: 7
docker-smoke-test:
name: Docker Smoke Test
if: github.event_name == 'merge_group'
runs-on: ${{ github.repository_owner == 'coder' && 'depot-ubuntu-22.04-16' || 'ubuntu-latest' }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: docker/setup-buildx-action@v3
- uses: docker/build-push-action@v6
with:
context: .
load: true
tags: mux-server:test
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Start container
run: |
docker run -d --name mux-test -p 3000:3000 mux-server:test
for i in {1..30}; do
if curl -sf http://localhost:3000/health; then
echo "Server is ready"
break
fi
echo "Waiting for server... ($i/30)"
sleep 1
done
- name: Health check
run: |
response=$(curl -sf http://localhost:3000/health)
echo "Health response: $response"
echo "$response" | grep -q '"status":"ok"'
- name: Version check
run: |
response=$(curl -sf http://localhost:3000/version)
echo "Version response: $response"
echo "$response" | grep -q '"mode":"server"'
echo "$response" | grep -q '"git_describe"'
- if: failure()
run: docker logs mux-test
- if: always()
run: docker rm -f mux-test || true
check-codex-comments:
name: Check Codex Comments
if: github.event_name == 'pull_request'
runs-on: ${{ github.repository_owner == 'coder' && 'depot-ubuntu-22.04-16' || 'ubuntu-latest' }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./scripts/check_codex_comments.sh ${{ github.event.pull_request.number }}
# This job is the single required check - it passes if all other jobs pass or are skipped
ci-passed:
name: CI Passed
if: always()
needs:
- changes
- static-check
- test
- integration-test
- storybook-test
- e2e-test
- mux-server-smoke-test
- docker-smoke-test
- check-codex-comments
runs-on: ubuntu-latest
steps:
- name: Check all job results
run: |
# Get all job results
results="${{ join(needs.*.result, ' ') }}"
echo "Job results: $results"
# Fail if any job failed (skipped is OK)
for result in $results; do
if [[ "$result" == "failure" ]] || [[ "$result" == "cancelled" ]]; then
echo "❌ CI failed: found job with result '$result'"
exit 1
fi
done
echo "✅ All CI checks passed (or were skipped)"