v0.0.14 - Sushi 🍣 #19
Workflow file for this run
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: Publish Appcast | |
| # Fires only once a release is actually public (draft -> published), so the | |
| # Sparkle enclosure URL below always resolves for end users. | |
| on: | |
| release: | |
| types: | |
| - released | |
| permissions: | |
| contents: write | |
| jobs: | |
| publish-appcast: | |
| runs-on: macos-15 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v5 | |
| - name: Download release DMGs | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| TAG_NAME: ${{ github.event.release.tag_name }} | |
| run: gh release download "$TAG_NAME" --pattern "EasyKey-*.dmg" --dir /tmp/dmg | |
| - name: Locate DMG | |
| id: dmg | |
| run: | | |
| shopt -s nullglob | |
| matches=(/tmp/dmg/EasyKey-*-universal.dmg) | |
| if (( ${#matches[@]} != 1 )); then | |
| printf 'Expected exactly one universal DMG, found %s.\n' "${#matches[@]}" >&2 | |
| exit 1 | |
| fi | |
| dmg_path="${matches[0]}" | |
| echo "path=$dmg_path" >> "$GITHUB_OUTPUT" | |
| echo "length=$(stat -f%z "$dmg_path")" >> "$GITHUB_OUTPUT" | |
| - name: Read release metadata | |
| id: metadata | |
| env: | |
| DMG_PATH: ${{ steps.dmg.outputs.path }} | |
| TAG_NAME: ${{ github.event.release.tag_name }} | |
| run: | | |
| mount_point=/tmp/easykey-release | |
| mkdir -p "$mount_point" | |
| hdiutil attach "$DMG_PATH" -readonly -nobrowse -mountpoint "$mount_point" | |
| trap 'hdiutil detach "$mount_point"' EXIT | |
| info_plist="$mount_point/EasyKey.app/Contents/Info.plist" | |
| version=$(/usr/libexec/PlistBuddy -c 'Print :CFBundleShortVersionString' "$info_plist") | |
| build=$(/usr/libexec/PlistBuddy -c 'Print :CFBundleVersion' "$info_plist") | |
| minimum_system_version=$(/usr/libexec/PlistBuddy -c 'Print :LSMinimumSystemVersion' "$info_plist") | |
| [[ "$TAG_NAME" == "v$version" ]] || { | |
| printf 'Tag %s does not match built version %s.\n' "$TAG_NAME" "$version" >&2 | |
| exit 1 | |
| } | |
| echo "version=$version" >> "$GITHUB_OUTPUT" | |
| echo "build=$build" >> "$GITHUB_OUTPUT" | |
| echo "minimum-system-version=$minimum_system_version" >> "$GITHUB_OUTPUT" | |
| - name: Download Sparkle tools | |
| # Pin Sparkle 2.9.4 tarball SHA256 checksum to prevent untrusted execution | |
| run: | | |
| expected_sha256="ce89daf967db1e1893ed3ebd67575ed82d3902563e3191ca92aaec9164fbdef9" | |
| curl -fsSL -o /tmp/sparkle.tar.xz \ | |
| "https://github.com/sparkle-project/Sparkle/releases/download/2.9.4/Sparkle-2.9.4.tar.xz" | |
| echo "${expected_sha256} /tmp/sparkle.tar.xz" | shasum -a 256 -c - | |
| mkdir -p /tmp/sparkle-tools | |
| tar -xf /tmp/sparkle.tar.xz -C /tmp/sparkle-tools | |
| - name: Sign DMGs | |
| id: sign | |
| env: | |
| SPARKLE_PRIVATE_KEY: ${{ secrets.SPARKLE_PRIVATE_ED_KEY }} | |
| run: | | |
| key_file=$(mktemp) | |
| trap 'rm -f "$key_file"' EXIT | |
| chmod 600 "$key_file" | |
| printf '%s' "$SPARKLE_PRIVATE_KEY" > "$key_file" | |
| for dmg in /tmp/dmg/EasyKey-*.dmg; do | |
| echo "Signing $dmg..." | |
| /tmp/sparkle-tools/bin/sign_update "$dmg" --ed-key-file "$key_file" | |
| done | |
| signature=$(/tmp/sparkle-tools/bin/sign_update "${{ steps.dmg.outputs.path }}" --ed-key-file "$key_file" -p) | |
| echo "signature=$signature" >> "$GITHUB_OUTPUT" | |
| - name: Checkout gh-pages | |
| uses: actions/checkout@v5 | |
| with: | |
| ref: gh-pages | |
| path: gh-pages | |
| - name: Update appcast | |
| env: | |
| TAG_NAME: ${{ github.event.release.tag_name }} | |
| REPOSITORY: ${{ github.repository }} | |
| DMG_PATH: ${{ steps.dmg.outputs.path }} | |
| DMG_LENGTH: ${{ steps.dmg.outputs.length }} | |
| SIGNATURE: ${{ steps.sign.outputs.signature }} | |
| run: | | |
| pub_date=$(date -R) | |
| dmg_url="https://github.com/${REPOSITORY}/releases/download/${TAG_NAME}/$(basename "$DMG_PATH")" | |
| python3 Scripts/generate-appcast.py \ | |
| gh-pages/appcast.xml \ | |
| "${{ steps.metadata.outputs.version }}" \ | |
| "${{ steps.metadata.outputs.build }}" \ | |
| "$dmg_url" \ | |
| "$DMG_LENGTH" \ | |
| "$SIGNATURE" \ | |
| "${{ steps.metadata.outputs.minimum-system-version }}" \ | |
| "$pub_date" | |
| - name: Commit and push appcast | |
| working-directory: gh-pages | |
| env: | |
| TAG_NAME: ${{ github.event.release.tag_name }} | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| git add appcast.xml | |
| git commit -m "chore: publish appcast for $TAG_NAME" | |
| git push |