Skip to content

CI

CI #1

Workflow file for this run

name: CI
on:
workflow_dispatch:
workflow_run:
workflows: ["Code Quality"]
types: [completed]
branches: [main]
pull_request:
branches: [main]
# Cancel in-progress runs for the same branch/PR
concurrency:
group: ci-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
build:
name: Build DMG
runs-on: macos-26
if: >-
github.event_name == 'workflow_dispatch' ||
github.event_name == 'pull_request' ||
github.event.workflow_run.conclusion == 'success'
outputs:
version: ${{ steps.version.outputs.version }}
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
ref: ${{ github.event.workflow_run.head_sha || github.sha }}
- name: Setup Xcode
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: latest-stable
- name: Verify Swift version
run: |
swift --version
SWIFT_VERSION=$(swift --version 2>&1 | sed -n 's/.*Apple Swift version \([0-9]*\.[0-9]*\).*/\1/p')
if [[ -z "$SWIFT_VERSION" ]]; then
echo "::error::Could not detect Swift version from 'swift --version' output"
exit 1
fi
echo "Detected Swift $SWIFT_VERSION"
SWIFT_MAJOR=$(echo "$SWIFT_VERSION" | cut -d. -f1)
SWIFT_MINOR=$(echo "$SWIFT_VERSION" | cut -d. -f2)
if [[ "$SWIFT_MAJOR" -lt 6 ]] || { [[ "$SWIFT_MAJOR" -eq 6 ]] && [[ "$SWIFT_MINOR" -lt 2 ]]; }; then
echo "::error::Swift 6.2+ required. Found $SWIFT_VERSION"
exit 1
fi
- name: Build with ad-hoc signing
run: ./scripts/build.sh
- name: Install create-dmg
run: brew install create-dmg || true
- name: Setup Sparkle key
id: sparkle-key
env:
SPARKLE_PRIVATE_KEY: ${{ secrets.SPARKLE_PRIVATE_KEY }}
run: |
if [ -n "$SPARKLE_PRIVATE_KEY" ]; then
mkdir -p .sparkle-keys
echo "$SPARKLE_PRIVATE_KEY" > .sparkle-keys/eddsa_private_key
echo "has_key=true" >> $GITHUB_OUTPUT
else
echo "has_key=false" >> $GITHUB_OUTPUT
echo "::warning::SPARKLE_PRIVATE_KEY not set -- Sparkle signing will be skipped."
fi
- name: Create DMG and sign with Sparkle
run: |
SPARKLE_FLAG=""
if [ "${{ steps.sparkle-key.outputs.has_key }}" != "true" ]; then
SPARKLE_FLAG="--skip-sparkle"
fi
./scripts/create-release.sh --skip-notarization --skip-github --skip-website $SPARKLE_FLAG
- name: Get version
id: version
run: |
VERSION=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" \
"build/export/Claude Island.app/Contents/Info.plist")
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Built version: $VERSION"
- name: Upload DMG artifact
uses: actions/upload-artifact@v7
with:
name: claude-island-dmg
path: releases/ClaudeIsland-${{ steps.version.outputs.version }}.dmg
retention-days: 30
virustotal-scan:
name: VirusTotal Scan
needs: build
runs-on: ubuntu-latest
if: >-
github.event_name != 'pull_request' &&
vars.HAS_VT_KEY == 'true'
steps:
- name: Download DMG artifact
uses: actions/download-artifact@v8
with:
name: claude-island-dmg
- name: Scan with VirusTotal
uses: crazy-max/ghaction-virustotal@v5
id: virustotal
with:
vt_api_key: ${{ secrets.VT_API_KEY }}
request_rate: 4
files: |
*.dmg
- name: Create scan results summary
run: |
{
echo "## VirusTotal Scan Results"
echo ""
echo "**Scan completed:** $(date -u '+%Y-%m-%d %H:%M:%S UTC')"
echo ""
echo "| File | Report |"
echo "|------|--------|"
IFS=',' read -ra PAIRS <<< "${{ steps.virustotal.outputs.analysis }}"
for pair in "${PAIRS[@]}"; do
filename="${pair%%=*}"
url="${pair#*=}"
echo "| \`${filename}\` | [View Report](${url}) |"
done
} | tee virustotal-results.md >> $GITHUB_STEP_SUMMARY
- name: Upload scan results
uses: actions/upload-artifact@v7
with:
name: virustotal-results
path: virustotal-results.md
retention-days: 90