name: Release Binaries
on:
release:
types: [published]
workflow_dispatch:
inputs:
tag:
description: 'Release tag to attach binaries to'
required: true
type: string
permissions:
contents: write
jobs:
build-binaries:
name: Build ${{ matrix.name }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
# Linux x64 (glibc) - Most servers, CI environments
- os: ubuntu-latest
target: bun-linux-x64
name: octocode-mcp-linux-x64
artifact: octocode-mcp-linux-x64
# Linux ARM64 (glibc) - AWS Graviton, Raspberry Pi
- os: ubuntu-latest
target: bun-linux-arm64
name: octocode-mcp-linux-arm64
artifact: octocode-mcp-linux-arm64
# Linux x64 (musl) - Alpine Linux, minimal containers
- os: ubuntu-latest
target: bun-linux-x64-musl
name: octocode-mcp-linux-x64-musl
artifact: octocode-mcp-linux-x64-musl
# macOS ARM64 (Apple Silicon M1/M2/M3)
- os: macos-latest
target: bun-darwin-arm64
name: octocode-mcp-darwin-arm64
artifact: octocode-mcp-darwin-arm64
# macOS x64 (Intel)
- os: macos-latest
target: bun-darwin-x64
name: octocode-mcp-darwin-x64
artifact: octocode-mcp-darwin-x64
# Windows x64
- os: ubuntu-latest
target: bun-windows-x64
name: octocode-mcp-windows-x64
artifact: octocode-mcp-windows-x64.exe
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Enable Corepack
run: corepack enable
- name: Install dependencies
run: yarn install --immutable
working-directory: .
- name: Build binary
run: |
bun build ./src/index.ts \
--compile \
--minify \
--target=${{ matrix.target }} \
--outfile ${{ matrix.artifact }}
working-directory: packages/octocode-mcp
- name: Verify binary was created
run: |
ls -la ${{ matrix.artifact }}
file ${{ matrix.artifact }} || true
working-directory: packages/octocode-mcp
- name: Test binary execution
run: |
if [[ "${{ matrix.name }}" == *"windows"* ]]; then
echo "⏭️ Skipping execution test for Windows binary on Linux"
else
echo "🧪 Testing binary execution..."
./${{ matrix.artifact }} --version || echo "⚠️ Warning: Binary version check failed"
fi
working-directory: packages/octocode-mcp
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.name }}
path: packages/octocode-mcp/${{ matrix.artifact }}
retention-days: 7
build-source:
name: Build JS Source
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'
- name: Enable Corepack
run: corepack enable
- name: Install dependencies
run: yarn install --immutable
- name: Build packages
run: yarn build
- name: Upload index.js
uses: actions/upload-artifact@v4
with:
name: octocode-mcp-index.js
path: packages/octocode-mcp/dist/index.js
retention-days: 7 # Keep for a week to allow for workflow retries
upload-to-release:
name: Upload to Release
needs: [build-binaries, build-source]
runs-on: ubuntu-latest
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: binaries
merge-multiple: true
- name: List downloaded binaries
run: |
echo "Downloaded binaries:"
ls -la binaries/
- name: Get release tag
id: get_tag
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "tag=${{ inputs.tag }}" >> $GITHUB_OUTPUT
else
echo "tag=${{ github.event.release.tag_name }}" >> $GITHUB_OUTPUT
fi
- name: Upload binaries to release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.get_tag.outputs.tag }}
files: binaries/*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
create-checksums:
name: Create Checksums
needs: upload-to-release
runs-on: ubuntu-latest
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: binaries
merge-multiple: true
- name: Generate SHA256 checksums
run: |
cd binaries
echo "Generating checksums for all binaries..."
sha256sum * > checksums-sha256.txt
echo ""
echo "Checksums:"
cat checksums-sha256.txt
- name: Get release tag
id: get_tag
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "tag=${{ inputs.tag }}" >> $GITHUB_OUTPUT
else
echo "tag=${{ github.event.release.tag_name }}" >> $GITHUB_OUTPUT
fi
- name: Upload checksums to release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.get_tag.outputs.tag }}
files: binaries/checksums-sha256.txt
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
notify-discord:
name: Discord Notification
needs: [build-binaries, upload-to-release, create-checksums]
runs-on: ubuntu-latest
if: always()
steps:
- name: Send Discord notification
continue-on-error: true
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
run: |
if [ -z "$DISCORD_WEBHOOK" ]; then
echo "ℹ️ DISCORD_WEBHOOK not configured, skipping notification"
exit 0
fi
BUILD_RESULT="${{ needs.build-binaries.result }}"
UPLOAD_RESULT="${{ needs.upload-to-release.result }}"
CHECKSUM_RESULT="${{ needs.create-checksums.result }}"
if [ "$BUILD_RESULT" = "failure" ] || [ "$UPLOAD_RESULT" = "failure" ] || [ "$CHECKSUM_RESULT" = "failure" ]; then
STATUS="❌ **Binary Release Failed**"
COLOR=15158332
DESCRIPTION="Failed to build or upload binaries"
else
STATUS="🎉 **Binaries Released**"
COLOR=3066993
DESCRIPTION="Successfully built and uploaded binaries for all platforms"
fi
# Get tag
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
TAG="${{ inputs.tag }}"
else
TAG="${{ github.event.release.tag_name }}"
fi
# Escape JSON special characters to prevent injection
STATUS_ESCAPED=$(echo "$STATUS" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g')
DESCRIPTION_ESCAPED=$(echo "$DESCRIPTION" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g')
TAG_ESCAPED=$(echo "$TAG" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g')
PAYLOAD=$(cat <<EOF
{
"username": "GitHub Releases",
"avatar_url": "https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png",
"embeds": [{
"title": "📦 Octocode MCP Binary Release",
"description": "$DESCRIPTION_ESCAPED",
"color": $COLOR,
"fields": [
{"name": "Status", "value": "$STATUS_ESCAPED", "inline": true},
{"name": "Tag", "value": "\`$TAG_ESCAPED\`", "inline": true},
{"name": "Platforms", "value": "Linux x64, Linux ARM64, Alpine, macOS ARM64, macOS x64, Windows", "inline": false},
{"name": "Download", "value": "[View Release](https://github.com/${{ github.repository }}/releases/tag/$TAG)", "inline": false}
],
"footer": {"text": "GitHub Actions • $(date -u +'%Y-%m-%d %H:%M:%S UTC')"}
}]
}
EOF
)
curl -H "Content-Type: application/json" -X POST -d "$PAYLOAD" "$DISCORD_WEBHOOK" || echo "⚠️ Discord notification failed"