Skip to content

Release macOS

Release macOS #7

Workflow file for this run

name: Release macOS
on:
push:
tags:
- "v*.*.*"
workflow_dispatch:
inputs:
version:
description: "Semantic version to release, for example 0.1.0"
required: true
type: string
permissions:
contents: read
jobs:
release:
name: Build and publish Lithe for macOS
if: github.actor == github.repository_owner
runs-on: macos-14
permissions:
contents: write
outputs:
version: ${{ steps.version.outputs.version }}
tag: ${{ steps.version.outputs.tag }}
steps:
- name: Check out source
uses: actions/checkout@v4
- name: Set up Swift
# v2 downloads the macOS toolchain package directly. The beta v3
# Swiftly installer is currently unstable on the macos-14 runner.
uses: swift-actions/setup-swift@v2
with:
swift-version: "6.2"
- name: Set up Rust targets
run: |
rustup toolchain install stable --profile minimal
rustup default stable
rustup target add aarch64-apple-darwin x86_64-apple-darwin
- name: Resolve release version
id: version
env:
EVENT_NAME: ${{ github.event_name }}
MANUAL_VERSION: ${{ inputs.version }}
shell: bash
run: |
if [[ "$EVENT_NAME" == "workflow_dispatch" ]]; then
version="$MANUAL_VERSION"
else
version="${GITHUB_REF_NAME#v}"
fi
if [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Release version must use the form MAJOR.MINOR.PATCH: $version"
exit 1
fi
echo "version=$version" >> "$GITHUB_OUTPUT"
echo "tag=v$version" >> "$GITHUB_OUTPUT"
echo "build_number=$GITHUB_RUN_NUMBER" >> "$GITHUB_OUTPUT"
- name: Build the App bundle
env:
LITHE_VERSION: ${{ steps.version.outputs.version }}
LITHE_BUILD_NUMBER: ${{ steps.version.outputs.build_number }}
run: |
chmod +x scripts/package-app.sh
chmod +x scripts/create-dmg.sh
for architecture in arm64 x86_64; do
LITHE_ARCH="$architecture" ./scripts/package-app.sh
LITHE_ARCH="$architecture" ./scripts/create-dmg.sh
# 在 dist/ 内部计算,让校验文件只记录裸文件名,
# 这样下载后直接 shasum -c 就能通过。
dmg_name="Lithe-${LITHE_VERSION}-${architecture}.dmg"
(cd dist && shasum -a 256 "$dmg_name" > "$dmg_name.sha256")
done
- name: Verify the bundle and disk image
env:
LITHE_VERSION: ${{ steps.version.outputs.version }}
run: |
for architecture in arm64 x86_64; do
app_path="dist/Lithe-${architecture}.app"
dmg_path="dist/Lithe-${LITHE_VERSION}-${architecture}.dmg"
codesign --verify --deep --strict "$app_path"
/usr/libexec/PlistBuddy \
-c "Print :CFBundleShortVersionString" \
"$app_path/Contents/Info.plist"
/usr/libexec/PlistBuddy \
-c "Print :CFBundleVersion" \
"$app_path/Contents/Info.plist"
lipo "$app_path/Contents/MacOS/Lithe" -verify_arch "$architecture"
hdiutil imageinfo "$dmg_path" > /dev/null
test -s "$dmg_path"
done
- name: Create GitHub Release
env:
GH_TOKEN: ${{ github.token }}
RELEASE_TAG: ${{ steps.version.outputs.tag }}
LITHE_VERSION: ${{ steps.version.outputs.version }}
run: |
notes_file="docs/releases/v${LITHE_VERSION}.md"
release_args=(
"$RELEASE_TAG"
"dist/Lithe-${LITHE_VERSION}-arm64.dmg"
"dist/Lithe-${LITHE_VERSION}-arm64.dmg.sha256"
"dist/Lithe-${LITHE_VERSION}-x86_64.dmg"
"dist/Lithe-${LITHE_VERSION}-x86_64.dmg.sha256"
--repo "$GITHUB_REPOSITORY"
--target "$GITHUB_SHA"
--title "Lithe $RELEASE_TAG"
)
if [[ -f "$notes_file" ]]; then
release_args+=(--notes-file "$notes_file")
else
release_args+=(--generate-notes)
fi
gh release create "${release_args[@]}"
update-cask:
name: Update Homebrew Cask
needs: release
runs-on: macos-14
permissions:
contents: write
pull-requests: write
steps:
- name: Check out the default branch
uses: actions/checkout@v4
with:
ref: main
- name: Download release checksums
env:
GH_TOKEN: ${{ github.token }}
RELEASE_TAG: ${{ needs.release.outputs.tag }}
LITHE_VERSION: ${{ needs.release.outputs.version }}
run: |
checksum_dir="$RUNNER_TEMP/lithe-release"
mkdir -p "$checksum_dir"
gh release download "$RELEASE_TAG" \
--repo "$GITHUB_REPOSITORY" \
--pattern "*.dmg.sha256" \
--dir "$checksum_dir"
echo "CHECKSUM_DIR=$checksum_dir" >> "$GITHUB_ENV"
- name: Update the Cask metadata
env:
LITHE_VERSION: ${{ needs.release.outputs.version }}
run: |
arm_sha=$(awk 'NR == 1 { print $1 }' "$CHECKSUM_DIR/Lithe-${LITHE_VERSION}-arm64.dmg.sha256")
intel_sha=$(awk 'NR == 1 { print $1 }' "$CHECKSUM_DIR/Lithe-${LITHE_VERSION}-x86_64.dmg.sha256")
LITHE_ARM64_SHA256="$arm_sha" \
LITHE_X86_64_SHA256="$intel_sha" \
ruby scripts/update-homebrew-cask.rb
- name: Validate the Cask
run: |
brew tap 1lck/lithe https://github.com/1lck/Lithe-IDEA.git
tap_path="$(brew --repository)/Library/Taps/1lck/homebrew-lithe"
cp "$GITHUB_WORKSPACE/Casks/lithe.rb" "$tap_path/Casks/lithe.rb"
brew style --cask 1lck/lithe/lithe
brew audit --cask --online 1lck/lithe/lithe
- name: Create or update the Cask pull request
env:
GH_TOKEN: ${{ github.token }}
LITHE_VERSION: ${{ needs.release.outputs.version }}
run: |
branch="automation/homebrew-cask-v${LITHE_VERSION}"
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git checkout -b "$branch"
git add Casks/lithe.rb
if git diff --cached --quiet; then
exit 0
fi
git commit -m "lithe ${LITHE_VERSION}"
git fetch origin "$branch" || true
git push --force-with-lease origin "HEAD:refs/heads/$branch"
existing_pr=$(gh pr list \
--repo "$GITHUB_REPOSITORY" \
--base main \
--head "$branch" \
--state open \
--json url \
--jq '.[0].url // empty')
if [[ -n "$existing_pr" ]]; then
echo "Updated existing pull request: $existing_pr"
exit 0
fi
gh pr create \
--repo "$GITHUB_REPOSITORY" \
--base main \
--head "$branch" \
--title "lithe ${LITHE_VERSION}" \
--body "Automated Homebrew Cask metadata update for Lithe ${LITHE_VERSION}."