native macOS codings agent orchestrator
6
fork

Configure Feed

Select the types of activity you want to include in your feed.

Remove pr-dmg workflow

khoi d7f80e0b 82c067a2

-234
-234
.github/workflows/pr-dmg.yml
··· 1 - name: PR DMG 2 - 3 - on: 4 - pull_request: 5 - types: [labeled] 6 - 7 - concurrency: 8 - group: pr-dmg-${{ github.event.pull_request.number }} 9 - cancel-in-progress: true 10 - 11 - jobs: 12 - build_dmg: 13 - if: github.event.label.name == 'create-dmg' 14 - runs-on: macos-26 15 - permissions: 16 - contents: read 17 - actions: read 18 - issues: write 19 - pull-requests: write 20 - env: 21 - MISE_HTTP_TIMEOUT: 120 22 - MISE_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 23 - DEVELOPER_ID_CERT_P12: ${{ secrets.DEVELOPER_ID_CERT_P12 }} 24 - DEVELOPER_ID_CERT_PASSWORD: ${{ secrets.DEVELOPER_ID_CERT_PASSWORD }} 25 - DEVELOPER_ID_IDENTITY: ${{ secrets.DEVELOPER_ID_IDENTITY }} 26 - KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} 27 - APPLE_ID: ${{ secrets.APPLE_ID }} 28 - APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }} 29 - APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} 30 - steps: 31 - - uses: actions/checkout@v4 32 - with: 33 - submodules: recursive 34 - - name: Mise cache 35 - uses: actions/cache@v4 36 - with: 37 - path: | 38 - ~/.local/share/mise 39 - ~/.cache/mise 40 - key: ${{ runner.os }}-${{ runner.arch }}-mise-v0-${{ hashFiles('**/mise.toml', '**/.mise.toml', '**/.tool-versions', '**/.config/mise.toml', '**/mise/config.toml', '**/mise.lock', '**/.mise.lock', '**/mise/config.lock', '**/.config/mise.lock', '**/mise.*.toml', '**/.mise.*.toml', '**/.config/mise.*.toml', '**/mise.*.lock', '**/.mise.*.lock', '**/.config/mise.*.lock') }} 41 - - run: brew install mise 2>/dev/null 42 - - run: mise install 43 - - name: Ghostty cache key 44 - run: | 45 - set -euo pipefail 46 - GHOSTTY_SHA=$(git -C ThirdParty/ghostty rev-parse HEAD) 47 - printf '%s\n' "GHOSTTY_SHA=$GHOSTTY_SHA" >> "$GITHUB_ENV" 48 - - run: | 49 - echo "$DEVELOPER_ID_CERT_P12" | base64 --decode > build-cert.p12 50 - security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain 51 - security set-keychain-settings -t 3600 -u build.keychain 52 - security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain 53 - security import build-cert.p12 -k build.keychain -P "$DEVELOPER_ID_CERT_PASSWORD" -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/xcodebuild 54 - security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" build.keychain 55 - security list-keychains -d user -s build.keychain $(security list-keychains -d user | tr -d '"') 56 - security default-keychain -s build.keychain 57 - security find-identity -v -p codesigning build.keychain 58 - DEVELOPER_ID_IDENTITY_SHA=$(security find-identity -v -p codesigning build.keychain | grep "Developer ID Application" | head -1 | awk '{print $2}') 59 - if [ -z "$DEVELOPER_ID_IDENTITY_SHA" ]; then 60 - echo "::error::Developer ID Application identity not found in keychain" 61 - exit 1 62 - fi 63 - echo "DEVELOPER_ID_IDENTITY_SHA=$DEVELOPER_ID_IDENTITY_SHA" >> "$GITHUB_ENV" 64 - - name: Ghostty cache 65 - uses: actions/cache@v4 66 - with: 67 - path: | 68 - Frameworks/GhosttyKit.xcframework 69 - Resources/ghostty 70 - Resources/terminfo 71 - key: ${{ runner.os }}-${{ runner.arch }}-ghostty-${{ env.GHOSTTY_SHA }} 72 - - name: Build ghostty 73 - run: | 74 - set -euo pipefail 75 - make build-ghostty-xcframework 76 - - name: Archive Xcode project 77 - run: | 78 - set -o pipefail 79 - xcodebuild -project supacode.xcodeproj -scheme supacode -configuration Release -archivePath build/supacode.xcarchive archive CODE_SIGN_STYLE=Manual DEVELOPMENT_TEAM="$APPLE_TEAM_ID" CODE_SIGN_IDENTITY="$DEVELOPER_ID_IDENTITY_SHA" OTHER_CODE_SIGN_FLAGS="--timestamp" -skipMacroValidation 2>&1 | mise exec -- xcsift -qw --format toon 80 - - run: | 81 - cat > build/ExportOptions.plist <<EOF 82 - <?xml version="1.0" encoding="UTF-8"?> 83 - <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 84 - <plist version="1.0"> 85 - <dict> 86 - <key>method</key> 87 - <string>developer-id</string> 88 - <key>signingStyle</key> 89 - <string>manual</string> 90 - <key>signingCertificate</key> 91 - <string>$DEVELOPER_ID_IDENTITY</string> 92 - <key>teamID</key> 93 - <string>$APPLE_TEAM_ID</string> 94 - </dict> 95 - </plist> 96 - EOF 97 - set -o pipefail 98 - xcodebuild -exportArchive -archivePath build/supacode.xcarchive -exportPath build/export -exportOptionsPlist build/ExportOptions.plist 2>&1 | mise exec -- xcsift -qw --format toon 99 - - name: Re-sign Sparkle framework 100 - run: | 101 - set -ex 102 - APP_PATH="$(find build/export -name "supacode.app" -maxdepth 3 -print -quit)" 103 - SPARKLE="$APP_PATH/Contents/Frameworks/Sparkle.framework/Versions/B" 104 - 105 - echo "Using identity: $DEVELOPER_ID_IDENTITY" 106 - security find-identity -v -p codesigning 107 - 108 - codesign -f -s "$DEVELOPER_ID_IDENTITY_SHA" -o runtime --timestamp -v "$SPARKLE/XPCServices/Installer.xpc" 109 - codesign -f -s "$DEVELOPER_ID_IDENTITY_SHA" -o runtime --timestamp --preserve-metadata=entitlements -v "$SPARKLE/XPCServices/Downloader.xpc" 110 - codesign -f -s "$DEVELOPER_ID_IDENTITY_SHA" -o runtime --timestamp -v "$SPARKLE/Updater.app" 111 - codesign -f -s "$DEVELOPER_ID_IDENTITY_SHA" -o runtime --timestamp -v "$SPARKLE/Autoupdate" 112 - codesign -f -s "$DEVELOPER_ID_IDENTITY_SHA" -o runtime --timestamp -v "$SPARKLE/Sparkle" 113 - codesign -f -s "$DEVELOPER_ID_IDENTITY_SHA" -o runtime --timestamp -v "$APP_PATH/Contents/Frameworks/Sparkle.framework" 114 - SENTRY_FRAMEWORK="$APP_PATH/Contents/Frameworks/Sentry.framework" 115 - codesign -f -s "$DEVELOPER_ID_IDENTITY_SHA" -o runtime --timestamp -v "$SENTRY_FRAMEWORK/Versions/A/Sentry" 116 - codesign -f -s "$DEVELOPER_ID_IDENTITY_SHA" -o runtime --timestamp -v "$SENTRY_FRAMEWORK" 117 - codesign -f -s "$DEVELOPER_ID_IDENTITY_SHA" -o runtime --timestamp -v "$APP_PATH" 118 - 119 - codesign -vvv --deep --strict "$APP_PATH" 120 - codesign -dv --verbose=4 "$APP_PATH" 2>&1 | grep -E "Authority=Developer ID Application|Timestamp=" 121 - codesign -dv --verbose=4 "$APP_PATH/Contents/MacOS/supacode" 2>&1 | grep -E "Authority=Developer ID Application|Timestamp=" 122 - codesign -dv --verbose=4 "$SPARKLE/Updater.app/Contents/MacOS/Updater" 2>&1 | grep -E "Authority=Developer ID Application|Timestamp=" 123 - codesign -dv --verbose=4 "$SPARKLE/XPCServices/Installer.xpc/Contents/MacOS/Installer" 2>&1 | grep -E "Authority=Developer ID Application|Timestamp=" 124 - codesign -dv --verbose=4 "$SPARKLE/XPCServices/Downloader.xpc/Contents/MacOS/Downloader" 2>&1 | grep -E "Authority=Developer ID Application|Timestamp=" 125 - echo "Signature verified successfully" 126 - - name: Notarize and staple 127 - run: | 128 - APP_PATH="$(find build/export -name "supacode.app" -maxdepth 3 -print -quit)" 129 - NOTARY_ZIP=build/supacode.notary.zip 130 - ditto -c -k --sequesterRsrc --keepParent "$APP_PATH" "$NOTARY_ZIP" 131 - 132 - for attempt in 1 2 3; do 133 - echo "Notarization attempt $attempt..." 134 - OUTPUT=$(xcrun notarytool submit "$NOTARY_ZIP" --apple-id "$APPLE_ID" --password "$APPLE_APP_SPECIFIC_PASSWORD" --team-id "$APPLE_TEAM_ID" --wait --output-format json 2>&1) && break 135 - echo "Attempt $attempt failed, retrying in 30s..." 136 - sleep 30 137 - done 138 - 139 - SUBMISSION_ID=$(echo "$OUTPUT" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4) 140 - STATUS=$(echo "$OUTPUT" | grep -o '"status":"[^"]*"' | head -1 | cut -d'"' -f4) 141 - echo "Submission ID: $SUBMISSION_ID" 142 - echo "Status: $STATUS" 143 - 144 - if [ "$STATUS" != "Accepted" ]; then 145 - echo "::error::Notarization failed with status: $STATUS" 146 - echo "Fetching notarization log..." 147 - xcrun notarytool log "$SUBMISSION_ID" --apple-id "$APPLE_ID" --password "$APPLE_APP_SPECIFIC_PASSWORD" --team-id "$APPLE_TEAM_ID" 148 - exit 1 149 - fi 150 - 151 - xcrun stapler staple "$APP_PATH" 152 - - name: Build DMG 153 - run: | 154 - APP_PATH="$(find build/export -name "supacode.app" -maxdepth 3 -print -quit)" 155 - 156 - mise exec -- create-dmg "$APP_PATH" build/ \ 157 - --overwrite \ 158 - --dmg-title="Supacode" \ 159 - --identity="$DEVELOPER_ID_IDENTITY_SHA" 160 - 161 - DMG_OUTPUT=$(find build -name "*.dmg" -maxdepth 1 | head -1) 162 - if [ "$DMG_OUTPUT" != "build/supacode.dmg" ]; then 163 - mv "$DMG_OUTPUT" build/supacode.dmg 164 - fi 165 - DMG_PATH=build/supacode.dmg 166 - 167 - for attempt in 1 2 3; do 168 - echo "DMG notarization attempt $attempt..." 169 - OUTPUT=$(xcrun notarytool submit "$DMG_PATH" --apple-id "$APPLE_ID" --password "$APPLE_APP_SPECIFIC_PASSWORD" --team-id "$APPLE_TEAM_ID" --wait --output-format json 2>&1) && break 170 - echo "Attempt $attempt failed, retrying in 30s..." 171 - sleep 30 172 - done 173 - 174 - SUBMISSION_ID=$(echo "$OUTPUT" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4) 175 - STATUS=$(echo "$OUTPUT" | grep -o '"status":"[^"]*"' | head -1 | cut -d'"' -f4) 176 - echo "Submission ID: $SUBMISSION_ID" 177 - echo "Status: $STATUS" 178 - 179 - if [ "$STATUS" != "Accepted" ]; then 180 - echo "::error::DMG notarization failed with status: $STATUS" 181 - echo "Fetching notarization log..." 182 - xcrun notarytool log "$SUBMISSION_ID" --apple-id "$APPLE_ID" --password "$APPLE_APP_SPECIFIC_PASSWORD" --team-id "$APPLE_TEAM_ID" 183 - exit 1 184 - fi 185 - 186 - xcrun stapler staple "$DMG_PATH" 187 - echo "DMG_PATH=$DMG_PATH" >> "$GITHUB_ENV" 188 - - uses: actions/upload-artifact@v4 189 - with: 190 - name: supacode-pr-dmg 191 - path: build/supacode.dmg 192 - - name: Comment on PR 193 - uses: actions/github-script@v7 194 - with: 195 - script: | 196 - const marker = 'Supacode PR DMG' 197 - const owner = context.repo.owner 198 - const repo = context.repo.repo 199 - const runUrl = `https://github.com/${owner}/${repo}/actions/runs/${context.runId}` 200 - const artifacts = await github.rest.actions.listWorkflowRunArtifacts({ 201 - owner, 202 - repo, 203 - run_id: context.runId 204 - }) 205 - const artifact = artifacts.data.artifacts.find(item => item.name === 'supacode-pr-dmg') 206 - const artifactUrl = artifact 207 - ? `https://github.com/${owner}/${repo}/actions/runs/${context.runId}/artifacts/${artifact.id}` 208 - : runUrl 209 - const body = `${marker}\n\nSigned DMG is ready. Download:\n${artifactUrl}\n\nRun details:\n${runUrl}` 210 - 211 - const { data: comments } = await github.rest.issues.listComments({ 212 - owner, 213 - repo, 214 - issue_number: context.issue.number, 215 - per_page: 100 216 - }) 217 - 218 - const existing = comments.find(comment => comment.user?.login === 'github-actions[bot]' && comment.body?.startsWith(marker)) 219 - 220 - if (existing) { 221 - await github.rest.issues.updateComment({ 222 - owner, 223 - repo, 224 - comment_id: existing.id, 225 - body 226 - }) 227 - } else { 228 - await github.rest.issues.createComment({ 229 - owner, 230 - repo, 231 - issue_number: context.issue.number, 232 - body 233 - }) 234 - }