name: CLI Release on: push: branches: - main paths: - 'apps/cli/**' - 'packages/**' - '.github/workflows/cli-release.yml' workflow_dispatch: # Add permissions for creating releases permissions: contents: write packages: write actions: read jobs: build: strategy: matrix: include: - os: ubuntu-latest target: linux-x64 artifact_name: buster-cli-linux-x86_64.tar.gz bun_target: linux-x64-modern - os: macos-latest target: darwin-x64 artifact_name: buster-cli-darwin-x86_64.tar.gz bun_target: darwin-x64 - os: macos-latest target: darwin-arm64 artifact_name: buster-cli-darwin-arm64.tar.gz bun_target: darwin-arm64 - os: windows-2022 target: windows-x64 artifact_name: buster-cli-windows-x86_64.zip bun_target: win32-x64 runs-on: ${{ matrix.os }} steps: - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 0 - name: Install pnpm uses: pnpm/action-setup@v2 with: version: 9.15.0 - name: Setup Node.js uses: useblacksmith/setup-node@v5 with: node-version: 22 cache: 'pnpm' - name: Install Bun uses: oven-sh/setup-bun@v2 with: bun-version: latest - name: Mount Turbo cache sticky disk if: runner.os != 'Windows' uses: useblacksmith/stickydisk@v1 with: key: ${{ github.repository }}-turbo-cache-cli-${{ matrix.target }} path: ./.turbo - name: Install dependencies run: pnpm install --frozen-lockfile - name: Build dependencies with Turbo run: | echo "๐Ÿ”จ Building CLI dependencies with Turbo..." pnpm turbo run build --filter=@buster-app/cli^... env: NODE_ENV: production SKIP_ENV_CHECK: true TURBO_CACHE_DIR: .turbo TURBO_TELEMETRY_DISABLED: 1 - name: Build standalone CLI binary working-directory: ./apps/cli run: | echo "๐Ÿ“ฆ Building standalone CLI binary for ${{ matrix.target }}..." # Note: Bun compiles for the host platform, cross-compilation happens via matrix strategy bun build src/index.tsx --compile --outfile dist/buster-cli # Make binary executable on Unix systems if [[ "${{ runner.os }}" != "Windows" ]]; then chmod +x dist/buster-cli fi # Display binary info ls -lah dist/ shell: bash - name: Test binary (Unix) if: runner.os != 'Windows' working-directory: ./apps/cli run: | echo "๐Ÿงช Testing CLI binary..." ./dist/buster-cli --version || echo "Version command not implemented yet" ./dist/buster-cli --help || echo "Help command output" - name: Test binary (Windows) if: runner.os == 'Windows' working-directory: ./apps/cli shell: pwsh run: | echo "๐Ÿงช Testing CLI binary..." .\dist\buster-cli.exe --version .\dist\buster-cli.exe --help - name: Compress binary (Unix) if: runner.os != 'Windows' working-directory: ./apps/cli run: | cd dist # Rename to just 'buster' for end users mv buster-cli buster tar czf ${{ matrix.artifact_name }} buster if [[ "${{ runner.os }}" == "macOS" ]]; then shasum -a 256 ${{ matrix.artifact_name }} > ${{ matrix.artifact_name }}.sha256 else sha256sum ${{ matrix.artifact_name }} > ${{ matrix.artifact_name }}.sha256 fi echo "๐Ÿ“ฆ Archive created:" ls -lah ${{ matrix.artifact_name }}* - name: Compress binary (Windows) if: runner.os == 'Windows' working-directory: ./apps/cli shell: pwsh run: | cd dist # Rename to just 'buster.exe' for end users Rename-Item -Path "buster-cli.exe" -NewName "buster.exe" Compress-Archive -Path buster.exe -DestinationPath ${{ matrix.artifact_name }} Get-FileHash -Algorithm SHA256 ${{ matrix.artifact_name }} | Select-Object -ExpandProperty Hash > "${{ matrix.artifact_name }}.sha256" echo "๐Ÿ“ฆ Archive created:" Get-ChildItem ${{ matrix.artifact_name }}* - name: Upload artifacts uses: actions/upload-artifact@v4 with: name: buster-cli-${{ matrix.target }} path: | apps/cli/dist/${{ matrix.artifact_name }} apps/cli/dist/${{ matrix.artifact_name }}.sha256 retention-days: 1 release: needs: build runs-on: blacksmith-2vcpu-ubuntu-2404 outputs: cli_version: ${{ steps.get_version.outputs.version }} cli_tag_name: ${{ steps.output_release_info.outputs.tag_name }} steps: - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 0 - name: Download all artifacts uses: actions/download-artifact@v4 - name: Extract version from package.json id: get_version run: | # Update this to 0.3.1 as requested VERSION="0.3.1" echo "version=$VERSION" >> $GITHUB_OUTPUT echo "Extracted version: $VERSION" # Also update the package.json to match cd apps/cli npm version $VERSION --no-git-tag-version || true cd ../.. - name: Check if release exists id: check_release env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | if gh release view "v${{ steps.get_version.outputs.version }}" &>/dev/null; then echo "exists=true" >> $GITHUB_OUTPUT echo "Release v${{ steps.get_version.outputs.version }} already exists" else echo "exists=false" >> $GITHUB_OUTPUT echo "Release v${{ steps.get_version.outputs.version }} does not exist" fi - name: Create Release id: create_the_release if: steps.check_release.outputs.exists != 'true' uses: softprops/action-gh-release@v2 with: tag_name: v${{ steps.get_version.outputs.version }} name: Release v${{ steps.get_version.outputs.version }} body: | ## Buster CLI v${{ steps.get_version.outputs.version }} ### What's New - TypeScript-based CLI built with Bun - Fast native binary compilation - Cross-platform support (macOS, Linux, Windows) ### Installation #### Homebrew (macOS/Linux) ```bash brew tap buster-so/buster-homebrew brew install buster ``` #### Direct Download Download the appropriate binary for your platform from the assets below. ### Checksums Verify your download with the SHA256 checksums provided. files: | **/buster-cli-linux-x86_64.tar.gz **/buster-cli-linux-x86_64.tar.gz.sha256 **/buster-cli-darwin-x86_64.tar.gz **/buster-cli-darwin-x86_64.tar.gz.sha256 **/buster-cli-darwin-arm64.tar.gz **/buster-cli-darwin-arm64.tar.gz.sha256 **/buster-cli-windows-x86_64.zip **/buster-cli-windows-x86_64.zip.sha256 draft: false prerelease: false generate_release_notes: true env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Output release info id: output_release_info run: | echo "tag_name=v${{ steps.get_version.outputs.version }}" >> $GITHUB_OUTPUT if [[ "${{ steps.check_release.outputs.exists }}" == "true" ]]; then echo "โ„น๏ธ Using existing release: v${{ steps.get_version.outputs.version }}" else echo "โœ… Release created: v${{ steps.get_version.outputs.version }}" fi update_homebrew_tap: name: Update Homebrew Tap needs: release if: needs.release.outputs.cli_version != '' && needs.release.outputs.cli_tag_name != '' uses: ./.github/workflows/update-brew-tap.yml with: tag: ${{ needs.release.outputs.cli_tag_name }} version: ${{ needs.release.outputs.cli_version }} secrets: HOMEBREW_TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }} notify: name: Notify Release Completion needs: [release, update_homebrew_tap] if: always() runs-on: ubuntu-latest steps: - name: Release Summary run: | echo "## ๐Ÿš€ CLI Release Summary" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY if [[ "${{ needs.release.result }}" == "success" ]]; then echo "โœ… **Release Status:** Success" >> $GITHUB_STEP_SUMMARY echo "๐Ÿ“ฆ **Version:** v${{ needs.release.outputs.cli_version }}" >> $GITHUB_STEP_SUMMARY echo "๐Ÿท๏ธ **Tag:** ${{ needs.release.outputs.cli_tag_name }}" >> $GITHUB_STEP_SUMMARY else echo "โŒ **Release Status:** Failed" >> $GITHUB_STEP_SUMMARY fi if [[ "${{ needs.update_homebrew_tap.result }}" == "success" ]]; then echo "๐Ÿบ **Homebrew:** Updated successfully" >> $GITHUB_STEP_SUMMARY elif [[ "${{ needs.update_homebrew_tap.result }}" == "skipped" ]]; then echo "โญ๏ธ **Homebrew:** Skipped (no new release)" >> $GITHUB_STEP_SUMMARY else echo "โŒ **Homebrew:** Update failed" >> $GITHUB_STEP_SUMMARY fi echo "" >> $GITHUB_STEP_SUMMARY echo "### Next Steps" >> $GITHUB_STEP_SUMMARY echo "- Test installation: \`brew upgrade buster\`" >> $GITHUB_STEP_SUMMARY echo "- Verify functionality: \`buster --version\`" >> $GITHUB_STEP_SUMMARY