From d44c1f9d828aada1f34deac5ee69e669d0247c8c Mon Sep 17 00:00:00 2001 From: Danila Poyarkov Date: Tue, 18 Aug 2026 22:52:18 +0300 Subject: [PATCH] ci: parallelize quality and trim shard builds (#558) * ci: parallelize quality and trim shard builds - Split source, package, repository, and Storybook checks into independent jobs - Build only Core before quick unit shards instead of all public packages - Keep full package and dist validation in the dedicated package-quality job - Disable duplicate Storybook component metadata extraction * fix(ci): build declarations before source checks * fix(ci): apply review security and docgen settings - Pin checkout and disable credential persistence - Declare read-only workflow permissions - Explicitly disable Storybook Vue docgen * ci: clarify check and step names * fix(ci): cap workflow job runtimes - Limit the WebView dependency install to three minutes - Limit native contracts to eight minutes - Limit all other CI jobs to ten minutes * ci: retry native contracts on a fresh runner * ci: move native contracts to Ubuntu 24 - Leave the deprecated Ubuntu 22 hosted image - Retry WebKit dependency provisioning on the current runner image * ci: prebuild native contract dependencies * ci: pin native contracts image digest * fix(ci): authenticate native image pulls * fix(ci): include Bun archive tooling * ci: pin updated native contracts image * fix(tools): register CI image tooling --- .github/workflows/ci.yml | 132 +++++++++++++++---- .github/workflows/native-contracts-image.yml | 44 +++++++ .storybook/main.ts | 7 +- package.json | 1 + tools/ci-images/native-contracts/Dockerfile | 16 +++ tools/ci-images/package.json | 5 + 6 files changed, 177 insertions(+), 28 deletions(-) create mode 100644 .github/workflows/native-contracts-image.yml create mode 100644 tools/ci-images/native-contracts/Dockerfile create mode 100644 tools/ci-images/package.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5f12501f1..d2c941ce1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,33 +8,123 @@ on: - 'openspec/**' - '*.md' +permissions: + contents: read + packages: read + concurrency: group: ci-${{ github.ref }} cancel-in-progress: true jobs: - quality: + source-quality: + name: Code quality + timeout-minutes: 10 runs-on: ubuntu-latest steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 + with: + persist-credentials: false - uses: ./.github/actions/setup-bun - with: - lfs: 'true' - - name: Format check + - name: Generate package declarations + run: bun run build:packages + + - name: Verify formatting run: bun run format:check - - name: Lint, typecheck, architecture, package, and tooling checks - run: bun run check + - name: Lint TypeScript and Vue + run: bun run lint - - name: Build Storybook + - name: Typecheck application and SDKs + run: bun run typecheck + + - name: Enforce architecture and type-shape boundaries + run: bun run check:arch && bun run test:type-shapes + + package-quality: + name: Package integrity + timeout-minutes: 10 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 + with: + persist-credentials: false + + - uses: ./.github/actions/setup-bun + + - name: Build publishable packages + run: bun run build:packages + + - name: Validate package exports + run: bun run check:packages + + - name: Detect unused dependencies and files + run: bun run check:deps + + - name: Validate workspace dependency policy + run: bun run check:monorepo + + repository-quality: + name: Repository hygiene + timeout-minutes: 10 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 + with: + persist-credentials: false + + - uses: ./.github/actions/setup-bun + + - name: Validate translations + run: bun run check:i18n + + - name: Validate documentation links and structure + run: bun run check:docs + + - name: Audit critical dependency vulnerabilities + run: bun run check:audit + + - name: Scan for committed secrets + run: bun run check:secrets + + - name: Test repository tooling + run: bun run test:tools + + - name: Detect duplicated product code + run: bun run test:dupes + + storybook: + name: Component workshop + timeout-minutes: 10 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 + with: + persist-credentials: false + + - uses: ./.github/actions/setup-bun + + - name: Build component dependencies + run: bun run build:packages + + - name: Build static Storybook run: bun run build-storybook native-test-contracts: - runs-on: ubuntu-22.04 + name: Native app contracts + timeout-minutes: 8 + runs-on: ubuntu-24.04 + container: + image: ghcr.io/open-pencil/native-contracts-ci@sha256:64e6b1b50a988c1cefe2b69ac9d58076fd743b18391fa2dbd1d153eba2be9521 + credentials: + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 + with: + persist-credentials: false - uses: dtolnay/rust-toolchain@stable @@ -43,37 +133,35 @@ jobs: workspaces: desktop -> target key: native-test - - name: Install Tauri dependencies - run: | - sudo apt-get update - sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev - - uses: ./.github/actions/setup-bun - - name: Typecheck native tests + - name: Typecheck native interaction tests run: bun run check:native-test - - name: Check test-only Tauri feature + - name: Compile native-test Tauri feature run: cargo check --manifest-path desktop/Cargo.toml --features native-test unit-tests: + timeout-minutes: 10 runs-on: ubuntu-latest strategy: fail-fast: true matrix: group: [app, dom, editor, fig, render, scene, vue] - name: Unit tests (${{ matrix.group }}) + name: Engine tests — ${{ matrix.group }} steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 + with: + persist-credentials: false - uses: ./.github/actions/setup-bun with: lfs: 'true' - - name: Build packages - run: bun run build:packages + - name: Build shared Core test dependency + run: bun --filter @open-pencil/core build - - name: Run quick unit test shard + - name: Run ${{ matrix.group }} engine tests shell: bash run: | mapfile -t test_files < <(bun tools/unit-tests/src/list.ts "${{ matrix.group }}") diff --git a/.github/workflows/native-contracts-image.yml b/.github/workflows/native-contracts-image.yml new file mode 100644 index 000000000..fc7d75289 --- /dev/null +++ b/.github/workflows/native-contracts-image.yml @@ -0,0 +1,44 @@ +name: Build native contracts CI image + +on: + workflow_dispatch: + push: + branches: [master] + paths: + - 'tools/ci-images/native-contracts/Dockerfile' + - '.github/workflows/native-contracts-image.yml' + +permissions: + contents: read + packages: write + +concurrency: + group: native-contracts-image + cancel-in-progress: true + +jobs: + publish: + name: Publish native contracts image + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 + with: + persist-credentials: false + + - uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 + + - uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 + with: + context: tools/ci-images/native-contracts + push: true + tags: | + ghcr.io/open-pencil/native-contracts-ci:ubuntu-24.04 + ghcr.io/open-pencil/native-contracts-ci:${{ github.sha }} + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/.storybook/main.ts b/.storybook/main.ts index c5ab612a2..d3bbd3d3a 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -10,12 +10,7 @@ const config: StorybookConfig = { addons: ['@storybook/addon-docs', '@storybook/addon-a11y', '@storybook/addon-themes'], framework: { name: '@storybook/vue3-vite', - options: { - docgen: { - plugin: 'vue-component-meta', - tsconfig: 'tsconfig.json' - } - } + options: { docgen: false } }, viteFinal(config) { const excludedPluginPrefixes = [ diff --git a/package.json b/package.json index 0756b182e..09e51d16b 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "test:update": "playwright test --project=openpencil --update-snapshots", "test:figma": "playwright test --project=figma", "figma:debug": "open -a Figma --args --remote-debugging-port=9222", + "typecheck": "tsgo --noEmit && bun run check:vue", "test:unit": "bun test ./tests/engine", "test:unit:quick": "bash -lc 'mapfile -t test_files < <(bun tools/unit-tests/src/list.ts all); bun test \"${test_files[@]}\"'", "test:unit:heavy": "bash -lc 'mapfile -t test_files < <(bun tools/unit-tests/src/list.ts all --heavy-only); bun test --timeout 180000 \"${test_files[@]}\"'", diff --git a/tools/ci-images/native-contracts/Dockerfile b/tools/ci-images/native-contracts/Dockerfile new file mode 100644 index 000000000..3751f7919 --- /dev/null +++ b/tools/ci-images/native-contracts/Dockerfile @@ -0,0 +1,16 @@ +FROM ubuntu@sha256:561618e2c15bf2397621dd04f96926663a3b5616c189cf7e38db7e82f5c538ea + +ARG DEBIAN_FRONTEND=noninteractive + +RUN apt-get update \ + && apt-get install --yes --no-install-recommends \ + ca-certificates \ + curl \ + git \ + libappindicator3-dev \ + librsvg2-dev \ + libwebkit2gtk-4.1-dev \ + pkg-config \ + unzip \ + xz-utils \ + && rm -rf /var/lib/apt/lists/* diff --git a/tools/ci-images/package.json b/tools/ci-images/package.json new file mode 100644 index 000000000..389ada96b --- /dev/null +++ b/tools/ci-images/package.json @@ -0,0 +1,5 @@ +{ + "name": "@open-pencil/ci-images", + "private": true, + "type": "module" +}