From 423d7d7b3411d8d8ac2b135db33dea362ad85a44 Mon Sep 17 00:00:00 2001 From: anandgupta42 Date: Wed, 18 Mar 2026 01:10:28 -0700 Subject: [PATCH 1/2] fix: Docker E2E tests skip in CI unless explicitly opted in GitHub Actions runners have Docker pre-installed, so isDockerAvailable() returns true. But the TypeScript CI job has no test databases running, causing 3 tests to hang for 60-90s then fail. Fix: require DRIVER_E2E_DOCKER=1 env var to run Docker-based tests. The driver-e2e CI job sets TEST_*_HOST vars (CI services), which still work. Local dev can set DRIVER_E2E_DOCKER=1 to test with Docker. This eliminates 3 of the 14 CI failures on main. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../opencode/test/altimate/drivers-docker-e2e.test.ts | 8 +++++++- packages/opencode/test/altimate/drivers-e2e.test.ts | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/opencode/test/altimate/drivers-docker-e2e.test.ts b/packages/opencode/test/altimate/drivers-docker-e2e.test.ts index 8fe097b0b0..13b0b6eb1e 100644 --- a/packages/opencode/test/altimate/drivers-docker-e2e.test.ts +++ b/packages/opencode/test/altimate/drivers-docker-e2e.test.ts @@ -9,8 +9,14 @@ import { createConnection } from "net" const HAS_CI_SERVICES = !!(process.env.TEST_MYSQL_HOST || process.env.TEST_MSSQL_HOST || process.env.TEST_REDSHIFT_HOST) +// Only run Docker tests when explicitly opted in via DRIVER_E2E_DOCKER=1 +// or when CI services are configured. This prevents the TypeScript CI job +// (which has Docker but no test databases) from trying to start containers. +const DOCKER_OPT_IN = process.env.DRIVER_E2E_DOCKER === "1" + function isDockerAvailable(): boolean { - if (HAS_CI_SERVICES) return true // CI services replace Docker + if (HAS_CI_SERVICES) return true + if (!DOCKER_OPT_IN) return false // Skip unless explicitly opted in try { execSync("docker info", { stdio: "ignore", timeout: 3000 }) return true diff --git a/packages/opencode/test/altimate/drivers-e2e.test.ts b/packages/opencode/test/altimate/drivers-e2e.test.ts index 031063021c..e59dcf3807 100644 --- a/packages/opencode/test/altimate/drivers-e2e.test.ts +++ b/packages/opencode/test/altimate/drivers-e2e.test.ts @@ -34,6 +34,7 @@ function isBetterSqlite3Available(): boolean { function isDockerAvailable(): boolean { if (process.env.TEST_PG_HOST) return true // CI services replace Docker + if (!process.env.DRIVER_E2E_DOCKER) return false // Skip unless opted in try { execSync("docker info", { stdio: "ignore", timeout: 3000 }) return true From a0e7ca9703fa1dfe04113d66bc79dc81fa6b2209 Mon Sep 17 00:00:00 2001 From: anandgupta42 Date: Wed, 18 Mar 2026 01:20:56 -0700 Subject: [PATCH 2/2] =?UTF-8?q?ci:=20parallel=20per-target=20builds=20?= =?UTF-8?q?=E2=80=94=2012=20jobs=20instead=20of=203=20sequential?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before: 3 build jobs (linux/darwin/win32), each building 3-6 targets sequentially. Darwin took ~20min (3 × 7min per binary). After: 12 build jobs, one per target, all running in parallel. Each builds ONE binary in ~5min. Total build time = ~5min (wall clock). Changes: - build.ts: add --target-index=N flag to build single target by index - release.yml: matrix of 12 individual targets instead of 3 OS groups - Build runs parallel with test (no needs: test) - Lower artifact compression (level 1 — binaries don't compress much) - Tighter timeouts (15min per build instead of 60min) Expected: release time from ~36min to ~10-15min. Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/release.yml | 35 ++++++++++++++++++++++--------- packages/opencode/script/build.ts | 7 ++++++- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7fb70af6e2..d7c359fe0e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -48,16 +48,30 @@ jobs: working-directory: packages/opencode build: - name: Build (${{ matrix.os }}) - needs: test + name: Build (${{ matrix.name }}) + # Runs in PARALLEL with test — publish waits for both runs-on: ubuntu-latest - timeout-minutes: 60 + timeout-minutes: 15 permissions: contents: read strategy: fail-fast: false matrix: - os: [linux, darwin, win32] + include: + # Each target builds ONE binary in parallel (~5 min each) + # Index matches allTargets array in build.ts + - { index: 0, name: "linux-arm64" } + - { index: 1, name: "linux-x64" } + - { index: 2, name: "linux-x64-baseline" } + - { index: 3, name: "linux-arm64-musl" } + - { index: 4, name: "linux-x64-musl" } + - { index: 5, name: "linux-x64-baseline-musl" } + - { index: 6, name: "darwin-arm64" } + - { index: 7, name: "darwin-x64" } + - { index: 8, name: "darwin-x64-baseline" } + - { index: 9, name: "win32-arm64" } + - { index: 10, name: "win32-x64" } + - { index: 11, name: "win32-x64-baseline" } steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 @@ -76,8 +90,8 @@ jobs: - name: Install dependencies run: bun install - - name: Build ${{ matrix.os }} targets - run: bun run packages/opencode/script/build.ts --targets=${{ matrix.os }} + - name: Build ${{ matrix.name }} + run: bun run packages/opencode/script/build.ts --target-index=${{ matrix.index }} env: OPENCODE_VERSION: ${{ github.ref_name }} OPENCODE_CHANNEL: latest @@ -85,11 +99,12 @@ jobs: GH_REPO: ${{ env.GH_REPO }} MODELS_DEV_API_JSON: test/tool/fixtures/models-api.json - - name: Upload build artifacts + - name: Upload build artifact uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: - name: dist-${{ matrix.os }} + name: dist-${{ matrix.name }} path: packages/opencode/dist/ + compression-level: 1 publish-npm: name: Publish to npm @@ -124,7 +139,7 @@ jobs: - name: Download all build artifacts uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 with: - pattern: dist-* + pattern: "dist-*" path: packages/opencode/dist/ merge-multiple: true @@ -228,7 +243,7 @@ jobs: - name: Download all build artifacts uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 with: - pattern: dist-* + pattern: "dist-*" path: packages/opencode/dist/ merge-multiple: true diff --git a/packages/opencode/script/build.ts b/packages/opencode/script/build.ts index e103eec6d4..802f475104 100755 --- a/packages/opencode/script/build.ts +++ b/packages/opencode/script/build.ts @@ -142,7 +142,12 @@ if (targetsFlag) { } } -const targets = singleFlag +// --target-index=N builds a single target by index (for parallel CI matrix) +const targetIndexFlag = process.argv.find(a => a.startsWith('--target-index='))?.split('=')[1] + +const targets = targetIndexFlag !== undefined + ? [allTargets[parseInt(targetIndexFlag, 10)]].filter(Boolean) + : singleFlag ? allTargets.filter((item) => { if (item.os !== process.platform || item.arch !== process.arch) { return false