Skip to content

Add demo GIF showing TerminusAI build command example #32

Add demo GIF showing TerminusAI build command example

Add demo GIF showing TerminusAI build command example #32

Workflow file for this run

name: Build and Release Installers
on:
push:
tags:
- 'v*'
- '[0-9]+.[0-9]+.[0-9]+'
workflow_dispatch:
inputs:
version:
description: 'Version to build (e.g., 1.0.3 or v1.0.3)'
required: true
type: string
permissions:
contents: write
jobs:
build-windows:
name: Build Windows Installer
runs-on: windows-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.21'
- name: Build Windows binary
run: |
go mod tidy
# Install goversioninfo for Windows version metadata
go install github.com/josephspurrier/goversioninfo/cmd/goversioninfo@latest
# Extract version number from tag (remove 'v' prefix)
$VERSION = "${{ github.ref_name }}" -replace '^v', ''
$VERSION_PARTS = $VERSION -split '\.'
$MAJOR = if ($VERSION_PARTS.Length -gt 0) { $VERSION_PARTS[0] } else { "1" }
$MINOR = if ($VERSION_PARTS.Length -gt 1) { $VERSION_PARTS[1] } else { "0" }
$PATCH = if ($VERSION_PARTS.Length -gt 2) { $VERSION_PARTS[2] } else { "0" }
$BUILD = "0"
# Create versioninfo.json with format expected by goversioninfo
$versionInfo = @{
FixedFileInfo = @{
FileVersion = @{
Major = [int]$MAJOR
Minor = [int]$MINOR
Patch = [int]$PATCH
Build = [int]$BUILD
}
ProductVersion = @{
Major = [int]$MAJOR
Minor = [int]$MINOR
Patch = [int]$PATCH
Build = [int]$BUILD
}
FileFlagsMask = "3f"
FileFlags = "00"
FileOS = "040004"
FileType = "01"
FileSubType = "00"
}
StringFileInfo = @{
Comments = "TerminusAI CLI agent"
CompanyName = "TerminusAI"
FileDescription = "CLI AI agent that understands and executes tasks with your approval"
FileVersion = "$MAJOR.$MINOR.$PATCH.$BUILD"
InternalName = "terminusai"
LegalCopyright = "Copyright © 2024 TerminusAI"
LegalTrademarks = ""
OriginalFilename = "terminusai.exe"
PrivateBuild = ""
ProductName = "TerminusAI"
ProductVersion = "$MAJOR.$MINOR.$PATCH.$BUILD"
SpecialBuild = ""
}
VarFileInfo = @{
Translation = @{
LangID = "0409"
CharsetID = "04B0"
}
}
}
$versionInfo | ConvertTo-Json -Depth 10 | Set-Content versioninfo.json
# Debug: Show the generated versioninfo.json
Write-Host "Generated versioninfo.json:"
Get-Content versioninfo.json
# Generate version resource in the correct directory
goversioninfo -64=true
# Move resource.syso to cmd/terminusai directory where main.go is located
if (Test-Path "resource.syso") {
Move-Item "resource.syso" "cmd\terminusai\resource.syso" -Force
Write-Host "✓ resource.syso moved to cmd/terminusai directory"
$resourceSize = (Get-Item "cmd\terminusai\resource.syso").Length
Write-Host "Resource file size: $resourceSize bytes"
} else {
Write-Host "✗ resource.syso not found - version info may not be embedded"
}
# Extract version without 'v' prefix for build flags
$VERSION_NO_V = $VERSION
# Build with version info
go build -ldflags "-X 'terminusai/cmd/terminusai/commands.Version=$VERSION_NO_V' -X 'terminusai/cmd/terminusai/commands.BuildVersion=$VERSION_NO_V'" -o terminusai.exe ./cmd/terminusai
- name: Sign Windows binary
if: ${{ vars.ENABLE_SIGNING == 'true' }}
uses: dlemstra/code-sign-action@v1
with:
certificate: '${{ secrets.CERTIFICATE_BASE64 }}'
folder: '.'
recursive: false
files: |
terminusai.exe
- name: Build Windows Installer
run: |
# Extract version number from tag (remove 'v' prefix)
$VERSION = "${{ github.ref_name }}" -replace '^v', ''
# Build installer with correct version
& "C:\Program Files (x86)\Inno Setup 6\ISCC.exe" "build\terminusai.iss" "/O+" "/DMyAppVersion=$VERSION"
- name: Sign Windows Installer
if: ${{ vars.ENABLE_SIGNING == 'true' }}
uses: dlemstra/code-sign-action@v1
with:
certificate: '${{ secrets.CERTIFICATE_BASE64 }}'
folder: 'build/Output'
recursive: false
files: |
*.exe
- name: Upload Windows Installer
uses: actions/upload-artifact@v4
with:
name: terminusai-windows-installer
path: build/Output/terminusai-setup.exe
build-macos:
name: Build macOS Binary
runs-on: macos-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.21'
- name: Build macOS universal binary
run: |
go mod tidy
# Extract version for metadata
VERSION="${{ github.ref_name }}"
VERSION_NO_V="${VERSION#v}"
# Enhanced build flags with version metadata
BUILD_FLAGS="-X 'terminusai/cmd/terminusai/commands.Version=$VERSION' -X 'terminusai/cmd/terminusai/commands.BuildVersion=$VERSION_NO_V' -X 'terminusai/cmd/terminusai/commands.BuildDate=$(date -u +%Y-%m-%dT%H:%M:%SZ)'"
# Build for Intel Macs
GOOS=darwin GOARCH=amd64 go build -ldflags "$BUILD_FLAGS" -o terminusai-amd64 ./cmd/terminusai
# Build for Apple Silicon
GOOS=darwin GOARCH=arm64 go build -ldflags "$BUILD_FLAGS" -o terminusai-arm64 ./cmd/terminusai
# Create universal binary
lipo -create -output terminusai-macos-universal terminusai-amd64 terminusai-arm64
# Set extended attributes for version info (macOS specific)
xattr -w com.apple.metadata:kMDItemVersion "$VERSION_NO_V" terminusai-macos-universal
xattr -w com.apple.metadata:kMDItemCopyright "Copyright © 2024 TerminusAI" terminusai-macos-universal
# macOS signing disabled - requires Apple Developer certificate
# - name: Sign macOS binary
# if: ${{ vars.ENABLE_SIGNING == 'true' && secrets.APPLE_CERTIFICATE_BASE64 != '' }}
# run: |
# echo "macOS signing requires Apple Developer certificate - skipped"
- name: Upload macOS Binary
uses: actions/upload-artifact@v4
with:
name: terminusai-macos-binary
path: terminusai-macos-universal
build-linux:
name: Build Linux Binary
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.21'
- name: Build Linux binary
run: |
go mod tidy
# Extract version for metadata
VERSION="${{ github.ref_name }}"
VERSION_NO_V="${VERSION#v}"
BUILD_DATE=$(date -u +%Y-%m-%dT%H:%M:%SZ)
# Enhanced build flags with version metadata and ELF section
BUILD_FLAGS="-X 'terminusai/cmd/terminusai/commands.Version=$VERSION' -X 'terminusai/cmd/terminusai/commands.BuildVersion=$VERSION_NO_V' -X 'terminusai/cmd/terminusai/commands.BuildDate=$BUILD_DATE' -s -w"
# Build Linux binary with version metadata
GOOS=linux GOARCH=amd64 go build -ldflags "$BUILD_FLAGS" -o terminusai-linux-amd64 ./cmd/terminusai
# Add version info to ELF binary using objcopy
echo "TerminusAI $VERSION_NO_V" > version.txt
echo "Build Date: $BUILD_DATE" >> version.txt
echo "Copyright © 2024 TerminusAI" >> version.txt
objcopy --add-section .version=version.txt terminusai-linux-amd64
rm version.txt
- name: Create Linux binary checksum and metadata
run: |
# Create SHA256 checksum for integrity verification
sha256sum terminusai-linux-amd64 > terminusai-linux-amd64.sha256
# Create metadata file with build information
cat > terminusai-linux-amd64.info << EOF
Binary: terminusai-linux-amd64
Version: ${{ github.ref_name }}
Architecture: linux/amd64
Build Date: $(date -u +%Y-%m-%dT%H:%M:%SZ)
Repository: ${{ github.repository }}
Commit: ${{ github.sha }}
EOF
echo "Linux binary checksum and metadata created:"
cat terminusai-linux-amd64.sha256
cat terminusai-linux-amd64.info
- name: Upload Linux Binary
uses: actions/upload-artifact@v4
with:
name: terminusai-linux-binary
path: |
terminusai-linux-amd64
terminusai-linux-amd64.sha256
terminusai-linux-amd64.info
create-release:
name: Create GitHub Release
needs: [build-windows, build-macos, build-linux]
runs-on: ubuntu-latest
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Download all artifacts
uses: actions/download-artifact@v4
- name: Extract version changelog
id: changelog
run: |
# Extract version number from tag (remove 'v' prefix)
VERSION="${{ github.ref_name }}"
VERSION_NO_V="${VERSION#v}"
# Extract changelog for this version from CHANGELOG.md
echo "Extracting changelog for version $VERSION_NO_V"
# Use awk to extract the section for this version
CHANGELOG_CONTENT=$(awk "
/^## \[$VERSION_NO_V\]/ { found=1; next }
/^## \[/ && found { exit }
found && /^$/ { if (content) print \"\" }
found && !/^$/ { content=1; print }
" CHANGELOG.md)
# If no specific version found, fall back to auto-generated notes
if [ -z "$CHANGELOG_CONTENT" ]; then
echo "No changelog found for version $VERSION_NO_V, using auto-generated notes"
echo "use_generated_notes=true" >> $GITHUB_OUTPUT
else
echo "Found changelog for version $VERSION_NO_V"
echo "use_generated_notes=false" >> $GITHUB_OUTPUT
# Save changelog to file for use in release
echo "$CHANGELOG_CONTENT" > version_changelog.md
echo "Changelog content:"
cat version_changelog.md
fi
- name: Create Release
uses: softprops/action-gh-release@v2
with:
files: |
terminusai-windows-installer/terminusai-setup.exe
terminusai-macos-binary/terminusai-macos-universal
terminusai-linux-binary/terminusai-linux-amd64
terminusai-linux-binary/terminusai-linux-amd64.sha256
terminusai-linux-binary/terminusai-linux-amd64.info
body_path: ${{ steps.changelog.outputs.use_generated_notes == 'true' && '' || 'version_changelog.md' }}
generate_release_notes: ${{ steps.changelog.outputs.use_generated_notes == 'true' }}