CI #2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 (Fork).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 |