Merge pull request #574 from trycua/feat/cli-release-pipeline

Updated cli publish workflow to build binaries with bun bundled
This commit is contained in:
ddupont
2025-11-14 15:57:29 -05:00
committed by GitHub
4 changed files with 494 additions and 97 deletions

View File

@@ -1,43 +1,186 @@
name: Publish @trycua/cli to npm
name: Publish @trycua/cli
on:
push:
branches: main
workflow_dispatch:
inputs:
version:
description: 'Version to publish (default: from package.json)'
required: false
default: ''
jobs:
publish:
build-and-publish:
permissions:
id-token: write
contents: read
runs-on: ubuntu-latest
contents: write
packages: write
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
include:
- os: ubuntu-latest
target: bun-linux-x64
ext: ''
binary_name: cua-linux-x64
- os: macos-latest
target: bun-darwin-x64
ext: ''
binary_name: cua-darwin-x64
- os: macos-latest
target: bun-darwin-arm64
ext: ''
binary_name: cua-darwin-arm64
- os: windows-latest
target: bun-windows-x64
ext: '.exe'
binary_name: cua-windows-x64.exe
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'bun'
cache-dependency-path: 'libs/typescript/cua-cli/bun.lockb'
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Check if version changed
id: check-version
uses: EndBug/version-check@v2
with:
file-name: libs/typescript/cua-cli/package.json
diff-search: true
- name: Get version
id: version
run: |
if [ -n "${{ github.event.inputs.version }}" ]; then
echo "version=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT
else
VERSION=$(node -p "require('./libs/typescript/cua-cli/package.json').version")
echo "version=${VERSION}" >> $GITHUB_OUTPUT
fi
- name: Install dependencies
if: steps.check-version.outputs.changed == 'true'
working-directory: ./libs/typescript/cua-cli
run: bun install --frozen-lockfile
- name: Build package
if: steps.check-version.outputs.changed == 'true'
- name: Build binary
working-directory: ./libs/typescript/cua-cli
run: bun run build --if-present
run: |
bun build --compile --minify --sourcemap --target=${{ matrix.target }} dist/index.js --outfile ${{ matrix.binary_name }}
mkdir -p ../../../dist
mv ${{ matrix.binary_name }}${{ matrix.ext }}* ../../../dist/
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: cua-binaries
path: dist/
if-no-files-found: error
retention-days: 1
publish-npm:
needs: build-and-publish
if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/cua-v')
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
registry-url: 'https://registry.npmjs.org'
cache: 'bun'
cache-dependency-path: 'libs/typescript/cua-cli/bun.lockb'
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Publish to npm
if: steps.check-version.outputs.changed == 'true'
working-directory: ./libs/typescript/cua-cli
run: bun publish --access public
run: |
npm config set //registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}
npm publish --access public
create-release:
needs: [build-and-publish, publish-npm]
runs-on: ubuntu-latest
steps:
- name: Get version
id: version
run: |
VERSION=$(node -p "require('./libs/typescript/cua-cli/package.json').version")
echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "tag=cua-v${VERSION}" >> $GITHUB_OUTPUT
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
name: cua-binaries
path: dist
- name: Create Release
id: create_release
uses: actions/create-release@v2
with:
tag_name: ${{ steps.version.outputs.tag }}
release_name: CUA CLI ${{ steps.version.outputs.version }}
body: |
# CUA CLI ${{ steps.version.outputs.version }}
## Installation
### Using install script (recommended)
```bash
# For Linux/macOS
curl -fsSL https://cua.ai/install.sh | sh
# For Windows (PowerShell)
irm https://cua.ai/install.ps1 | iex
```
### Using npm/bun
```bash
# Using bun
bun add -g @trycua/cli
# Or using npm
npm install -g @trycua/cli
```
### From source
```bash
git clone -b ${{ steps.version.outputs.tag }} https://github.com/trycua/cua.git
cd cua/libs/typescript/cua-cli
bun install
bun link
bun link cua-cli
```
## Release Assets
- `cua-darwin-arm64`: macOS (Apple Silicon)
- `cua-darwin-x64`: macOS (Intel)
- `cua-linux-x64`: Linux (x86_64)
- `cua-windows-x64.exe`: Windows (x86_64)
draft: false
prerelease: false
- name: Upload Release Assets
uses: actions/upload-release-asset@v2
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./dist/${{ matrix.binary_name }}
asset_name: ${{ matrix.binary_name }}
asset_content_type: application/octet-stream
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -376,6 +376,59 @@ All packages are managed through a single consolidated workflow: [Bump Version](
5. Click "Run workflow" to start the version bump
6. The workflow will automatically commit changes and push to main
## Releasing a New CLI Version
To release a new version of the CUA CLI, follow these steps:
### 1. Update the Version
1. Update the version in `libs/typescript/cua-cli/package.json`
2. Commit the version change with a message like "Bump version to x.y.z"
3. Push the changes to the main branch
### 2. Trigger the Release Workflow
1. Go to the GitHub Actions tab in the repository
2. Select the "Publish @trycua/cli" workflow
3. Click "Run workflow"
4. Optionally, specify a version (e.g., "1.2.3") or leave empty to use the version from package.json
5. Click "Run workflow"
The workflow will:
- Build single-file executables for all supported platforms
- Publish the package to npm
- Create a GitHub release with the version tag (format: `cua-vX.Y.Z`)
- Attach all platform-specific binaries to the release
### 3. Verify the Release
1. Check the GitHub Releases page to ensure the new version is published
2. Verify the npm package was published to the registry
3. Test installation on different platforms:
```bash
# Test Linux/macOS installation
curl -fsSL https://cua.ai/install.sh | sh
# Test Windows installation (PowerShell)
irm https://cua.ai/install.ps1 | iex
```
### 4. Update Documentation
Update any relevant documentation with the new version number, including:
- Example code in documentation
- Any version-specific instructions
- Compatibility matrices
### 5. Announce the Release
- Create a new GitHub release with release notes
- Update the changelog if maintained separately
- Announce in relevant channels (Slack, Discord, etc.)
---
### Rolling Back a Version Bump
If you need to revert a version bump, follow these steps:

View File

@@ -1,65 +1,137 @@
# CUA CLI Installation Script for Windows
$ErrorActionPreference = "Stop"
Write-Host "🚀 Installing CUA CLI..." -ForegroundColor Green
# Check if bun is already installed
try {
$bunVersion = bun --version 2>$null
Write-Host "✅ Bun is already installed (version $bunVersion)" -ForegroundColor Green
} catch {
Write-Host "📦 Installing Bun..." -ForegroundColor Yellow
try {
powershell -c "irm bun.sh/install.ps1|iex"
# Refresh environment variables
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
# Add bun to PATH for this session if not already there
$bunPath = "$env:USERPROFILE\.bun\bin"
if ($env:Path -notlike "*$bunPath*") {
$env:Path = "$bunPath;$env:Path"
function Install-WithBun {
Write-Host "Installing CUA CLI using Bun..." -ForegroundColor Yellow
# Check if bun is already installed
if (-not (Get-Command bun -ErrorAction SilentlyContinue)) {
Write-Host "Installing Bun..." -ForegroundColor Yellow
try {
powershell -c "irm bun.sh/install.ps1|iex"
# Refresh environment variables
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
# Add bun to PATH for this session if not already there
$bunPath = "$env:USERPROFILE\.bun\bin"
if ($env:Path -notlike "*$bunPath*") {
$env:Path = "$bunPath;$env:Path"
}
} catch {
Write-Host "Error: Failed to install Bun. Please install manually from https://bun.sh" -ForegroundColor Red
return $false
}
} catch {
Write-Host "❌ Failed to install Bun. Please install manually from https://bun.sh" -ForegroundColor Red
exit 1
}
}
# Verify bun installation
try {
$bunVersion = bun --version 2>$null
Write-Host "✅ Bun verified (version $bunVersion)" -ForegroundColor Green
} catch {
Write-Host "❌ Bun installation failed. Please install manually from https://bun.sh" -ForegroundColor Red
exit 1
}
# Verify bun installation
if (-not (Get-Command bun -ErrorAction SilentlyContinue)) {
Write-Host "Error: Bun installation failed. Please install manually from https://bun.sh" -ForegroundColor Red
return $false
}
Write-Host "📦 Installing CUA CLI..." -ForegroundColor Yellow
try {
bun add -g @trycua/cli
} catch {
Write-Host "❌ Failed to install CUA CLI with Bun. Trying with npm..." -ForegroundColor Yellow
try {
npm install -g @trycua/cli
bun add -g @trycua/cli
return $true
} catch {
Write-Host "❌ Installation failed. Please ensure you have Node.js or Bun installed." -ForegroundColor Red
Write-Host "Warning: Failed to install with Bun, trying npm..." -ForegroundColor Yellow
try {
npm install -g @trycua/cli
return $true
} catch {
Write-Host "Error: Installation failed with npm as well." -ForegroundColor Red
return $false
}
}
}
Write-Host "Installing CUA CLI..." -ForegroundColor Green
# Determine if this is a 64-bit system
$is64Bit = [Environment]::Is64BitOperatingSystem
if (-not $is64Bit) {
Write-Host "Warning: 32-bit Windows is not supported. Falling back to Bun installation..." -ForegroundColor Yellow
if (Install-WithBun) {
exit 0
} else {
Write-Host "Error: Installation failed. Please try installing manually:" -ForegroundColor Red
Write-Host " irm https://cua.ai/install.ps1 | iex"
exit 1
}
}
# Get the latest release version
try {
$release = Invoke-RestMethod -Uri "https://api.github.com/repos/trycua/cua/releases/latest" -ErrorAction Stop
$version = $release.tag_name -replace '^cua-v', ''
# Look for the windows binary in the release assets
$windowsAsset = $release.assets | Where-Object { $_.name -eq 'cua-windows-x64.exe' }
if (-not $windowsAsset) {
throw "Windows binary not found in release assets"
}
$binaryUrl = $windowsAsset.browser_download_url
} catch {
Write-Host "Warning: Could not fetch latest release, falling back to Bun installation" -ForegroundColor Yellow
if (Install-WithBun) {
exit 0
} else {
Write-Host "Error: Installation failed. Please try installing manually:" -ForegroundColor Red
Write-Host " irm https://cua.ai/install.ps1 | iex"
exit 1
}
}
# Create installation directory
$installDir = "$env:USERPROFILE\.cua\bin"
if (-not (Test-Path $installDir)) {
New-Item -ItemType Directory -Path $installDir -Force | Out-Null
}
$binaryPath = Join-Path $installDir "cua.exe"
# Download the binary
Write-Host "Downloading CUA CLI $version for Windows x64..." -ForegroundColor Cyan
try {
Invoke-WebRequest -Uri $binaryUrl -OutFile $binaryPath -ErrorAction Stop
} catch {
Write-Host "Warning: Failed to download pre-built binary, falling back to Bun installation" -ForegroundColor Yellow
if (Install-WithBun) {
exit 0
} else {
Write-Host "Error: Installation failed. Please try installing manually:" -ForegroundColor Red
Write-Host " irm https://cua.ai/install.ps1 | iex"
exit 1
}
}
# Add to PATH if not already there
$currentPath = [Environment]::GetEnvironmentVariable("Path", "User")
if ($currentPath -notlike "*$installDir*") {
[Environment]::SetEnvironmentVariable("Path", "$currentPath;$installDir", "User")
$env:Path = "$env:Path;$installDir"
Write-Host "Success: Added $installDir to your PATH" -ForegroundColor Green
}
# Verify installation
try {
$cuaVersion = cua --version 2>$null
Write-Host "✅ CUA CLI installed successfully!" -ForegroundColor Green
if (Test-Path $binaryPath) {
Write-Host "Success: CUA CLI $version installed successfully to $binaryPath" -ForegroundColor Green
Write-Host ""
Write-Host "🎉 Get started with:" -ForegroundColor Cyan
Write-Host " cua auth login" -ForegroundColor White
Write-Host " cua vm create --os linux --configuration small --region north-america" -ForegroundColor White
Write-Host "Get started with:" -ForegroundColor Cyan
Write-Host " cua auth login"
Write-Host " cua vm create --os linux --configuration small --region north-america"
Write-Host ""
Write-Host "📚 For more help, visit: https://docs.cua.ai/libraries/cua-cli" -ForegroundColor Cyan
} catch {
Write-Host "❌ Installation verification failed. Please try installing manually:" -ForegroundColor Red
Write-Host " npm install -g @trycua/cli" -ForegroundColor White
Write-Host "For more help, visit: https://docs.cua.ai/libraries/cua-cli" -ForegroundColor Cyan
# Offer to add to PATH if not already there
if (-not ($env:Path -like "*$installDir*")) {
Write-Host ""
Write-Host "Note: Please restart your terminal or run the following command to use CUA CLI:" -ForegroundColor Yellow
Write-Host " `$env:Path += ';$installDir'"
}
} else {
Write-Host "Error: Installation failed. Please try installing manually:" -ForegroundColor Red
Write-Host " irm https://cua.ai/install.ps1 | iex"
exit 1
}
}

View File

@@ -4,44 +4,173 @@ set -e
# CUA CLI Installation Script for macOS/Linux
echo "🚀 Installing CUA CLI..."
# Check if bun is already installed
if command -v bun &> /dev/null; then
echo "✅ Bun is already installed"
else
echo "📦 Installing Bun..."
curl -fsSL https://bun.sh/install | bash
# Function to print success message
print_success() {
local bin_path="$1"
local version="$2"
local config_file="$3"
# Source the shell profile to make bun available
echo -e "\033[32m✅ CUA CLI $version was installed successfully to $bin_path\033[0m"
echo -e "\033[90mAdded \"$bin_path\" to \$PATH in \"$config_file\"\033[0m"
echo -e "\n\033[90mTo get started, run:\033[0m"
echo -e " source $config_file"
echo -e " cua --help\n"
echo -e "\033[90m📚 For more help, visit: https://docs.cua.ai/libraries/cua-cli"
}
# Function to install with bun as fallback
install_with_bun() {
echo "📦 Installing CUA CLI using Bun..."
# Check if bun is already installed
if ! command -v bun &> /dev/null; then
echo "📦 Installing Bun..."
curl -fsSL https://bun.sh/install | bash
# Source the shell profile to make bun available
if [ -f "$HOME/.bashrc" ]; then
source "$HOME/.bashrc"
elif [ -f "$HOME/.zshrc" ]; then
source "$HOME/.zshrc"
fi
# Add bun to PATH for this session
export PATH="$HOME/.bun/bin:$PATH"
fi
# Verify bun installation
if ! command -v bun &> /dev/null; then
echo "❌ Failed to install Bun. Please install manually from https://bun.sh"
exit 1
fi
echo "📦 Installing CUA CLI..."
if ! bun add -g @trycua/cli; then
echo "❌ Failed to install with Bun, trying npm..."
if ! npm install -g @trycua/cli; then
echo "❌ Installation failed. Please try installing manually:"
echo " npm install -g @trycua/cli"
exit 1
fi
fi
# Verify installation
if command -v cua &> /dev/null; then
# Determine which config file was updated
local config_file="$HOME/.bashrc"
if [ -f "$HOME/.zshrc" ]; then
config_file="$HOME/.zshrc"
elif [ -f "$HOME/.profile" ]; then
config_file="$HOME/.profile"
fi
print_success "cua" "$VERSION" "$config_file"
exit 0
else
echo "❌ Installation failed. Please try installing manually:"
echo " npm install -g @trycua/cli"
exit 1
fi
}
# Determine OS and architecture
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m)
# Map architecture to the format used in release assets
case "$ARCH" in
x86_64) ARCH="x64" ;;
aarch64) ARCH="arm64" ;;
arm64) ARCH="arm64" ;;
*) ARCH="$ARCH" ;;
esac
# Determine the binary name
BINARY_NAME="cua-${OS}-${ARCH}"
if [ "$OS" = "darwin" ] && [ "$ARCH" = "arm64" ]; then
BINARY_NAME="cua-darwin-arm64"
elif [ "$OS" = "darwin" ] && [ "$ARCH" = "x86_64" ]; then
BINARY_NAME="cua-darwin-x64"
elif [ "$OS" = "linux" ] && [ "$ARCH" = "x86_64" ]; then
BINARY_NAME="cua-linux-x64"
else
echo "⚠️ Pre-built binary not available for ${OS}-${ARCH}, falling back to Bun installation"
install_with_bun
exit 0
fi
# Get the latest release version
LATEST_RELEASE=$(curl -s https://api.github.com/repos/trycua/cua/releases/latest)
if [ -z "$LATEST_RELEASE" ]; then
echo "⚠️ Could not fetch latest release, falling back to Bun installation"
install_with_bun
exit 0
fi
# Extract version number (remove 'cua-v' prefix)
TAG_NAME=$(echo "$LATEST_RELEASE" | grep 'tag_name' | cut -d '"' -f 4)
VERSION=${TAG_NAME#cua-v}
# Find the binary URL in the release assets
BINARY_URL=$(echo "$LATEST_RELEASE" | grep -o 'https://.*/download/[^"]*/'${BINARY_NAME}'"' | head -1)
if [ -z "$BINARY_URL" ]; then
echo "⚠️ Could not find ${BINARY_NAME} in release assets, falling back to Bun installation"
install_with_bun
exit 0
fi
# Create ~/.cua/bin directory if it doesn't exist
INSTALL_DIR="$HOME/.cua/bin"
mkdir -p "$INSTALL_DIR"
# Download the binary
echo "📥 Downloading CUA CLI $VERSION for ${OS}-${ARCH}..."
if ! curl -L "$BINARY_URL" -o "$INSTALL_DIR/cua" 2>/dev/null; then
echo "⚠️ Failed to download pre-built binary, falling back to Bun installation"
install_with_bun
exit 0
fi
# Make the binary executable
chmod +x "$INSTALL_DIR/cua"
# Add ~/.cua/bin to PATH if not already in PATH
if [[ ":$PATH:" != *":$INSTALL_DIR:"* ]]; then
# Add to .bashrc, .zshrc, or .profile
if [ -f "$HOME/.bashrc" ]; then
source "$HOME/.bashrc"
elif [ -f "$HOME/.zshrc" ]; then
source "$HOME/.zshrc"
echo "export PATH=\"$INSTALL_DIR:\$PATH\"" >> "$HOME/.bashrc"
echo "Added $INSTALL_DIR to PATH in ~/.bashrc"
fi
# Add bun to PATH for this session
export PATH="$HOME/.bun/bin:$PATH"
if [ -f "$HOME/.zshrc" ]; then
echo "export PATH=\"$INSTALL_DIR:\$PATH\"" >> "$HOME/.zshrc"
echo "Added $INSTALL_DIR to PATH in ~/.zshrc"
fi
if [ -f "$HOME/.profile" ] && [ ! -f "$HOME/.bashrc" ] && [ ! -f "$HOME/.zshrc" ]; then
echo "export PATH=\"$INSTALL_DIR:\$PATH\"" >> "$HOME/.profile"
echo "Added $INSTALL_DIR to PATH in ~/.profile"
fi
# Add to current session
export PATH="$INSTALL_DIR:$PATH"
fi
# Verify bun installation
if ! command -v bun &> /dev/null; then
echo "❌ Failed to install Bun. Please install manually from https://bun.sh"
exit 1
fi
echo "📦 Installing CUA CLI..."
bun add -g @trycua/cli
# Verify installation
if command -v cua &> /dev/null; then
echo "✅ CUA CLI installed successfully!"
echo ""
echo "🎉 Get started with:"
echo " cua auth login"
echo " cua vm create --os linux --configuration small --region north-america"
echo ""
echo "📚 For more help, visit: https://docs.cua.ai/libraries/cua-cli"
# Determine which config file was updated
config_file="$HOME/.bashrc"
if [ -f "$HOME/.zshrc" ]; then
config_file="$HOME/.zshrc"
elif [ -f "$HOME/.profile" ]; then
config_file="$HOME/.profile"
fi
print_success "$(which cua)" "$VERSION" "$config_file"
exit 0
else
echo "❌ Installation failed. Please try installing manually:"
echo " npm install -g @trycua/cli"
echo " curl -fsSL https://cua.ai/install.sh | sh"
exit 1
fi