Skip to content

feat: add Cursor and verified OpenCode support #15

feat: add Cursor and verified OpenCode support

feat: add Cursor and verified OpenCode support #15

Workflow file for this run

name: release

Check failure on line 1 in .github/workflows/release.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/release.yml

Invalid workflow file

(Line: 132, Col: 15): Unrecognized named-value: 'runner'. Located at position 1 within expression: runner.temp
on:
push:
tags: ["v*"]
pull_request:
branches: [main]
workflow_dispatch:
permissions:
contents: read
jobs:
validate:
runs-on: ${{ vars.AGENTBOOT_LINUX_RUNNER || 'ubuntu-latest' }}
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false
- name: Validate tag and version
shell: bash
run: |
if [ "$GITHUB_REF_TYPE" = "tag" ]; then test "$GITHUB_REF_NAME" = "v$(cat VERSION)"; fi
python3 -m unittest discover -s tests -v
python3 -m py_compile core/*.py scripts/*.py scripts/tools/*.py tests/*.py
sh -n install.sh scripts/*.sh pages/install.sh cloudflare/deploy.sh
python3 scripts/sync-web-assets.py --check
node --check cloudflare/worker.js
online:
runs-on: ${{ vars.AGENTBOOT_LINUX_RUNNER || 'ubuntu-latest' }}
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false
- name: Build online packages
run: |
cp install.sh pages/install.sh
cp scripts/install.ps1 pages/install.ps1
python3 scripts/build-online.py
cp install.sh scripts/install.ps1 VERSION pages/
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: online
path: |
pages/agentboot-online-*
pages/install.sh
pages/install.ps1
pages/VERSION
offline-linux:
runs-on: ${{ vars.AGENTBOOT_LINUX_RUNNER || 'ubuntu-latest' }}
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false
- name: Build verified Codex offline package
run: AGENTS=codex PLATFORMS=linux-x64 TAG="v$(cat VERSION)" sh scripts/build-offline.sh
- name: Smoke install, execute, and uninstall
shell: bash
run: |
root="$(mktemp -d)"
mkdir -p "$root/extract" "$root/home"
tag="v$(cat VERSION)"
tar -xzf "dist/AgentBoot-offline-${tag}-linux-x64.tar.gz" -C "$root/extract"
app="$root/extract/AgentBoot"
HOME="$root/home" sh "$app/install-offline.sh" codex
AGENTBOOT_HOME="$root/home/.agentboot" HOME="$root/home" "$root/home/.agentboot/bin/codex" --version
AGENTBOOT_HOME="$root/home/.agentboot" HOME="$root/home" python3 "$root/home/.agentboot/app/core/menu.py" uninstall codex
test ! -e "$root/home/.agentboot/agents/codex"
mv "dist/AgentBoot-offline-${tag}-linux-x64.tar.gz" "dist/AgentBoot-offline-${tag}-linux-x64-codex.tar.gz"
mv "dist/AgentBoot-offline-${tag}-linux-x64-sfx.sh" "dist/AgentBoot-offline-${tag}-linux-x64-codex-sfx.sh"
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: offline-linux
path: dist/AgentBoot-offline-*-linux-x64-codex*
offline-windows:
runs-on: windows-latest
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false
- name: Build verified Codex offline package
shell: powershell
run: .\scripts\build-offline.ps1 -Tag ('v' + (Get-Content VERSION -Raw).Trim()) -Platforms win-x64 -Agents codex
- name: Smoke install, execute, and uninstall
shell: powershell
run: |
$root = Join-Path $env:RUNNER_TEMP 'agentboot-smoke'
$extract = Join-Path $root 'extract'
$smokeHome = Join-Path $root '测试-home'
New-Item -ItemType Directory -Path $extract, $smokeHome -Force | Out-Null
$tag = 'v' + (Get-Content VERSION -Raw).Trim()
tar -xf "dist\AgentBoot-offline-$tag-win-x64.zip" -C $extract
$app = Join-Path $extract 'AgentBoot'
$env:AGENTBOOT_HOME = Join-Path $smokeHome '.agentboot'
$env:USERPROFILE = $smokeHome
$env:LOCALAPPDATA = Join-Path $smokeHome 'LocalAppData'
& "$app\install-offline.ps1" -Agents codex
& "$smokeHome\.agentboot\bin\codex.cmd" --version
python "$env:LOCALAPPDATA\AgentBoot\app\core\menu.py" uninstall codex
if (Test-Path "$smokeHome\.agentboot\agents\codex") { throw 'Codex payload not removed' }
Move-Item "dist\AgentBoot-offline-$tag-win-x64.zip" "dist\AgentBoot-offline-$tag-win-x64-codex.zip"
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: offline-windows
path: dist/AgentBoot-offline-*-win-x64-codex.zip
macos-smoke:
runs-on: macos-15-intel
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false
- name: Build and smoke native macOS Codex package
shell: bash
run: |
AGENTS=codex PLATFORMS=darwin-x64 TAG="v$(cat VERSION)" sh scripts/build-offline.sh
root="$(mktemp -d)"
mkdir -p "$root/extract" "$root/home"
tag="v$(cat VERSION)"
tar -xzf "dist/AgentBoot-offline-${tag}-darwin-x64.tar.gz" -C "$root/extract"
HOME="$root/home" sh "$root/extract/AgentBoot/install-offline.sh" codex
HOME="$root/home" AGENTBOOT_HOME="$root/home/.agentboot" "$root/home/.agentboot/bin/codex" --version
HOME="$root/home" AGENTBOOT_HOME="$root/home/.agentboot" python3 "$root/home/.agentboot/app/core/menu.py" uninstall codex
test ! -e "$root/home/.agentboot/agents/codex"
extended-linux:
runs-on: ${{ vars.AGENTBOOT_LINUX_RUNNER || 'ubuntu-latest' }}
env:
TMPDIR: ${{ runner.temp }}
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false
- name: Build and smoke OpenCode Linux offline package
shell: bash
run: |
AGENTS=opencode PLATFORMS=linux-x64 TAG="v$(cat VERSION)" sh scripts/build-offline.sh
root="$(mktemp -d)"
mkdir -p "$root/extract" "$root/home"
tag="v$(cat VERSION)"
tar -xzf "dist/AgentBoot-offline-${tag}-linux-x64.tar.gz" -C "$root/extract"
app="$root/extract/AgentBoot"
HOME="$root/home" sh "$app/install-offline.sh" opencode
HOME="$root/home" AGENTBOOT_HOME="$root/home/.agentboot" "$root/home/.agentboot/bin/opencode" --version
HOME="$root/home" AGENTBOOT_HOME="$root/home/.agentboot" python3 "$root/home/.agentboot/app/core/menu.py" uninstall opencode
test ! -e "$root/home/.agentboot/agents/opencode"
test -f "$root/home/.config/opencode/opencode.json"
mv "dist/AgentBoot-offline-${tag}-linux-x64.tar.gz" "dist/AgentBoot-offline-${tag}-linux-x64-opencode.tar.gz"
mv "dist/AgentBoot-offline-${tag}-linux-x64-sfx.sh" "dist/AgentBoot-offline-${tag}-linux-x64-opencode-sfx.sh"
- name: Install verify and uninstall official Cursor AppImage
shell: bash
run: |
root="$(mktemp -d)"
HOME="$root" AGENTBOOT_HOME="$root/.agentboot" python3 core/menu.py install cursor
HOME="$root" "$root/.agentboot/apps/cursor/Cursor.AppImage" --appimage-version
HOME="$root" AGENTBOOT_HOME="$root/.agentboot" python3 core/menu.py uninstall cursor
test ! -e "$root/.agentboot/apps/cursor"
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: extended-linux
path: dist/AgentBoot-offline-*-linux-x64-opencode*
extended-windows:
runs-on: windows-latest
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false
- name: Build and smoke OpenCode Windows offline package
shell: powershell
run: |
$tag = 'v' + (Get-Content VERSION -Raw).Trim()
.\scripts\build-offline.ps1 -Tag $tag -Platforms win-x64 -Agents opencode
$root = Join-Path $env:RUNNER_TEMP 'opencode-smoke'
$extract = Join-Path $root 'extract'
$opencodeHome = Join-Path $root 'home'
New-Item -ItemType Directory -Path $extract, $opencodeHome -Force | Out-Null
tar -xf "dist\AgentBoot-offline-$tag-win-x64.zip" -C $extract
$app = Join-Path $extract 'AgentBoot'
$env:AGENTBOOT_HOME = Join-Path $opencodeHome '.agentboot'
$env:USERPROFILE = $opencodeHome
$env:LOCALAPPDATA = Join-Path $opencodeHome 'LocalAppData'
& "$app\install-offline.ps1" -Agents opencode
& "$opencodeHome\.agentboot\bin\opencode.cmd" --version
python "$env:LOCALAPPDATA\AgentBoot\app\core\menu.py" uninstall opencode
if (Test-Path "$opencodeHome\.agentboot\agents\opencode") { throw 'OpenCode payload not removed' }
if (-not (Test-Path "$opencodeHome\.config\opencode\opencode.json")) { throw 'OpenCode config was not preserved' }
Move-Item "dist\AgentBoot-offline-$tag-win-x64.zip" "dist\AgentBoot-offline-$tag-win-x64-opencode.zip"
- name: Install verify and uninstall official Cursor user app
shell: powershell
run: |
$root = Join-Path $env:RUNNER_TEMP 'cursor-smoke'
New-Item -ItemType Directory -Path $root -Force | Out-Null
$env:AGENTBOOT_HOME = Join-Path $root '.agentboot'
$env:USERPROFILE = $root
python core/menu.py install cursor
$exe = Join-Path $root '.agentboot\apps\cursor\Cursor.exe'
if (-not (Test-Path $exe)) { throw 'Cursor.exe missing' }
$signature = Get-AuthenticodeSignature -LiteralPath $exe
if ($signature.Status -ne 'Valid') { throw 'Cursor.exe signature invalid' }
python core/menu.py uninstall cursor
if (Test-Path (Join-Path $root '.agentboot\apps\cursor')) { throw 'Cursor managed app not removed' }
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: extended-windows
path: dist/AgentBoot-offline-*-win-x64-opencode.zip
extended-macos-x64:
runs-on: macos-15-intel
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false
- name: Build and smoke OpenCode plus Cursor on Intel macOS
shell: bash
run: |
AGENTS=opencode PLATFORMS=darwin-x64 TAG="v$(cat VERSION)" sh scripts/build-offline.sh
root="$(mktemp -d)"; mkdir -p "$root/extract" "$root/home"
tag="v$(cat VERSION)"; tar -xzf "dist/AgentBoot-offline-${tag}-darwin-x64.tar.gz" -C "$root/extract"
HOME="$root/home" sh "$root/extract/AgentBoot/install-offline.sh" opencode
HOME="$root/home" AGENTBOOT_HOME="$root/home/.agentboot" "$root/home/.agentboot/bin/opencode" --version
HOME="$root/home" AGENTBOOT_HOME="$root/home/.agentboot" python3 "$root/home/.agentboot/app/core/menu.py" uninstall opencode
HOME="$root/home" AGENTBOOT_HOME="$root/home/.agentboot" python3 core/menu.py install cursor
test -d "$root/home/.agentboot/apps/cursor/Cursor.app"
HOME="$root/home" AGENTBOOT_HOME="$root/home/.agentboot" python3 core/menu.py uninstall cursor
test ! -e "$root/home/.agentboot/apps/cursor"
mv "dist/AgentBoot-offline-${tag}-darwin-x64.tar.gz" "dist/AgentBoot-offline-${tag}-darwin-x64-opencode.tar.gz"
mv "dist/AgentBoot-offline-${tag}-darwin-x64-sfx.sh" "dist/AgentBoot-offline-${tag}-darwin-x64-opencode-sfx.sh"
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: extended-macos-x64
path: dist/AgentBoot-offline-*-darwin-x64-opencode*
extended-macos-arm64:
runs-on: macos-15
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false
- name: Build and smoke OpenCode plus Cursor on Apple Silicon
shell: bash
run: |
test "$(uname -m)" = arm64
AGENTS=opencode PLATFORMS=darwin-arm64 TAG="v$(cat VERSION)" sh scripts/build-offline.sh
root="$(mktemp -d)"; mkdir -p "$root/extract" "$root/home"
tag="v$(cat VERSION)"; tar -xzf "dist/AgentBoot-offline-${tag}-darwin-arm64.tar.gz" -C "$root/extract"
HOME="$root/home" sh "$root/extract/AgentBoot/install-offline.sh" opencode
HOME="$root/home" AGENTBOOT_HOME="$root/home/.agentboot" "$root/home/.agentboot/bin/opencode" --version
HOME="$root/home" AGENTBOOT_HOME="$root/home/.agentboot" python3 "$root/home/.agentboot/app/core/menu.py" uninstall opencode
HOME="$root/home" AGENTBOOT_HOME="$root/home/.agentboot" python3 core/menu.py install cursor
test -d "$root/home/.agentboot/apps/cursor/Cursor.app"
HOME="$root/home" AGENTBOOT_HOME="$root/home/.agentboot" python3 core/menu.py uninstall cursor
test ! -e "$root/home/.agentboot/apps/cursor"
mv "dist/AgentBoot-offline-${tag}-darwin-arm64.tar.gz" "dist/AgentBoot-offline-${tag}-darwin-arm64-opencode.tar.gz"
mv "dist/AgentBoot-offline-${tag}-darwin-arm64-sfx.sh" "dist/AgentBoot-offline-${tag}-darwin-arm64-opencode-sfx.sh"
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: extended-macos-arm64
path: dist/AgentBoot-offline-*-darwin-arm64-opencode*
publish:
needs: [validate, online, offline-linux, offline-windows, macos-smoke, extended-linux, extended-windows, extended-macos-x64, extended-macos-arm64]
if: github.ref_type == 'tag'
runs-on: ${{ vars.AGENTBOOT_LINUX_RUNNER || 'ubuntu-latest' }}
environment: release-production
permissions:
contents: write
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
path: release
merge-multiple: true
- name: Generate checksums
run: (cd release && find . -maxdepth 1 -type f ! -name SHA256SUMS.txt -print0 | sort -z | xargs -0 sha256sum > SHA256SUMS.txt)
- name: Publish GitHub Release
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" release/* --repo "$GITHUB_REPOSITORY" --clobber
gh release edit "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" --prerelease --latest=false
else
gh release create "$GITHUB_REF_NAME" release/* \
--repo "$GITHUB_REPOSITORY" \
--title "AgentBoot $GITHUB_REF_NAME" \
--prerelease \
--generate-notes \
--verify-tag
fi
- name: Wait for Pages deployment
env:
GH_TOKEN: ${{ github.token }}
run: |
for attempt in $(seq 1 30); do
row=$(gh run list --repo "$GITHUB_REPOSITORY" --workflow deploy-pages --branch main --limit 10 \
--json headSha,conclusion,status -q ".[] | select(.headSha == \"$GITHUB_SHA\") | [.status,.conclusion] | @tsv" | head -n 1)
status=$(printf '%s' "$row" | cut -f1)
conclusion=$(printf '%s' "$row" | cut -f2)
[ "$status" = completed ] && [ "$conclusion" = success ] && exit 0
[ "$status" = completed ] && [ "$conclusion" = failure ] && exit 1
sleep 10
done
exit 1
- name: Wait for primary and mirror endpoints
run: |
for attempt in $(seq 1 60); do
python3 scripts/verify-live-release.py && exit 0
sleep 10
done
exit 1
- name: Promote verified release
env:
GH_TOKEN: ${{ github.token }}
run: gh release edit "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" --prerelease=false --latest