name: Signed release on: push: tags: ['v*'] jobs: release: runs-on: macos-14 steps: - uses: actions/checkout@v4 - name: Import Developer ID certificate env: SIGNING_P12: ${{ secrets.DEVELOPER_ID_P12_BASE64 }} SIGNING_PASSWORD: ${{ secrets.DEVELOPER_ID_P12_PASSWORD }} run: | KEYCHAIN="$RUNNER_TEMP/puter-signing.keychain-db" security create-keychain -p runner "$KEYCHAIN" security set-keychain-settings -lut 21600 "$KEYCHAIN" security unlock-keychain -p runner "$KEYCHAIN" printf '%s' "$SIGNING_P12" | base64 --decode > "$RUNNER_TEMP/puter-signing.p12" security import "$RUNNER_TEMP/puter-signing.p12" -k "$KEYCHAIN" -P "$SIGNING_PASSWORD" -T /usr/bin/codesign security set-key-partition-list -S apple-tool:,apple: -s -k runner "$KEYCHAIN" security list-keychains -d user -s "$KEYCHAIN" login.keychain-db - name: Prepare notarization key env: NOTARY_KEY: ${{ secrets.APPLE_NOTARY_KEY_BASE64 }} run: printf '%s' "$NOTARY_KEY" | base64 --decode > "$RUNNER_TEMP/AuthKey.p8" - name: Build signed app and DMG env: PUTER_RELEASE_BUILD: '1' PUTER_SIGN_IDENTITY: ${{ secrets.DEVELOPER_ID_IDENTITY }} PUTER_UPDATE_FEED_URL: ${{ secrets.SPARKLE_FEED_URL }} PUTER_UPDATE_PUBLIC_KEY: ${{ secrets.SPARKLE_PUBLIC_KEY }} run: | export PUTER_VERSION="${GITHUB_REF_NAME#v}" export PUTER_BUILD_NUMBER="$GITHUB_RUN_NUMBER" ./scripts/build-app.sh ./scripts/build-dmg.sh ./scripts/validate-package.sh - name: Notarize and staple env: PUTER_NOTARY_KEY_PATH: ${{ runner.temp }}/AuthKey.p8 PUTER_NOTARY_KEY_ID: ${{ secrets.APPLE_NOTARY_KEY_ID }} PUTER_NOTARY_ISSUER: ${{ secrets.APPLE_NOTARY_ISSUER_ID }} run: ./scripts/notarize-release.sh - name: Validate notarized release env: PUTER_RELEASE_BUILD: '1' run: | ./scripts/validate-package.sh xcrun stapler validate dist/puter.app xcrun stapler validate dist/puter-macOS.dmg - name: Generate signed appcast env: PUTER_UPDATE_DOWNLOAD_PREFIX: ${{ secrets.SPARKLE_DOWNLOAD_PREFIX }} PUTER_SPARKLE_PRIVATE_KEY: ${{ secrets.SPARKLE_PRIVATE_KEY }} run: | mkdir -p dist/updates ditto dist/puter-macOS.dmg "dist/updates/puter-${GITHUB_REF_NAME#v}.dmg" ./scripts/generate-appcast.sh dist/updates - name: Prepare release assets run: | ditto -c -k --sequesterRsrc --keepParent dist/puter.app "dist/puter-${GITHUB_REF_NAME#v}-macOS.zip" shasum -a 256 \ dist/puter-macOS.dmg \ "dist/puter-${GITHUB_REF_NAME#v}-macOS.zip" \ dist/updates/appcast.xml > dist/SHA256SUMS - name: Publish Gitea release env: RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }} run: | API_ROOT="${GITHUB_API_URL:-${GITEA_SERVER_URL}/api/v1}" RELEASE_JSON="$(curl --fail-with-body -sS -X POST \ -H "Authorization: token $RELEASE_TOKEN" -H 'Content-Type: application/json' \ "$API_ROOT/repos/$GITHUB_REPOSITORY/releases" \ -d "{\"tag_name\":\"$GITHUB_REF_NAME\",\"name\":\"puter $GITHUB_REF_NAME\",\"draft\":false,\"prerelease\":false}")" RELEASE_ID="$(printf '%s' "$RELEASE_JSON" | jq -r .id)" for ASSET in \ dist/puter-macOS.dmg \ "dist/puter-${GITHUB_REF_NAME#v}-macOS.zip" \ dist/updates/appcast.xml \ dist/SHA256SUMS; do curl --fail-with-body -sS -X POST -H "Authorization: token $RELEASE_TOKEN" \ -H 'Content-Type: application/octet-stream' --data-binary "@$ASSET" \ "$API_ROOT/repos/$GITHUB_REPOSITORY/releases/$RELEASE_ID/assets?name=$(basename "$ASSET")" done