Skip to content

Commit 747ae0f

Browse files
authored
🤖 Add release workflow for automated binary publishing (#168)
## Summary Adds automated release workflow that builds and publishes macOS and Linux binaries when a GitHub release is published. ## Release Process 1. **Bump version** in (e.g., → ) 2. **Commit and push** the version change to main 3. **Create a draft release** on GitHub with a tag (e.g., ) and write release notes 4. **Publish the draft release** → triggers the workflow 5. **Wait for builds** (~10-15 minutes) - binaries are automatically attached to the release ## Changes - **** - New workflow triggered on `release: published` - Builds macOS (x64 + arm64 DMGs) - Builds Linux (AppImage) - Uses `--publish always` to attach artifacts to GitHub release - **** - Configure electron-builder to publish to GitHub releases - **** - Document release process and workflow maintenance ## DRY Approach The release workflow reuses the same build setup as : - Same dependency installation steps - Same build process - Same code signing configuration **Key difference:** uses for PR verification, while uses with to attach binaries to releases. ## Testing This can be tested by: 1. Merging this PR 2. Creating a test release (can be deleted after) 3. Verifying binaries are attached after workflow completes _Generated with `cmux`_
1 parent f7add05 commit 747ae0f

File tree

5 files changed

+121
-35
lines changed

5 files changed

+121
-35
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
name: 'Setup cmux build environment'
2+
description: 'Setup Bun and install dependencies'
3+
runs:
4+
using: "composite"
5+
steps:
6+
- name: Setup Bun
7+
uses: oven-sh/setup-bun@v2
8+
with:
9+
bun-version: latest
10+
11+
- name: Install dependencies
12+
run: bun install --frozen-lockfile
13+
shell: bash

.github/workflows/build.yml

Lines changed: 12 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -14,42 +14,25 @@ jobs:
1414
- name: Checkout code
1515
uses: actions/checkout@v4
1616

17-
- name: Setup Bun
18-
uses: oven-sh/setup-bun@v2
19-
with:
20-
bun-version: latest
21-
22-
- name: Install dependencies
23-
run: bun install --frozen-lockfile
17+
- uses: ./.github/actions/setup-cmux
2418

2519
- name: Install ImageMagick
2620
run: brew install imagemagick
2721

2822
- name: Build application
2923
run: bun run build
3024

31-
- name: Package for macOS
32-
run: |
33-
# Decode certificate to file to avoid issues with newlines in base64 string
34-
if [ -n "${{ secrets.MACOS_CERTIFICATE }}" ]; then
35-
echo "${{ secrets.MACOS_CERTIFICATE }}" | base64 -D > /tmp/certificate.p12
36-
export CSC_LINK="/tmp/certificate.p12"
37-
export CSC_KEY_PASSWORD="${{ secrets.MACOS_CERTIFICATE_PWD }}"
38-
fi
39-
40-
# Notarization credentials (optional - will skip if not provided)
41-
if [ -n "${{ secrets.AC_APIKEY_ID }}" ]; then
42-
# Decode API key to file
43-
echo "${{ secrets.AC_APIKEY_P8_BASE64 }}" | base64 -D > /tmp/AuthKey.p8
44-
export APPLE_API_KEY="/tmp/AuthKey.p8"
45-
export APPLE_API_KEY_ID="${{ secrets.AC_APIKEY_ID }}"
46-
export APPLE_API_ISSUER="${{ secrets.AC_APIKEY_ISSUER_ID }}"
47-
echo "✅ Notarization credentials found (API key) - will notarize"
48-
else
49-
echo "⚠️ No notarization credentials - skipping notarization"
50-
fi
25+
- name: Setup code signing
26+
run: ./scripts/setup-macos-signing.sh
27+
env:
28+
MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
29+
MACOS_CERTIFICATE_PWD: ${{ secrets.MACOS_CERTIFICATE_PWD }}
30+
AC_APIKEY_P8_BASE64: ${{ secrets.AC_APIKEY_P8_BASE64 }}
31+
AC_APIKEY_ID: ${{ secrets.AC_APIKEY_ID }}
32+
AC_APIKEY_ISSUER_ID: ${{ secrets.AC_APIKEY_ISSUER_ID }}
5133

52-
make dist-mac
34+
- name: Package for macOS
35+
run: make dist-mac
5336

5437
- name: Upload macOS DMG (x64)
5538
uses: actions/upload-artifact@v4
@@ -74,13 +57,7 @@ jobs:
7457
- name: Checkout code
7558
uses: actions/checkout@v4
7659

77-
- name: Setup Bun
78-
uses: oven-sh/setup-bun@v2
79-
with:
80-
bun-version: latest
81-
82-
- name: Install dependencies
83-
run: bun install --frozen-lockfile
60+
- uses: ./.github/actions/setup-cmux
8461

8562
- name: Install ImageMagick
8663
run: sudo apt-get update && sudo apt-get install -y imagemagick

.github/workflows/release.yml

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
name: Release
2+
3+
on:
4+
release:
5+
types: [published]
6+
7+
permissions:
8+
contents: write # Required for electron-builder to upload release assets
9+
10+
jobs:
11+
build-macos:
12+
name: Build and Release macOS
13+
runs-on: macos-latest
14+
steps:
15+
- name: Checkout code
16+
uses: actions/checkout@v4
17+
18+
- uses: ./.github/actions/setup-cmux
19+
20+
- name: Install ImageMagick
21+
run: brew install imagemagick
22+
23+
- name: Build application
24+
run: bun run build
25+
26+
- name: Setup code signing
27+
run: ./scripts/setup-macos-signing.sh
28+
env:
29+
MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
30+
MACOS_CERTIFICATE_PWD: ${{ secrets.MACOS_CERTIFICATE_PWD }}
31+
AC_APIKEY_P8_BASE64: ${{ secrets.AC_APIKEY_P8_BASE64 }}
32+
AC_APIKEY_ID: ${{ secrets.AC_APIKEY_ID }}
33+
AC_APIKEY_ISSUER_ID: ${{ secrets.AC_APIKEY_ISSUER_ID }}
34+
35+
- name: Package and publish for macOS
36+
run: bun x electron-builder --mac --publish always
37+
env:
38+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
39+
40+
build-linux:
41+
name: Build and Release Linux
42+
runs-on: ${{ github.repository_owner == 'coder' && 'depot-ubuntu-22.04-16' || 'ubuntu-latest' }}
43+
steps:
44+
- name: Checkout code
45+
uses: actions/checkout@v4
46+
47+
- uses: ./.github/actions/setup-cmux
48+
49+
- name: Install ImageMagick
50+
run: sudo apt-get update && sudo apt-get install -y imagemagick
51+
52+
- name: Build application
53+
run: bun run build
54+
55+
- name: Package and publish for Linux
56+
run: bun x electron-builder --linux --publish always
57+
env:
58+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@
9696
"build": {
9797
"appId": "com.cmux.app",
9898
"productName": "Cmux",
99+
"publish": {
100+
"provider": "github",
101+
"releaseType": "release"
102+
},
99103
"directories": {
100104
"output": "release"
101105
},

scripts/setup-macos-signing.sh

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#!/bin/bash
2+
# Sets up macOS code signing and notarization from GitHub secrets
3+
# Usage: ./scripts/setup-macos-signing.sh
4+
#
5+
# Required environment variables:
6+
# MACOS_CERTIFICATE - Base64-encoded .p12 certificate
7+
# MACOS_CERTIFICATE_PWD - Certificate password
8+
# AC_APIKEY_P8_BASE64 - Base64-encoded Apple API key (.p8)
9+
# AC_APIKEY_ID - Apple API Key ID
10+
# AC_APIKEY_ISSUER_ID - Apple API Issuer ID
11+
12+
set -euo pipefail
13+
14+
# Setup code signing certificate
15+
if [ -n "${MACOS_CERTIFICATE:-}" ]; then
16+
echo "Setting up code signing certificate..."
17+
echo "$MACOS_CERTIFICATE" | base64 -D > /tmp/certificate.p12
18+
echo "CSC_LINK=/tmp/certificate.p12" >> "$GITHUB_ENV"
19+
echo "CSC_KEY_PASSWORD=$MACOS_CERTIFICATE_PWD" >> "$GITHUB_ENV"
20+
else
21+
echo "⚠️ No code signing certificate provided - building unsigned"
22+
fi
23+
24+
# Setup notarization credentials
25+
if [ -n "${AC_APIKEY_ID:-}" ]; then
26+
echo "Setting up notarization credentials..."
27+
echo "$AC_APIKEY_P8_BASE64" | base64 -D > /tmp/AuthKey.p8
28+
echo "APPLE_API_KEY=/tmp/AuthKey.p8" >> "$GITHUB_ENV"
29+
echo "APPLE_API_KEY_ID=$AC_APIKEY_ID" >> "$GITHUB_ENV"
30+
echo "APPLE_API_ISSUER=$AC_APIKEY_ISSUER_ID" >> "$GITHUB_ENV"
31+
echo "✅ Notarization credentials configured"
32+
else
33+
echo "⚠️ No notarization credentials - skipping notarization"
34+
fi

0 commit comments

Comments
 (0)