Add demo GIF showing TerminusAI build command example #32
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: 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' }} |