Skip to content

feat: default to Altimate Base with no consent gate; stop falling back to keyless Zen #3450

feat: default to Altimate Base with no consent gate; stop falling back to keyless Zen

feat: default to Altimate Base with no consent gate; stop falling back to keyless Zen #3450

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 }}
installer: ${{ steps.filter.outputs.installer }}
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3
id: filter
with:
filters: |
typescript:
# altimate_change start — upstream_fix: typecheck every declared TypeScript workspace
- 'packages/cli/**'
- 'packages/core/**'
- 'packages/dbt-tools/**'
- 'packages/effect-drizzle-sqlite/**'
- 'packages/effect-sqlite-node/**'
- 'packages/http-recorder/**'
- 'packages/llm/**'
- 'packages/opencode/**'
- 'packages/server/**'
- 'packages/tui/**'
# altimate_change end
- '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'
# Run by the "DuckDB store-open E2E" step in the driver-e2e job.
# Without these, a PR touching only these files skips that job,
# and the main TypeScript job runs them with ALTIMATE_DUCKDB_E2E
# unset, which skips every test in them — no execution anywhere.
- 'packages/opencode/test/altimate/duckdb-open-e2e.test.ts'
- 'packages/opencode/test/altimate/warehouse-test-duckdb-e2e.test.ts'
- 'packages/opencode/test/altimate/duckdb-lock-helper.ts'
- 'packages/opencode/src/altimate/tools/warehouse-test.ts'
- 'packages/drivers/test/**'
# These govern whether the native DuckDB binding is fetched at all
# (`trustedDependencies`, and the pinned version). A change to them
# can break every real-DuckDB test while touching no test file.
- 'package.json'
- 'bun.lock'
- 'packages/drivers/package.json'
dbt-tools:
- 'packages/dbt-tools/**'
installer:
- 'install.ps1'
- 'test/windows/**'
# ---------------------------------------------------------------------------
# altimate_change start — run the tracker-leak guard on every PR.
# `script/check-tracker-leaks.ts` and its tests already existed but were wired
# into no workflow, so nothing enforced them: v0.10.0 shipped three new
# `AI-####` references into tracked files on this PUBLIC repo before a human
# review caught them. It scans the branch name, the commits ahead of
# origin/main, and the diff, so it needs full history and the base ref.
tracker-leaks:
name: Tracker Leaks
runs-on: ubuntu-latest
timeout-minutes: 10
# This job runs pull-request code, so it gets read-only scope and no
# persisted credentials — the checked-out branch must not be able to reach
# the token in `.git/config`. (bot review)
permissions:
contents: read
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
fetch-depth: 0
persist-credentials: false
- uses: oven-sh/setup-bun@ecf28ddc73e819eb6fa29df6b34ef8921c743461 # v2
with:
bun-version: "1.3.14"
- name: Fetch base branch
# `--depth=0` is not valid git ("depth 0 is not a positive number") and
# failed the job before the guard could run. `fetch-depth: 0` on the
# checkout above already gives full history, so a plain fetch of the
# base ref is all this needs.
run: git fetch origin main
- name: Check for internal tracker references
# `actions/checkout` lands on the synthetic merge commit in detached
# HEAD, so the script's own `rev-parse --abbrev-ref HEAD` yields "HEAD"
# and the branch-name source -- one of the three it documents -- is
# inert. Pass the real head ref explicitly. (review)
env:
PR_BRANCH: ${{ github.head_ref }}
run: bun script/check-tracker-leaks.ts
# altimate_change end
# 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.14"
- 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 "ci@test.local"
- name: Install dependencies
run: bun install
- name: Install merge tooling deps (script/upstream)
# The script/upstream/ workspace is its own bun project (depends on
# minimatch). Root `bun install` doesn't reach it. Tests in
# test/upstream/bridge-merge-e2e.test.ts shell out to
# `bun run script/upstream/analyze.ts --branding` which requires this.
# Mirrors the install step in the marker-guard job below.
run: bun install
working-directory: script/upstream
# NOTE: there is no "prebuild test CLI" step. We tried pointing the subprocess harness at a
# prebuilt single-file binary (OPENCODE_TEST_CLI) to dodge `bun run src` cold-boot, but the
# compiled binary has a load-triggered hang on the run+mock happy path (it never exits under CPU
# pressure). The robust answer is the dedicated bounded subprocess pass below: `bun run src` (no
# such hang) at --max-concurrency=2, which stays green even under heavy load (~43s locally at
# load 21). Do not reintroduce OPENCODE_TEST_CLI for these tests without fixing that binary hang.
# altimate_change start — deliberate exception: the cold-start-regression job below DOES set
# OPENCODE_TEST_CLI, for exactly one test (test/cli/serve/fresh-start.test.ts). That is safe
# despite the warning above because it is a single bounded cold-start smoke check with its own
# --timeout, not the general run+mock subprocess suite this NOTE is about — the load-triggered
# hang needs sustained CPU pressure across many concurrent mock round-trips to manifest.
# altimate_change end
- name: SDK codegen is reproducible
# The v2 gen tree is committed AND regenerated on every release build
# (script/build.ts, clean: true) with post-codegen patches re-applied.
# A clean checkout must round-trip to itself, or a release ships
# something the review never saw.
working-directory: packages/sdk/js
run: |
# The build mutates the checkout (both gen trees, openapi.json, dist);
# restore it whatever happens so later steps see the committed tree.
# An EXIT trap runs on `bash -e` aborts too.
cleanup() {
git checkout -- src/gen src/v2/gen 2>/dev/null
git clean -qfd src/gen src/v2/gen 2>/dev/null
rm -rf dist openapi.json build.log
}
trap cleanup EXIT
# Prove codegen actually ran: a sentinel comment on the asserted file
# (a comment, because the generator itself imports this client) must
# be gone afterwards. A failure anywhere before the clean:true wipe
# leaves the committed copy — and the sentinel — in place, so it can
# no longer pass the drift check untouched.
sed -i '1i // CI-SENTINEL: not regenerated' src/v2/gen/client/client.gen.ts
build_rc=0; bun script/build.ts > build.log 2>&1 || build_rc=$?
cat build.log
if grep -q 'CI-SENTINEL: not regenerated' src/v2/gen/client/client.gen.ts; then
echo "::error::codegen did not regenerate src/v2/gen/client/client.gen.ts (build exit $build_rc)"
exit 1
fi
drift_rc=0; git diff --exit-code -- src/v2/gen/client/client.gen.ts || drift_rc=$?
# build.ts ends with `bun tsc`, which fails on a clean main until the
# types.gen.ts round-trip is fixed (issue #1148). That ONE failure is
# whitelisted by its EXACT diagnostic set — not merely "tsc failed",
# which would silently whitelist new type regressions in the
# regenerated SDK (script/check-known-tsc-failure.sh, unit-tested) —
# and only when the file was regenerated AND round-trips (the two
# assertions above); any other non-zero build — codegen, a patch,
# prettier — fails the step. Remove the whitelist with #1148.
if [ "$build_rc" -ne 0 ]; then
wl_rc=0; bash script/check-known-tsc-failure.sh build.log || wl_rc=$?
if [ "$wl_rc" -eq 0 ]; then
echo "::warning::build.ts exited $build_rc at tsc with exactly the known #1148 diagnostic (TS2305 FileSystemEntry); codegen+patch asserted above"
elif [ "$wl_rc" -eq 2 ]; then
echo "::error::build.ts exited $build_rc before tsc — not the whitelisted #1148 failure"
exit "$build_rc"
else
echo "::error::tsc failed with diagnostics beyond the whitelisted #1148 set (see output above)"
exit "$build_rc"
fi
fi
exit "$drift_rc"
- 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 90000: the full suite (9500+ tests across 379 files) runs in
# one parallel bun process. Under CPU contention a handful of slower tests
# (real fs/spawn/git-bootstrap work) get starved and exceed a tight timeout
# NON-deterministically — different tests each run — failing CI with
# "timed out after Nms" (observed 32s/51s at the old 30s limit). 90s gives
# ~3x headroom over the worst observed, killing the resource-contention
# flakiness without masking genuinely-hung tests.
#
# 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 files, then cat for CI visibility (avoids tee/SIGTERM-flush issues).
#
# Two passes:
# - MAIN: the full suite EXCEPT the subprocess tests (OPENCODE_SKIP_SUBPROCESS=1 makes cliIt
# skip them), at default parallelism — fast.
# - SUBPROCESS: test/cli/{acp,smokes,serve} + run-process/mcp-add/help-snapshots, run in a
# DEDICATED pass with --max-concurrency=2 (default 20). These each spawn a real CLI + an
# in-process mock LLM server; at 20-concurrent the runner is CPU-starved and the mock
# round-trips time out (the load-variance flakes). NOTE: do NOT add --parallel=1 — a single
# worker hosts the mock server AND runs the tests on one event loop, so the mock gets starved
# and round-trips time out anyway. Default --parallel spreads the mocks across workers; the
# pass is isolated from the 11k main-suite tests so 2-per-worker is plenty bounded.
# (Bun 1.3.x can segfault during cleanup after all tests pass — we parse the summary, not the
# exit code. --timeout 90000 gives headroom for slow fs/spawn tests.)
SUBPROCESS_PATHS="test/cli/acp/ test/cli/smokes/ test/cli/serve/ test/cli/run/run-process.test.ts test/cli/mcp-add.test.ts test/cli/help/help-snapshots.test.ts"
OPENCODE_SKIP_SUBPROCESS=1 bun test --timeout 90000 > /tmp/test-main.txt 2>&1 || true
bun test --timeout 90000 --max-concurrency=2 $SUBPROCESS_PATHS > /tmp/test-sub.txt 2>&1 || true
echo "===== MAIN SUITE ====="; cat /tmp/test-main.txt
echo "===== SUBPROCESS SUITE (bounded) ====="; cat /tmp/test-sub.txt
# Sum pass/fail across both passes (one summary line each)
sum_field() { awk -v f="$1" '$0 ~ ("^ *[0-9]+ " f "$"){s+=$1} END{print s+0}' /tmp/test-main.txt /tmp/test-sub.txt; }
PASS_COUNT=$(sum_field pass)
FAIL_COUNT=$(sum_field fail)
echo ""
echo "--- Test Summary (main + subprocess) ---"
echo "pass=$PASS_COUNT fail=$FAIL_COUNT"
# Real test failures — always fail CI
if [ "$FAIL_COUNT" != "0" ]; then
echo "::error::$FAIL_COUNT test(s) failed"
exit 1
fi
# Each pass must have produced a summary, else Bun crashed before finishing
if ! grep -qE "^ *[0-9]+ pass$" /tmp/test-main.txt || ! grep -qE "^ *[0-9]+ pass$" /tmp/test-sub.txt; then
echo "::error::Missing test summary in a pass — Bun may have crashed before running tests"
exit 1
fi
if [ "$PASS_COUNT" -gt 0 ] 2>/dev/null; then
exit 0
fi
echo "::error::No test results found"
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.14"
- 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
# `packages/drivers` declares no scripts and no job had it as a working
# directory, so its 141 unit tests — including the driver's lock, timeout
# and read-only regressions — never ran in CI at all. The main TypeScript
# job runs `bun test` from `packages/opencode` only.
- name: Run drivers unit suite
run: bun test --timeout 60000
working-directory: packages/drivers
- 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
# Needs a dedicated process: four files in test/altimate install a
# top-level mock.module("@altimateai/drivers/duckdb", …), and Bun
# evaluates every test file's top level before running any test, so in a
# whole-directory run these would silently exercise a fake. With
# ALTIMATE_DUCKDB_E2E=1 a missing or mocked driver fails the step rather
# than skipping it.
#
# `--timeout` is explicit because invoking `bun test` directly does not use
# the package's `test` script, so it would otherwise take the CLI default
# of 5000ms — shorter than both the driver's 30s default open budget and
# the lock helper's 30s readiness budget, which would reimpose exactly the
# kind of too-short outer deadline this PR removes.
- name: Run DuckDB store-open E2E (real store, no mocks)
run: bun test --timeout 90000 test/altimate/duckdb-open-e2e.test.ts test/altimate/warehouse-test-duckdb-e2e.test.ts
working-directory: packages/opencode
env:
ALTIMATE_DUCKDB_E2E: "1"
- 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.14"
- name: Install dependencies
run: bun install
- name: Run dbt-tools unit tests
run: bun run test
working-directory: packages/dbt-tools
# ---------------------------------------------------------------------------
# Windows installer (install.ps1) — Pester behavioral tests on real Windows.
# Runs the script as a subprocess (stopping early via -Help / unknown version
# so nothing is downloaded) to cover arg parsing, the WOW64 arch fix, and
# unknown-version rejection. Only when install.ps1 / its tests change.
# ---------------------------------------------------------------------------
windows-installer:
name: Windows Installer (Pester)
needs: changes
if: needs.changes.outputs.installer == 'true' || github.event_name == 'push'
runs-on: windows-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Install Pester
shell: pwsh
run: Install-Module Pester -MinimumVersion 5.0.0 -Force -Scope CurrentUser -SkipPublisherCheck
- name: Run installer Pester tests
shell: pwsh
run: |
$config = New-PesterConfiguration
$config.Run.Path = "./test/windows/install.Tests.ps1"
$config.Run.Throw = $true
$config.Output.Verbosity = "Detailed"
Invoke-Pester -Configuration $config
# altimate_change start — Windows ripgrep E2E (issue #1072)
# ---------------------------------------------------------------------------
# Real Windows check for ripgrep binary resolution. Downloads and extracts the
# actual archive with PowerShell stripped from PATH, then executes the binary.
# This is the condition that broke grep for 99 Windows machines; no amount of
# unit testing on Linux/macOS covers it.
# ---------------------------------------------------------------------------
windows-ripgrep-e2e:
name: Windows ripgrep E2E
needs: changes
if: needs.changes.outputs.typescript == 'true' || github.event_name == 'push'
runs-on: windows-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: oven-sh/setup-bun@ecf28ddc73e819eb6fa29df6b34ef8921c743461 # v2
with:
bun-version: "1.3.14"
# --ignore-scripts: `tree-sitter-powershell` has no Windows prebuild and its fallback
# compile needs Visual Studio Build Tools, which this runner does not have (see
# anomalyco/opencode#25563). This check only needs the pure-JS dependency graph
# (effect, @zip.js/zip.js, which, xdg-basedir), so skipping lifecycle scripts is enough.
- name: Install dependencies
run: bun install --ignore-scripts
# Run from packages/core so `effect` and the other deps resolve — they are not root deps.
- name: Resolve ripgrep with PowerShell unavailable
working-directory: packages/core
run: bun run script/windows-ripgrep-e2e.ts
# altimate_change end
# ---------------------------------------------------------------------------
# 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.14"
- 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.14"
- 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"
ALTIMATE_BASE_GATEWAY_URL: https://gateway.test
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 }}
# altimate_change start — cold-start config regression, split out of sanity-verdaccio so it also
# runs on PRs. sanity-verdaccio stays push-only by design (Docker Compose, too slow for PRs — see
# its header above); this check only needs the compiled binary, so it gets its own job gated like
# `typescript` above: on PRs that touch TS, and unconditionally on push (safety net).
# ---------------------------------------------------------------------------
cold-start-regression:
name: Cold-start Config Regression
needs: changes
if: needs.changes.outputs.typescript == 'true' || 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.14"
- 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"
ALTIMATE_BASE_GATEWAY_URL: https://gateway.test
MODELS_DEV_API_JSON: test/tool/fixtures/models-api.json
# --version and PURE-mode tests never exercise ordinary config installs. This is the
# deliberate exception to the "no OPENCODE_TEST_CLI" NOTE in the `typescript` job above: a
# single bounded cold-start check with its own --timeout, not the general run+mock subprocess
# suite, so the compiled-binary load hang that NOTE warns about cannot stall CI here.
- name: Cold-start config regression (compiled, non-PURE)
working-directory: packages/opencode
env:
OPENCODE_TEST_CLI: ${{ github.workspace }}/packages/opencode/dist/@altimateai/altimate-code-linux-x64/bin/altimate-code
run: bun test test/cli/serve/fresh-start.test.ts --timeout 90000
# altimate_change end
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.14"
- 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: Run release preflight tests
# Root bunfig.toml pins `bun test` away from the repo root, so run from
# script/ — same pattern as the marker parser tests above.
run: bun test release-preflight.test.ts
working-directory: script
- 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
# Squash-merging an `upstream/merge-*` PR lands as a single commit
# on main, so the second-parent / branch-name signal is gone here.
# Detect bridge/merge-upstream commits in the pushed range by subject
# and downgrade to non-strict — the PR-side review already gated this.
if git log --format=%s "${{ github.event.before }}..${{ github.sha }}" \
| grep -qiE '(bridge|merge) upstream'; then
echo "Bridge/upstream-merge commit detected in push range — running marker check in non-strict mode"
bun run script/upstream/analyze.ts --markers --base "${{ github.event.before }}"
else
echo "Push to main — running marker check against pre-push state"
bun run script/upstream/analyze.ts --markers --base "${{ github.event.before }}" --strict
fi
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 origin/${{ github.event.pull_request.base.ref }}
else
bun run script/upstream/analyze.ts --markers --base origin/${{ github.event.pull_request.base.ref }} --strict
fi
- name: Branding leak audit (broadened scan, see analyze.ts LEAK_PATTERNS)
# Catches user-visible bare "opencode" strings that markers alone miss —
# yargs describe text, console output, MCP client identity, workflow YAML,
# User-Agent strings, OIDC audience, infrastructure identifiers.
# Caught 13 of 16 v1.4.0 bridge merge regressions in retrospective testing.
run: bun run script/upstream/analyze.ts --branding
- name: Require-markers regression backstop
# Verifies every file in config.requireMarkers (38 files known to hold
# altimate behavioral patches) has at least one altimate_change block.
# If any patches were silently lost (refactor, accidental delete, bridge
# merge oversight), CI fails here BEFORE the bug reaches production.
run: bun run script/upstream/analyze.ts --require-markers --strict