release: v0.5.14 #72
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release | |
| on: | |
| push: | |
| tags: | |
| - "v*" | |
| concurrency: | |
| group: release | |
| cancel-in-progress: false | |
| 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 "[email protected]" | |
| - name: Install dependencies | |
| run: bun install | |
| - name: Typecheck | |
| run: bun turbo typecheck | |
| - name: Run release-critical tests | |
| run: bun test --timeout 30000 test/branding/ test/install/ | |
| working-directory: packages/opencode | |
| build: | |
| name: Build (${{ matrix.name }}) | |
| # Runs in PARALLEL with test — publish waits for both | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| permissions: | |
| contents: read | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| 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 | |
| - 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 ${{ matrix.name }} | |
| run: bun run packages/opencode/script/build.ts --target-index=${{ matrix.index }} | |
| env: | |
| OPENCODE_VERSION: ${{ github.ref_name }} | |
| OPENCODE_CHANNEL: latest | |
| OPENCODE_RELEASE: "1" | |
| GH_REPO: ${{ env.GH_REPO }} | |
| MODELS_DEV_API_JSON: test/tool/fixtures/models-api.json | |
| # Smoke-test: verify the compiled binary actually starts. | |
| # Only possible for native linux-x64 builds on the ubuntu runner. | |
| # This catches missing externals (e.g. @altimateai/altimate-core) | |
| # that compile fine but crash at runtime. | |
| - name: Smoke test binary | |
| if: matrix.name == 'linux-x64' | |
| run: | | |
| BINARY=$(find packages/opencode/dist -name altimate -type f | head -1) | |
| if [ -z "$BINARY" ]; then | |
| echo "::error::No binary found in dist/" | |
| exit 1 | |
| fi | |
| chmod +x "$BINARY" | |
| # Set NODE_PATH so the binary can resolve external NAPI modules | |
| # (mirrors what the npm bin wrapper does at runtime) | |
| NODE_PATH="$(pwd)/packages/opencode/node_modules:$(pwd)/node_modules" "$BINARY" --version | |
| echo "Smoke test passed: binary starts and prints version" | |
| - name: Upload build artifact | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | |
| with: | |
| name: dist-${{ matrix.name }} | |
| path: packages/opencode/dist/ | |
| compression-level: 1 | |
| publish-npm: | |
| name: Publish to npm | |
| needs: build | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 60 | |
| permissions: | |
| contents: read | |
| 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 dbt-tools (bundled with CLI) | |
| run: bun run build | |
| working-directory: packages/dbt-tools | |
| - name: Smoke test dbt-tools bundle | |
| run: | | |
| # Verify node_python_bridge.py was copied into dist | |
| if [ ! -f packages/dbt-tools/dist/node_python_bridge.py ]; then | |
| echo "::error::node_python_bridge.py missing from dbt-tools dist" | |
| exit 1 | |
| fi | |
| # Verify no hardcoded absolute path in __dirname (catches any CI runner OS) | |
| if grep -qE 'var __dirname\s*=\s*"(/|[A-Za-z]:\\)' packages/dbt-tools/dist/index.js; then | |
| echo "::error::dbt-tools bundle contains hardcoded absolute path in __dirname" | |
| exit 1 | |
| fi | |
| # Verify __dirname was patched to runtime resolution | |
| if ! grep -q 'import.meta.dirname' packages/dbt-tools/dist/index.js; then | |
| echo "::error::dbt-tools bundle missing import.meta.dirname patch" | |
| exit 1 | |
| fi | |
| echo "dbt-tools smoke test passed" | |
| - name: Free disk space for artifact download + npm publish | |
| run: | | |
| sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /usr/local/share/boost | |
| df -h / | |
| - name: Download all build artifacts | |
| uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 | |
| with: | |
| pattern: "dist-*" | |
| path: packages/opencode/dist/ | |
| merge-multiple: true | |
| - name: Configure npm auth | |
| run: echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > "$RUNNER_TEMP/.npmrc" | |
| env: | |
| NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| # TODO: Uncomment when AUR publishing is enabled (see publish.ts for setup steps) | |
| # - name: Configure SSH for AUR | |
| # if: ${{ !contains(github.ref_name, '-') }} | |
| # run: | | |
| # mkdir -p ~/.ssh | |
| # echo "$AUR_SSH_PRIVATE_KEY" > ~/.ssh/aur | |
| # chmod 600 ~/.ssh/aur | |
| # ssh-keyscan -t ed25519 aur.archlinux.org >> ~/.ssh/known_hosts 2>/dev/null | |
| # cat >> ~/.ssh/config << 'EOF' | |
| # Host aur.archlinux.org | |
| # IdentityFile ~/.ssh/aur | |
| # User aur | |
| # EOF | |
| # env: | |
| # AUR_SSH_PRIVATE_KEY: ${{ secrets.AUR_SSH_PRIVATE_KEY }} | |
| # Smoke-test a linux-x64 binary from the downloaded artifacts before publishing. | |
| # This is the last gate before npm publish — catches runtime crashes that | |
| # compile-time checks miss (e.g. missing NAPI externals like v0.5.10). | |
| - name: Pre-publish smoke test | |
| run: | | |
| BINARY=$(find packages/opencode/dist -path '*altimate-code-linux-x64/bin/altimate' -type f | head -1) | |
| if [ -z "$BINARY" ]; then | |
| echo "::error::No linux-x64 binary found in artifacts — cannot verify release" | |
| exit 1 | |
| else | |
| chmod +x "$BINARY" | |
| NODE_PATH="$(pwd)/packages/opencode/node_modules:$(pwd)/node_modules" "$BINARY" --version | |
| echo "Pre-publish smoke test passed" | |
| fi | |
| - name: Publish to npm | |
| run: bun run packages/opencode/script/publish.ts | |
| env: | |
| OPENCODE_VERSION: ${{ github.ref_name }} | |
| OPENCODE_CHANNEL: latest | |
| OPENCODE_RELEASE: "1" | |
| NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| NPM_CONFIG_USERCONFIG: ${{ runner.temp }}/.npmrc | |
| GH_REPO: ${{ env.GH_REPO }} | |
| GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }} | |
| # Python engine (publish-engine) job removed — engine eliminated. | |
| # All methods now run natively in TypeScript. | |
| github-release: | |
| name: Create GitHub Release | |
| needs: [build, publish-npm] | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 60 | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Generate release notes | |
| id: notes | |
| run: | | |
| # Validate tag format to prevent injection | |
| if ! echo "$CURRENT_TAG" | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9._-]+)?$'; then | |
| echo "::error::Invalid tag format: $CURRENT_TAG" | |
| exit 1 | |
| fi | |
| # Get the previous tag | |
| PREV_TAG=$(git tag --sort=-version:refname | grep -E '^v[0-9]' | head -2 | tail -1) | |
| # Generate changelog from commits between tags | |
| echo "## What's Changed" > notes.md | |
| echo "" >> notes.md | |
| if [ -n "$PREV_TAG" ]; then | |
| # Categorize commits | |
| echo "### Features" >> notes.md | |
| git log "${PREV_TAG}".."${CURRENT_TAG}" --pretty=format:"- %s (%h)" --grep="^feat" >> notes.md || true | |
| echo "" >> notes.md | |
| echo "" >> notes.md | |
| echo "### Bug Fixes" >> notes.md | |
| git log "${PREV_TAG}".."${CURRENT_TAG}" --pretty=format:"- %s (%h)" --grep="^fix" >> notes.md || true | |
| echo "" >> notes.md | |
| echo "" >> notes.md | |
| echo "### Other Changes" >> notes.md | |
| git log "${PREV_TAG}".."${CURRENT_TAG}" --pretty=format:"- %s (%h)" --invert-grep --grep="^feat" --grep="^fix" >> notes.md || true | |
| echo "" >> notes.md | |
| else | |
| echo "Initial release" >> notes.md | |
| fi | |
| echo "" >> notes.md | |
| echo "### Install" >> notes.md | |
| echo '```bash' >> notes.md | |
| echo "npm install -g @altimateai/altimate-code@${CURRENT_TAG#v}" >> notes.md | |
| echo "# or" >> notes.md | |
| echo "brew install AltimateAI/tap/altimate-code" >> notes.md | |
| echo '```' >> notes.md | |
| echo "" >> notes.md | |
| echo "**Full Changelog**: https://github.com/${GH_REPO}/compare/${PREV_TAG}...${CURRENT_TAG}" >> notes.md | |
| env: | |
| GH_REPO: ${{ env.GH_REPO }} | |
| CURRENT_TAG: ${{ github.ref_name }} | |
| - name: Download all build artifacts | |
| uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 | |
| with: | |
| pattern: "dist-*" | |
| path: packages/opencode/dist/ | |
| merge-multiple: true | |
| - name: Create GitHub Release | |
| uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2 | |
| with: | |
| body_path: notes.md | |
| draft: false | |
| prerelease: ${{ contains(github.ref_name, '-') }} | |
| files: | | |
| packages/opencode/dist/*.tar.gz | |
| packages/opencode/dist/*.zip | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |