Skip to content

Merge pull request #2 from anomalyco/checkpoint-cursor #14

Merge pull request #2 from anomalyco/checkpoint-cursor

Merge pull request #2 from anomalyco/checkpoint-cursor #14

Workflow file for this run

name: Release
on:
push:
branches:
- master
tags:
- "v*"
permissions:
contents: read
env:
CARGO_TERM_COLOR: always
PROTOCOL_VERSION: 6
ZIG_VERSION: 0.15.2
GNU_GLIBC_VERSION: "2.30"
CARGO_ZIGBUILD_VERSION: 0.23.2
jobs:
checks:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: mlugg/setup-zig@8d6198c65fb0feaa111df26e6b467fea8345e46f # v2.0.5
with:
version: ${{ env.ZIG_VERSION }}
- name: Configure baseline Zig builds
run: |
chmod +x "$GITHUB_WORKSPACE/script/release-bin/zig"
echo "OPENCODE_REAL_ZIG=$(command -v zig)" >> "$GITHUB_ENV"
echo "$GITHUB_WORKSPACE/script/release-bin" >> "$GITHUB_PATH"
- name: Install Rust
run: rustup toolchain install 1.90.0 --profile minimal --component clippy --component rustfmt
- name: Validate tag
run: |
package_version="$(cargo metadata --no-deps --format-version 1 | jq -r '.packages[] | select(.name == "opencode-pty") | .version')"
npm_version="$(node -p 'require("./npm/package.json").version')"
test "$package_version" = "$npm_version"
node -e 'const pkg = require("./npm/package.json"); if (Object.values(pkg.optionalDependencies).some(version => version !== pkg.version)) process.exit(1)'
if [[ "$GITHUB_REF" == refs/tags/* ]]; then
[[ "$GITHUB_REF_NAME" =~ ^v[0-9]+\.[0-9]+\.[0-9]+([+-][0-9A-Za-z.-]+)?$ ]]
test "${GITHUB_REF_NAME#v}" = "$package_version"
fi
- run: cargo fmt --check
- run: cargo clippy --all-targets --all-features -- -D warnings
build:
needs: checks
strategy:
fail-fast: false
matrix:
include:
- runner: ubuntu-22.04
target: x86_64-unknown-linux-gnu
- runner: ubuntu-22.04-arm
target: aarch64-unknown-linux-gnu
- runner: ubuntu-22.04
target: x86_64-unknown-linux-musl
musl: true
- runner: ubuntu-22.04-arm
target: aarch64-unknown-linux-musl
musl: true
- runner: macos-15-intel
target: x86_64-apple-darwin
- runner: macos-15
target: aarch64-apple-darwin
runs-on: ${{ matrix.runner }}
env:
MACOSX_DEPLOYMENT_TARGET: "11.0"
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: mlugg/setup-zig@8d6198c65fb0feaa111df26e6b467fea8345e46f # v2.0.5
with:
version: ${{ env.ZIG_VERSION }}
cache-key: ${{ matrix.target }}
- name: Configure baseline Zig builds
run: |
chmod +x "$GITHUB_WORKSPACE/script/release-bin/zig"
echo "OPENCODE_REAL_ZIG=$(command -v zig)" >> "$GITHUB_ENV"
echo "$GITHUB_WORKSPACE/script/release-bin" >> "$GITHUB_PATH"
- name: Install musl toolchain
if: matrix.musl
run: sudo apt-get update && sudo apt-get install -y musl-tools
- name: Install Rust target
run: rustup toolchain install 1.90.0 --profile minimal --target "${{ matrix.target }}"
- name: Install glibc baseline linker
if: endsWith(matrix.target, '-linux-gnu')
run: cargo install cargo-zigbuild --locked --version "$CARGO_ZIGBUILD_VERSION"
- name: Test service
run: cargo test --locked --target "${{ matrix.target }}" --lib --test service
- name: Test CLI integration
if: runner.os != 'macOS'
run: cargo test --locked --target "${{ matrix.target }}" --test playground
- name: Build
run: |
if [[ "${{ matrix.target }}" == *-linux-gnu ]]; then
cargo zigbuild --locked --release --target "${{ matrix.target }}.$GNU_GLIBC_VERSION"
else
cargo build --locked --release --target "${{ matrix.target }}"
fi
- name: Verify glibc baseline
if: endsWith(matrix.target, '-linux-gnu')
run: |
binary="target/${{ matrix.target }}/release/opencode-pty"
required="$(readelf --version-info "$binary" | grep -oE 'GLIBC_[0-9]+(\.[0-9]+)+' | sed 's/GLIBC_//' | sort -V | tail -n 1)"
echo "Highest required glibc version: $required"
test "$(printf '%s\n' "$required" "$GNU_GLIBC_VERSION" | sort -V | tail -n 1)" = "$GNU_GLIBC_VERSION"
- name: Smoke test
run: |
version="$(cargo metadata --no-deps --format-version 1 | jq -r '.packages[] | select(.name == "opencode-pty") | .version')"
binary="target/${{ matrix.target }}/release/opencode-pty"
output="$("$binary" --version)"
test "$output" = "opencode-pty $version (protocol $PROTOCOL_VERSION)"
runtime="$RUNNER_TEMP/opencode-pty-release-smoke"
rm -rf "$runtime"
printf 'new /bin/sh -c "printf release-smoke; sleep 1"\nwait 250\nquit\n' \
| OPENCODE_PTY_RUNTIME_DIR="$runtime" "$binary" play > "$RUNNER_TEMP/opencode-pty-release-smoke.log"
grep -q 'release-smoke' "$RUNNER_TEMP/opencode-pty-release-smoke.log"
grep -q 'checkpoint' "$RUNNER_TEMP/opencode-pty-release-smoke.log"
OPENCODE_PTY_RUNTIME_DIR="$runtime" "$binary" stop
- name: Package
run: |
version="$(cargo metadata --no-deps --format-version 1 | jq -r '.packages[] | select(.name == "opencode-pty") | .version')"
name="opencode-pty-${version}-${{ matrix.target }}"
mkdir -p "dist/$name"
cp "target/${{ matrix.target }}/release/opencode-pty" "dist/$name/"
cp LICENSE README.md "dist/$name/"
tar -C dist -czf "dist/$name.tar.gz" "$name"
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: opencode-pty-${{ matrix.target }}
path: dist/*.tar.gz
if-no-files-found: error
release:
needs: build
runs-on: ubuntu-22.04
permissions:
contents: write
id-token: write
attestations: write
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: "24"
registry-url: https://registry.npmjs.org
- name: Install npm with trusted publishing support
run: npm install --global npm@^11.5.1
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
path: dist
pattern: opencode-pty-*
merge-multiple: true
- name: Create checksums and manifest
working-directory: dist
run: |
version="${GITHUB_REF_NAME#v}"
sha256sum opencode-pty-*.tar.gz > SHA256SUMS
artifacts='[]'
while read -r sha256 archive; do
target="${archive#opencode-pty-${version}-}"
target="${target%.tar.gz}"
artifacts="$(jq --arg target "$target" --arg archive "$archive" --arg sha256 "$sha256" '. + [{target: $target, archive: $archive, sha256: $sha256}]' <<<"$artifacts")"
done < SHA256SUMS
jq -n \
--arg version "$version" \
--argjson protocol "$PROTOCOL_VERSION" \
--argjson artifacts "$artifacts" \
'{schema: 1, version: $version, protocol: $protocol, artifacts: $artifacts}' \
> release-manifest.json
sha256sum release-manifest.json >> SHA256SUMS
- name: Prepare npm packages
run: node script/npm-packages.mjs dist
- name: Validate npm packages
run: |
for package in dist/npm/*; do
npm pack --dry-run "$package" >/dev/null
done
temporary="$(mktemp -d)"
npm pack --pack-destination "$temporary" dist/npm/opencode-pty-linux-x64-gnu dist/npm/opencode-pty >/dev/null
npm install --prefix "$temporary" --ignore-scripts --no-package-lock --no-audit --no-fund "$temporary"/*.tgz
test "$("$temporary/node_modules/.bin/opencode-pty" --version)" = "opencode-pty $(node -p 'require("./npm/package.json").version') (protocol $PROTOCOL_VERSION)"
- uses: actions/attest@v4
if: startsWith(github.ref, 'refs/tags/')
with:
subject-checksums: dist/SHA256SUMS
- name: Publish release
if: startsWith(github.ref, 'refs/tags/')
env:
GH_TOKEN: ${{ github.token }}
run: |
if gh release view "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
gh release upload "$GITHUB_REF_NAME" dist/*.tar.gz dist/SHA256SUMS dist/release-manifest.json --clobber --repo "$GITHUB_REPOSITORY"
else
gh release create "$GITHUB_REF_NAME" dist/*.tar.gz dist/SHA256SUMS dist/release-manifest.json --generate-notes --repo "$GITHUB_REPOSITORY"
fi
- name: Publish npm packages
if: startsWith(github.ref, 'refs/tags/')
run: |
version="${GITHUB_REF_NAME#v}"
for package in dist/npm/opencode-pty-*; do
name="$(node -p 'require(process.argv[1]).name' "$(realpath "$package/package.json")")"
if ! npm view "$name@$version" version >/dev/null 2>&1; then
npm publish "$package" --access public --provenance
fi
done
name="@opencode-ai/pty"
if ! npm view "$name@$version" version >/dev/null 2>&1; then
npm publish dist/npm/opencode-pty --access public --provenance
fi