Files
humanlayer/.github/workflows/release-macos.yml
dexhorthy 44487997b9 Fix nightly release version format
Remove "-test" suffix from nightly version to ensure release notes
correctly show "codelayer-nightly" in installation instructions.

The conditional expression in release notes was already correct,
but the version format included an extra "-test" suffix causing
the condition to match incorrectly.
2025-08-11 17:44:45 -05:00

246 lines
10 KiB
YAML

name: Build macOS Release Artifacts
on:
schedule:
# Run daily at 7am PT (3pm UTC during standard time, 2pm UTC during daylight saving)
- cron: '0 14 * * *'
workflow_dispatch:
inputs:
release_version:
description: 'Version tag for the release (defaults to YYYYMMDD_HHmmss for manual, YYYYMMDD-nightly for cron)'
required: false
type: string
release_nightly:
description: 'Build and release a nightly build'
required: false
type: boolean
default: false
permissions:
contents: write # Needed to create releases
jobs:
build-macos:
runs-on: macos-latest
steps:
- name: Set release version
id: version
run: |
if [ "${{ github.event_name }}" = "schedule" ] || [ "${{ github.event.inputs.release_nightly }}" = "true" ]; then
# For cron/scheduled runs or test mode, use YYYYMMDD-nightly format
echo "release_version=$(date +%Y%m%d)-nightly" >> $GITHUB_OUTPUT
elif [ -z "${{ github.event.inputs.release_version }}" ]; then
# For manual runs without specified version, use YYYYMMDD_HHmmss
echo "release_version=$(date +%Y%m%d_%H%M%S)" >> $GITHUB_OUTPUT
else
# Use the provided version
echo "release_version=${{ github.event.inputs.release_version }}" >> $GITHUB_OUTPUT
fi
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version-file: 'hld/go.mod'
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Run repository setup
run: make setup
- name: Install WUI dependencies
working-directory: humanlayer-wui
run: bun install
- name: Build daemon for macOS ARM
working-directory: hld
run: |
BUILD_VERSION="${{ steps.version.outputs.release_version }}"
if [ "${{ github.event_name }}" = "schedule" ] || [ "${{ github.event.inputs.release_nightly }}" = "true" ]; then
# Nightly build with custom defaults
LDFLAGS="-X github.com/humanlayer/humanlayer/hld/internal/version.BuildVersion=${BUILD_VERSION}"
LDFLAGS="${LDFLAGS} -X github.com/humanlayer/humanlayer/hld/config.DefaultDatabasePath=~/.humanlayer/daemon-nightly.db"
LDFLAGS="${LDFLAGS} -X github.com/humanlayer/humanlayer/hld/config.DefaultSocketPath=~/.humanlayer/daemon-nightly.sock"
LDFLAGS="${LDFLAGS} -X github.com/humanlayer/humanlayer/hld/config.DefaultHTTPPort=7778"
else
# Regular build with version only
LDFLAGS="-X github.com/humanlayer/humanlayer/hld/internal/version.BuildVersion=${BUILD_VERSION}"
fi
GOOS=darwin GOARCH=arm64 go build -ldflags "${LDFLAGS}" -o hld-darwin-arm64 ./cmd/hld
- name: Build humanlayer CLI for macOS ARM
working-directory: hlyr
run: |
bun install
bun run build
bun build ./dist/index.js --compile --target=bun-darwin-arm64 --outfile=humanlayer-darwin-arm64
chmod +x humanlayer-darwin-arm64
- name: Copy binaries to Tauri resources
run: |
mkdir -p humanlayer-wui/src-tauri/bin
cp hld/hld-darwin-arm64 humanlayer-wui/src-tauri/bin/hld
cp hlyr/humanlayer-darwin-arm64 humanlayer-wui/src-tauri/bin/humanlayer
chmod +x humanlayer-wui/src-tauri/bin/hld
chmod +x humanlayer-wui/src-tauri/bin/humanlayer
- name: Use nightly icons for scheduled build
if: github.event_name == 'schedule' || github.event.inputs.release_nightly == 'true'
working-directory: humanlayer-wui/src-tauri
run: |
# Backup original icons
mv icons icons-original
# Use nightly icons
cp -r icons-nightly icons
- name: Build Tauri app (including DMG)
working-directory: humanlayer-wui
run: |
if [ "${{ github.event_name }}" = "schedule" ] || [ "${{ github.event.inputs.release_nightly }}" = "true" ]; then
# Use nightly config for scheduled builds
bun run tauri build --config src-tauri/tauri.nightly.conf.json
else
# Regular build for manual runs
bun run tauri build
fi
env:
APPLE_SIGNING_IDENTITY: "-" # Ad-hoc signing to prevent "damaged" error
- name: Upload DMG artifact
uses: actions/upload-artifact@v4
with:
name: humanlayer-wui-macos-dmg
path: humanlayer-wui/src-tauri/target/release/bundle/dmg/*.dmg
if-no-files-found: error
# Create GitHub Release with artifacts
- name: Create Release
if: github.event_name == 'workflow_dispatch' || github.event_name == 'schedule'
id: create_release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.version.outputs.release_version }}
name: codelayer-${{ steps.version.outputs.release_version }}
body: |
## codelayer-${{ steps.version.outputs.release_version }}
This release includes:
* **CodeLayer** - Desktop application (DMG installer)
### tl;dr
```
brew install --cask --no-quarantine humanlayer/humanlayer/codelayer${{ contains(steps.version.outputs.release_version, 'nightly') && '-nightly' || '' }}
# kill any existing hld process and open CodeLayer with current shell PATH so it can find your `claude` CLI
pkill hld; open /Applications/CodeLayer${{ contains(steps.version.outputs.release_version, 'nightly') && '-Nightly' || '' }}.app
```
* if your `claude` cli is not in a very-default location like `/usr/local/bin`, you will need to launch with `open /Applications/CodeLayer${{ contains(steps.version.outputs.release_version, 'nightly') && '-Nightly' || '' }}.app` rather than launching from Spotlight/Finder/Raycast/etc
### Requirements
* macOS (Apple Silicon/M-series)
### Troubleshooting / Known Issues
* If install fails, ensure you've cleaned up all previous artifacts. `brew reinstall` is worth a shot as well.
* Logs can be found at `~/Library/Logs/dev.humanlayer.wui${{ contains(steps.version.outputs.release_version, 'nightly') && '.nightly' || '' }}/CodeLayer.log`
* If daemon fails due to already running, you can `pkill hld` and reopen CodeLayer to try again
* If opening from spotlight/alfred/raycast/finder fails, try `pkill hld; open /Applications/CodeLayer${{ contains(steps.version.outputs.release_version, 'nightly') && '-Nightly' || '' }}.app` to push your PATH into CodeLayer so it can better find your `claude` CLI
draft: false
prerelease: ${{ contains(steps.version.outputs.release_version, 'nightly') }}
files: |
humanlayer-wui/src-tauri/target/release/bundle/dmg/*.dmg
# Update nightly cask for scheduled builds
- name: Prepare cask update
if: github.event_name == 'schedule' || github.event.inputs.release_nightly == 'true'
id: prepare
run: |
# Get the DMG filename
DMG_FILE=$(ls humanlayer-wui/src-tauri/target/release/bundle/dmg/*.dmg | head -1)
echo "dmg_file=${DMG_FILE}" >> $GITHUB_OUTPUT
# Calculate SHA256
SHA256=$(shasum -a 256 "${DMG_FILE}" | cut -f1 -d' ')
echo "sha256=${SHA256}" >> $GITHUB_OUTPUT
# Get release tag
RELEASE_TAG="${{ steps.version.outputs.release_version }}"
echo "release_tag=${RELEASE_TAG}" >> $GITHUB_OUTPUT
# Construct DMG URL
DMG_FILENAME=$(basename "${DMG_FILE}")
DMG_URL="https://github.com/humanlayer/humanlayer/releases/download/${RELEASE_TAG}/${DMG_FILENAME}"
echo "dmg_url=${DMG_URL}" >> $GITHUB_OUTPUT
- name: Checkout homebrew tap
if: github.event_name == 'schedule' || github.event.inputs.release_nightly == 'true'
uses: actions/checkout@v4
with:
repository: humanlayer/homebrew-humanlayer
token: ${{ secrets.HUMANLAYER_HOMEBREW_CASK_WRITE_GITHUB_PAT }}
path: homebrew-tap
- name: Update nightly cask
if: github.event_name == 'schedule' || github.event.inputs.release_nightly == 'true'
working-directory: homebrew-tap
run: |
# Update the cask file
cat > Casks/codelayer-nightly.rb << 'EOF'
cask "codelayer-nightly" do
version "${{ steps.prepare.outputs.release_tag }}"
sha256 "${{ steps.prepare.outputs.sha256 }}"
url "${{ steps.prepare.outputs.dmg_url }}",
verified: "github.com/humanlayer/humanlayer/"
name "CodeLayer Nightly"
desc "Nightly build of CodeLayer - Desktop application for managing AI agent approvals"
homepage "https://humanlayer.dev/"
# No conflicts - can install alongside stable
app "CodeLayer-Nightly.app"
binary "#{appdir}/CodeLayer-Nightly.app/Contents/Resources/bin/humanlayer", target: "humanlayer-nightly"
binary "#{appdir}/CodeLayer-Nightly.app/Contents/Resources/bin/hld", target: "hld-nightly"
zap trash: [
"~/Library/Application Support/CodeLayer-Nightly",
"~/Library/Preferences/dev.humanlayer.wui.nightly.plist",
"~/Library/Saved Application State/dev.humanlayer.wui.nightly.savedState",
"~/.humanlayer/codelayer-nightly*.json",
"~/.humanlayer/daemon-nightly*.db",
"~/.humanlayer/daemon-nightly*.sock",
"~/Library/Logs/dev.humanlayer.wui.nightly/",
]
end
EOF
- name: Commit and push cask update
if: github.event_name == 'schedule' || github.event.inputs.release_nightly == 'true'
working-directory: homebrew-tap
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add Casks/codelayer-nightly.rb
git commit -m "Update codelayer-nightly to ${{ steps.prepare.outputs.release_tag }}"
git push