From de1ba2ab1c6a93eab0361d38f9b19428c97c77ef Mon Sep 17 00:00:00 2001 From: anandgupta42 Date: Sun, 15 Mar 2026 13:47:34 -0700 Subject: [PATCH 1/4] fix: gate release workflow on tests and add build branding guards Release workflow: - Add test job (typecheck + bun test) that must pass before build/publish - Both build and publish-engine now depend on test job Branding guard tests (upstream-merge-guard.test.ts): - build.ts binary name is 'altimate' not 'opencode' - build.ts user-agent is 'altimate/' not 'opencode/' - build.ts embeds ALTIMATE_ENGINE_VERSION - build.ts reads engine version from pyproject.toml - build.ts creates altimate-code backward-compat symlink - build.ts has sourcemap: "external" - package.json bin entries are correct (no 'opencode') - package.json has no junk fields or echo-stub scripts - bin/opencode does not exist - keepOurs config includes build.ts, publish.ts, bin/**, CHANGELOG.md Publish package test: - Assert 'altimate' bin points to ./bin/altimate - Assert no 'opencode' bin entry exists --- .github/workflows/release.yml | 38 +++++++++- .../branding/upstream-merge-guard.test.ts | 74 ++++++++++++++++++- 2 files changed, 108 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 608dfa0253..d80bf041d3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,8 +13,43 @@ env: GH_REPO: AltimateAI/altimate-code jobs: + test: + name: Test + 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 "ci@test.local" + + - name: Install dependencies + run: bun install + + - name: Typecheck + run: bun turbo typecheck + + - name: Run tests + run: bun test + working-directory: packages/opencode + build: name: Build (${{ matrix.os }}) + needs: test runs-on: ubuntu-latest timeout-minutes: 60 permissions: @@ -122,9 +157,10 @@ jobs: GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }} # Engine publish runs without waiting for build — it builds from source and - # doesn't need CLI binary artifacts. This allows it to run in parallel. + # doesn't need CLI binary artifacts. This allows it to run in parallel with build. publish-engine: name: Publish engine to PyPI + needs: test runs-on: ubuntu-latest timeout-minutes: 60 environment: pypi diff --git a/packages/opencode/test/branding/upstream-merge-guard.test.ts b/packages/opencode/test/branding/upstream-merge-guard.test.ts index 54f8a5f24f..4bdf54063f 100644 --- a/packages/opencode/test/branding/upstream-merge-guard.test.ts +++ b/packages/opencode/test/branding/upstream-merge-guard.test.ts @@ -266,7 +266,71 @@ describe("No opencode.ai domain leaks in src/", () => { }) // --------------------------------------------------------------------------- -// 6. Repository Hygiene +// 6. Build & Package Branding +// --------------------------------------------------------------------------- +describe("Build and package branding", () => { + const buildTs = readText(join(pkgDir, "script", "build.ts")) + const pkg = readJSON(join(pkgDir, "package.json")) + + test("build.ts compiles binary as 'altimate' not 'opencode'", () => { + expect(buildTs).toContain("bin/altimate") + expect(buildTs).not.toMatch(/outfile:.*opencode/) + }) + + test("build.ts user-agent is 'altimate/' not 'opencode/'", () => { + expect(buildTs).toContain("--user-agent=altimate/") + expect(buildTs).not.toContain("--user-agent=opencode/") + }) + + test("build.ts embeds ALTIMATE_ENGINE_VERSION", () => { + expect(buildTs).toContain("ALTIMATE_ENGINE_VERSION") + }) + + test("build.ts reads engine version from pyproject.toml", () => { + expect(buildTs).toContain("altimate-engine/pyproject.toml") + }) + + test("build.ts creates altimate-code backward-compat symlink", () => { + expect(buildTs).toContain("altimate-code") + expect(buildTs).toMatch(/ln -sf altimate|altimate-code\.exe/) + }) + + test("build.ts has sourcemap: 'external'", () => { + expect(buildTs).toContain('sourcemap: "external"') + }) + + test("package.json bin has 'altimate' pointing to ./bin/altimate", () => { + expect(pkg.bin.altimate).toBe("./bin/altimate") + }) + + test("package.json bin has 'altimate-code' pointing to ./bin/altimate-code", () => { + expect(pkg.bin["altimate-code"]).toBe("./bin/altimate-code") + }) + + test("package.json bin does not have 'opencode' entry", () => { + expect(pkg.bin.opencode).toBeUndefined() + }) + + test("package.json has no junk fields", () => { + expect(pkg.randomField).toBeUndefined() + }) + + test("package.json has no echo-stub scripts", () => { + const junkNames = ["random", "clean", "lint", "format", "docs", "deploy"] + for (const name of junkNames) { + if (pkg.scripts?.[name]) { + expect(pkg.scripts[name]).not.toMatch(/^echo /) + } + } + }) + + test("bin/opencode does not exist", () => { + expect(existsSync(join(pkgDir, "bin", "opencode"))).toBe(false) + }) +}) + +// --------------------------------------------------------------------------- +// 7. Repository Hygiene // --------------------------------------------------------------------------- describe("Repository hygiene", () => { test("__pycache__ is in .gitignore", () => { @@ -301,7 +365,7 @@ describe("Repository hygiene", () => { }) // --------------------------------------------------------------------------- -// 7. Config Integrity +// 8. Config Integrity // --------------------------------------------------------------------------- describe("Config integrity", () => { const configTsPath = join(repoRoot, "script", "upstream", "utils", "config.ts") @@ -313,6 +377,10 @@ describe("Config integrity", () => { "script/upstream/**", "packages/opencode/src/altimate/**", "packages/opencode/src/bridge/**", + "packages/opencode/script/build.ts", + "packages/opencode/script/publish.ts", + "packages/opencode/bin/**", + "CHANGELOG.md", ] for (const pattern of criticalKeepOurs) { expect(configTs).toContain(`"${pattern}"`) @@ -344,7 +412,7 @@ describe("Config integrity", () => { }) // --------------------------------------------------------------------------- -// 8. altimate_change Marker Integrity +// 9. altimate_change Marker Integrity // --------------------------------------------------------------------------- describe("altimate_change marker integrity", () => { // Files that MUST have altimate_change markers (they contain custom logic in upstream-shared files) From 06e93554f3a637c6c80f5f908aaad3c7cf8694af Mon Sep 17 00:00:00 2001 From: anandgupta42 Date: Sun, 15 Mar 2026 13:54:07 -0700 Subject: [PATCH 2/4] fix: scope release test job to release-critical tests only Scope the release workflow test job to branding and install tests only, with --timeout 30000 for consistency with package.json. Prevents unrelated flaky tests from blocking releases while still catching branding regressions and packaging issues. --- .github/workflows/release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d80bf041d3..ca23d23306 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -43,8 +43,8 @@ jobs: - name: Typecheck run: bun turbo typecheck - - name: Run tests - run: bun test + - name: Run release-critical tests + run: bun test --timeout 30000 test/branding/ test/install/ working-directory: packages/opencode build: From d25f67dd91a3f74070a262d93d7c3d69228ed5f6 Mon Sep 17 00:00:00 2001 From: anandgupta42 Date: Sun, 15 Mar 2026 13:55:15 -0700 Subject: [PATCH 3/4] fix: fix pr-management duplicate check and update TEAM_MEMBERS - Replace broken `curl altimate.ai/install` with `npm install -g @altimateai/altimate-code` (altimate.ai/install returns HTML, not a shell script) - Replace upstream TEAM_MEMBERS with actual AltimateAI collaborators so internal PRs skip the duplicate check --- .github/TEAM_MEMBERS | 45 +++++++++++++++++++---------- .github/workflows/pr-management.yml | 4 +-- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/.github/TEAM_MEMBERS b/.github/TEAM_MEMBERS index 22c9a923d3..b2e585fbc8 100644 --- a/.github/TEAM_MEMBERS +++ b/.github/TEAM_MEMBERS @@ -1,15 +1,30 @@ -adamdotdevin -Brendonovich -fwang -Hona -iamdavidhill -jayair -jlongster -kitlangton -kommander -MrMushrooooom -nexxeln -R44VC0RP -rekram1-node -RhysSullivan -thdxr +aidtya +aloks98 +altimateanas +anandgupta42 +ankitksharma +anusha-sharma +arora-saurabh448 +dvanaken +frasermarlow +gaurpulkit +govindpawa +jontsai +kulvirgit +mdesmet +mhallida +ppradnesh +rakendd +ralphstodomingo +ravik-aai +robertmaybin +sahrizvi +sanjaykr5 +saravmajestic +sgvarsh +shreyastelkar +Sourabhchrs93 +suryaiyer95 +tshreyas +vivekvenkatareddy +yukthagv diff --git a/.github/workflows/pr-management.yml b/.github/workflows/pr-management.yml index 529dd315b7..bf1d07898b 100644 --- a/.github/workflows/pr-management.yml +++ b/.github/workflows/pr-management.yml @@ -35,9 +35,9 @@ jobs: if: steps.team-check.outputs.is_team != 'true' run: bun install - - name: Install opencode + - name: Install altimate-code if: steps.team-check.outputs.is_team != 'true' - run: curl -fsSL https://altimate.ai/install | bash + run: npm install -g @altimateai/altimate-code - name: Build prompt if: steps.team-check.outputs.is_team != 'true' From e91b0790b2cb76ce721fa0bd88933e90921c83ae Mon Sep 17 00:00:00 2001 From: anandgupta42 Date: Sun, 15 Mar 2026 14:02:53 -0700 Subject: [PATCH 4/4] =?UTF-8?q?fix:=20address=20code=20review=20findings?= =?UTF-8?q?=20=E2=80=94=20regex=20precedence=20and=20case-sensitive=20TEAM?= =?UTF-8?q?=5FMEMBERS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Split symlink guard regex into two explicit assertions to prevent false positives (Unix symlink + Windows .exe checked independently) - Lowercase TEAM_MEMBERS entries and make grep case-insensitive (-i) since GitHub logins are case-insensitive --- .github/TEAM_MEMBERS | 2 +- .github/workflows/pr-management.yml | 4 ++-- .../opencode/test/branding/upstream-merge-guard.test.ts | 6 ++++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/TEAM_MEMBERS b/.github/TEAM_MEMBERS index b2e585fbc8..34b7b23648 100644 --- a/.github/TEAM_MEMBERS +++ b/.github/TEAM_MEMBERS @@ -23,7 +23,7 @@ sanjaykr5 saravmajestic sgvarsh shreyastelkar -Sourabhchrs93 +sourabhchrs93 suryaiyer95 tshreyas vivekvenkatareddy diff --git a/.github/workflows/pr-management.yml b/.github/workflows/pr-management.yml index bf1d07898b..06eca8f3ae 100644 --- a/.github/workflows/pr-management.yml +++ b/.github/workflows/pr-management.yml @@ -19,8 +19,8 @@ jobs: - name: Check team membership id: team-check run: | - LOGIN="${{ github.event.pull_request.user.login }}" - if [ "$LOGIN" = "opencode-agent[bot]" ] || grep -qxF "$LOGIN" .github/TEAM_MEMBERS; then + LOGIN=$(echo "${{ github.event.pull_request.user.login }}" | tr '[:upper:]' '[:lower:]') + if [ "$LOGIN" = "opencode-agent[bot]" ] || grep -qixF "$LOGIN" .github/TEAM_MEMBERS; then echo "is_team=true" >> "$GITHUB_OUTPUT" echo "Skipping: $LOGIN is a team member or bot" else diff --git a/packages/opencode/test/branding/upstream-merge-guard.test.ts b/packages/opencode/test/branding/upstream-merge-guard.test.ts index 4bdf54063f..0fde091f59 100644 --- a/packages/opencode/test/branding/upstream-merge-guard.test.ts +++ b/packages/opencode/test/branding/upstream-merge-guard.test.ts @@ -291,8 +291,10 @@ describe("Build and package branding", () => { }) test("build.ts creates altimate-code backward-compat symlink", () => { - expect(buildTs).toContain("altimate-code") - expect(buildTs).toMatch(/ln -sf altimate|altimate-code\.exe/) + // Unix: symlink + expect(buildTs).toContain("ln -sf altimate") + // Windows: copy + expect(buildTs).toContain("altimate-code.exe") }) test("build.ts has sourcemap: 'external'", () => {