Skip to content

fix: eliminate stale file race condition and fix error misclassification #1465

fix: eliminate stale file race condition and fix error misclassification

fix: eliminate stale file race condition and fix error misclassification #1465

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
jobs:
# ---------------------------------------------------------------------------
# Detect which areas of the codebase changed to skip unaffected jobs.
# On push to main, all jobs run unconditionally (safety net).
# ---------------------------------------------------------------------------
changes:
name: Detect Changes
runs-on: ubuntu-latest
timeout-minutes: 2
outputs:
typescript: ${{ steps.filter.outputs.typescript }}
drivers: ${{ steps.filter.outputs.drivers }}
dbt-tools: ${{ steps.filter.outputs.dbt-tools }}
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3
id: filter
with:
filters: |
typescript:
- 'packages/opencode/**'
- 'packages/drivers/**'
- 'packages/plugin/**'
- 'packages/sdk/**'
- 'packages/util/**'
- 'packages/script/**'
- 'bun.lock'
- 'package.json'
- 'tsconfig.json'
drivers:
- 'packages/drivers/src/**'
- 'packages/opencode/src/altimate/native/connections/**'
- 'packages/opencode/test/altimate/drivers-e2e.test.ts'
- 'packages/opencode/test/altimate/drivers-docker-e2e.test.ts'
- 'packages/opencode/test/altimate/drivers-mongodb-e2e.test.ts'
- 'packages/opencode/test/altimate/drivers-clickhouse-e2e.test.ts'
- 'packages/opencode/test/altimate/connections.test.ts'
dbt-tools:
- 'packages/dbt-tools/**'
# ---------------------------------------------------------------------------
# Main TypeScript tests — excludes driver E2E tests (separate job) and
# cloud credential tests (local-only).
# ---------------------------------------------------------------------------
typescript:
name: TypeScript
needs: changes
if: needs.changes.outputs.typescript == 'true' || github.event_name == 'push'
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: oven-sh/setup-bun@ecf28ddc73e819eb6fa29df6b34ef8921c743461 # v2
with:
bun-version: "1.3.10"
- name: Cache Bun dependencies
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
with:
path: ~/.bun/install/cache
key: bun-${{ runner.os }}-${{ hashFiles('bun.lock') }}
restore-keys: |
bun-${{ runner.os }}-
- name: Configure git for tests
run: |
git config --global user.name "CI"
git config --global user.email "[email protected]"
- name: Install dependencies
run: bun install
- name: Run tests
working-directory: packages/opencode
# Cloud E2E tests (Snowflake, BigQuery, Databricks) auto-skip when
# ALTIMATE_CODE_CONN_* env vars are not set. Docker E2E tests auto-skip
# when Docker is not available. No exclusion needed — skipIf handles it.
# --timeout 30000: matches package.json "test" script; prevents 5s default
# from cutting off tests that run bun install or bootstrap git instances.
#
# Bun 1.3.x has a known segfault during process cleanup after all tests
# pass (exit code 143/SIGTERM or 134/SIGABRT). We capture test output and
# check for real failures vs Bun crashes to avoid false CI failures.
shell: bash
run: |
# Redirect bun output to file, then cat it for CI visibility.
# This avoids tee/pipe issues where SIGTERM kills tee before flush.
bun test --timeout 30000 > /tmp/test-output.txt 2>&1 || true
cat /tmp/test-output.txt
# Extract pass/fail counts from Bun test summary (e.g., " 5362 pass")
PASS_COUNT=$(awk '/^ *[0-9]+ pass$/{print $1}' /tmp/test-output.txt || true)
FAIL_COUNT=$(awk '/^ *[0-9]+ fail$/{print $1}' /tmp/test-output.txt || true)
echo ""
echo "--- Test Summary ---"
echo "pass=${PASS_COUNT:-none} fail=${FAIL_COUNT:-none}"
# Real test failures — always fail CI
if [ -n "$FAIL_COUNT" ] && [ "$FAIL_COUNT" != "0" ]; then
echo "::error::$FAIL_COUNT test(s) failed"
exit 1
fi
# Tests passed (we have a pass count and zero/no failures)
if [ -n "$PASS_COUNT" ] && [ "$PASS_COUNT" -gt 0 ] 2>/dev/null; then
exit 0
fi
# No test summary at all — Bun crashed before running tests
echo "::error::No test results found in output — Bun may have crashed before running tests"
exit 1
# ---------------------------------------------------------------------------
# Driver E2E tests — only when driver code changes.
# Uses GitHub Actions services (no Docker-in-Docker).
# Cloud tests (Snowflake, BigQuery, Databricks) are NOT run here —
# they require real credentials and are run locally only.
# ---------------------------------------------------------------------------
driver-e2e:
name: Driver E2E
needs: changes
if: needs.changes.outputs.drivers == 'true'
runs-on: ubuntu-latest
timeout-minutes: 10
services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_PASSWORD: testpass123
ports:
- 15432:5432
options: >-
--health-cmd pg_isready
--health-interval 5s
--health-timeout 5s
--health-retries 10
mysql:
image: mysql:8.0
env:
MYSQL_ROOT_PASSWORD: testpass123
MYSQL_DATABASE: testdb
ports:
- 13306:3306
options: >-
--health-cmd "mysqladmin ping -h 127.0.0.1"
--health-interval 5s
--health-timeout 5s
--health-retries 20
mssql:
image: mcr.microsoft.com/azure-sql-edge:latest
env:
ACCEPT_EULA: Y
MSSQL_SA_PASSWORD: TestPass123!
ports:
- 11433:1433
options: >-
--health-cmd "/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P 'TestPass123!' -Q 'SELECT 1' || exit 1"
--health-interval 10s
--health-timeout 10s
--health-retries 20
redshift:
image: postgres:16-alpine
env:
POSTGRES_PASSWORD: testpass123
POSTGRES_DB: dev
ports:
- 15439:5432
options: >-
--health-cmd pg_isready
--health-interval 5s
--health-timeout 5s
--health-retries 10
mongodb:
image: mongo:7.0
ports:
- 27017:27017
options: >-
--health-cmd "mongosh --eval 'db.runCommand({ping:1})' --quiet"
--health-interval 5s
--health-timeout 5s
--health-retries 10
clickhouse:
image: clickhouse/clickhouse-server:latest
env:
CLICKHOUSE_DB: testdb
CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT: 1
ports:
- 18123:8123
options: >-
--health-cmd "wget --no-verbose --tries=1 --spider http://localhost:8123/ping || exit 1"
--health-interval 5s
--health-timeout 5s
--health-retries 15
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: oven-sh/setup-bun@ecf28ddc73e819eb6fa29df6b34ef8921c743461 # v2
with:
bun-version: "1.3.10"
- name: Cache Bun dependencies
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
with:
path: ~/.bun/install/cache
key: bun-${{ runner.os }}-${{ hashFiles('bun.lock') }}
restore-keys: |
bun-${{ runner.os }}-
- name: Install dependencies
run: bun install
- name: Run local driver E2E (DuckDB, SQLite, PostgreSQL)
run: bun test test/altimate/drivers-e2e.test.ts
working-directory: packages/opencode
env:
TEST_PG_HOST: 127.0.0.1
TEST_PG_PORT: "15432"
TEST_PG_PASSWORD: testpass123
- name: Run Docker driver E2E (MySQL, SQL Server, Redshift)
run: bun test test/altimate/drivers-docker-e2e.test.ts
working-directory: packages/opencode
env:
TEST_MYSQL_HOST: 127.0.0.1
TEST_MYSQL_PORT: "13306"
TEST_MYSQL_PASSWORD: testpass123
TEST_MSSQL_HOST: 127.0.0.1
TEST_MSSQL_PORT: "11433"
TEST_MSSQL_PASSWORD: "TestPass123!"
TEST_REDSHIFT_HOST: 127.0.0.1
TEST_REDSHIFT_PORT: "15439"
TEST_REDSHIFT_PASSWORD: testpass123
- name: Run MongoDB driver E2E
run: bun test test/altimate/drivers-mongodb-e2e.test.ts
working-directory: packages/opencode
env:
TEST_MONGODB_HOST: 127.0.0.1
TEST_MONGODB_PORT: "27017"
- name: Run ClickHouse driver E2E
run: bun test test/altimate/drivers-clickhouse-e2e.test.ts
working-directory: packages/opencode
env:
TEST_CLICKHOUSE_HOST: 127.0.0.1
TEST_CLICKHOUSE_PORT: "18123"
# Cloud tests NOT included — they require real credentials
# Run locally with:
# ALTIMATE_CODE_CONN_SNOWFLAKE_TEST='...' bun test test/altimate/drivers-snowflake-e2e.test.ts
# ALTIMATE_CODE_CONN_BIGQUERY_TEST='...' bun test test/altimate/drivers-bigquery-e2e.test.ts
# ALTIMATE_CODE_CONN_DATABRICKS_TEST='...' bun test test/altimate/drivers-databricks-e2e.test.ts
# ---------------------------------------------------------------------------
# dbt-tools unit tests — fast (< 5s), run on PRs when dbt-tools changes.
# ---------------------------------------------------------------------------
dbt-tools:
name: dbt-tools
needs: changes
if: needs.changes.outputs.dbt-tools == 'true' || github.event_name == 'push'
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: oven-sh/setup-bun@ecf28ddc73e819eb6fa29df6b34ef8921c743461 # v2
with:
bun-version: "1.3.10"
- name: Install dependencies
run: bun install
- name: Run dbt-tools unit tests
run: bun run test
working-directory: packages/dbt-tools
# ---------------------------------------------------------------------------
# dbt-tools E2E — slow (~3 min), only on push to main.
# Tests dbt CLI fallbacks against real dbt versions (1.8, 1.10, 1.11) and
# real Python environments (venv, uv, system).
# ---------------------------------------------------------------------------
dbt-tools-e2e:
name: "dbt-tools E2E"
needs: changes
if: github.event_name == 'push'
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: oven-sh/setup-bun@ecf28ddc73e819eb6fa29df6b34ef8921c743461 # v2
with:
bun-version: "1.3.10"
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
python-version: "3.11"
- name: Install uv
run: curl -LsSf https://astral.sh/uv/install.sh | sh
- name: Install dependencies
run: bun install
- name: Cache dbt venvs
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
with:
path: packages/dbt-tools/test/.dbt-venvs
key: dbt-venvs-${{ runner.os }}-1.8-1.10-1.11
- name: Cache Python env scenarios
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
with:
path: packages/dbt-tools/test/.dbt-resolve-envs
key: dbt-resolve-envs-${{ runner.os }}-v1
- name: Set up dbt versions
run: ./test/e2e/setup-versions.sh 1.8 1.10 1.11
working-directory: packages/dbt-tools
- name: Set up Python env scenarios
run: ./test/e2e/setup-resolve.sh venv uv system
working-directory: packages/dbt-tools
- name: Run dbt-tools E2E tests
run: bun run test:e2e
working-directory: packages/dbt-tools
env:
DBT_E2E_VERSIONS: "1.8,1.10,1.11"
DBT_RESOLVE_SCENARIOS: "venv,uv,system"
# ---------------------------------------------------------------------------
# Verdaccio sanity suite — tests the real `npm install -g` flow.
# Only on push to main (too slow for PRs, needs Docker Compose).
# Catches publish-pipeline bugs: missing files, broken symlinks, wrong bin
# field, dependency resolution failures, postinstall script issues.
# ---------------------------------------------------------------------------
sanity-verdaccio:
name: Sanity (Verdaccio)
needs: changes
if: github.event_name == 'push'
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: oven-sh/setup-bun@ecf28ddc73e819eb6fa29df6b34ef8921c743461 # v2
with:
bun-version: "1.3.10"
- name: Cache Bun dependencies
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
with:
path: ~/.bun/install/cache
key: bun-${{ runner.os }}-${{ hashFiles('bun.lock') }}
restore-keys: |
bun-${{ runner.os }}-
- name: Install dependencies
run: bun install
- name: Build CLI binary
# target-index=1 = linux-x64 (see release.yml matrix)
run: bun run packages/opencode/script/build.ts --target-index=1
env:
OPENCODE_VERSION: 0.0.0-sanity-${{ github.sha }}
OPENCODE_RELEASE: "1"
MODELS_DEV_API_JSON: test/tool/fixtures/models-api.json
- name: Build dbt-tools
run: bun run build
working-directory: packages/dbt-tools
- name: Run Verdaccio sanity suite
run: |
docker compose -f test/sanity/docker-compose.verdaccio.yml up \
--build --abort-on-container-exit --exit-code-from sanity
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
marker-guard:
name: Marker Guard
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
fetch-depth: 0
- uses: oven-sh/setup-bun@ecf28ddc73e819eb6fa29df6b34ef8921c743461 # v2
with:
bun-version: "1.3.10"
- name: Add upstream remote
run: |
git remote add upstream https://github.com/anomalyco/opencode.git || true
git fetch upstream --quiet --no-tags
- name: Install merge tooling deps
run: bun install
working-directory: script/upstream
- name: Run marker parser tests
run: bun test
working-directory: script/upstream
- name: Check for missing altimate_change markers
run: |
if [[ "${{ github.event_name }}" == "push" ]]; then
if [[ "${{ github.event.before }}" == "0000000000000000000000000000000000000000" ]]; then
echo "Initial push (zero-SHA) — skipping marker check"
exit 0
fi
echo "Push to main — running marker check against pre-push state"
bun run script/upstream/analyze.ts --markers --base "${{ github.event.before }}" --strict
elif [[ "${{ github.head_ref }}" == merge-upstream-* ]] || [[ "${{ github.head_ref }}" == upstream/merge-* ]]; then
echo "Upstream merge PR detected — running marker check in non-strict mode"
bun run script/upstream/analyze.ts --markers --base ${{ github.event.pull_request.base.ref }}
else
bun run script/upstream/analyze.ts --markers --base ${{ github.event.pull_request.base.ref }} --strict
fi