diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 44e1f50..8af42d2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,6 +21,7 @@ on: options: - all - windows-x64 + - macos-arm64 permissions: contents: write # needed to create / update the GitHub Release @@ -29,6 +30,7 @@ jobs: build: if: >- github.ref != 'refs/heads/build/windows-x64' && + github.ref != 'refs/heads/build/macos-arm64' && (github.event_name != 'workflow_dispatch' || inputs.platform == 'all') name: ${{ matrix.name }} runs-on: ${{ matrix.os }} @@ -338,6 +340,122 @@ jobs: if-no-files-found: error retention-days: 14 + build-macos-arm64: + if: >- + github.ref == 'refs/heads/build/macos-arm64' || + (github.event_name == 'workflow_dispatch' && inputs.platform == 'macos-arm64') + name: macos-arm64 + runs-on: macos-14 + steps: + - uses: actions/checkout@v4 + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + targets: aarch64-apple-darwin + + - name: Cache cargo build + uses: Swatinem/rust-cache@v2 + with: + key: aarch64-apple-darwin + + - name: Build (release) + run: cargo build --release --target aarch64-apple-darwin + + - name: Set package metadata + shell: bash + run: | + set -euo pipefail + VERSION="$(sed -n 's/^version = "\([^"]*\)"/\1/p' Cargo.toml | head -n 1)" + if [ -z "$VERSION" ]; then + echo "Unable to read the package version from Cargo.toml" >&2 + exit 1 + fi + PACKAGE_VERSION="${VERSION}-dev.${GITHUB_SHA:0:7}" + echo "VERSION=$VERSION" >> "$GITHUB_ENV" + echo "PACKAGE_VERSION=$PACKAGE_VERSION" >> "$GITHUB_ENV" + echo "PACKAGE_BASENAME=ashell-v${PACKAGE_VERSION}-macos-arm64" >> "$GITHUB_ENV" + + - name: Package macOS app, DMG, and portable archive + shell: bash + run: | + set -euo pipefail + APP_ROOT="$RUNNER_TEMP/${PACKAGE_BASENAME}-app" + DMG_ROOT="$RUNNER_TEMP/${PACKAGE_BASENAME}-dmg" + APP="$APP_ROOT/ashell.app" + CONTENTS="$APP/Contents" + + mkdir -p "$CONTENTS/MacOS" "$CONTENTS/Resources" "$DMG_ROOT" dist + cp "target/aarch64-apple-darwin/release/ashell" "$CONTENTS/MacOS/ashell" + chmod 755 "$CONTENTS/MacOS/ashell" + cp "assets/icons/ashell.icns" "$CONTENTS/Resources/ashell.icns" + + cat > "$CONTENTS/Info.plist" < + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ashell + CFBundleIconFile + ashell.icns + CFBundleIdentifier + dev.ashell.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ashell + CFBundlePackageType + APPL + CFBundleShortVersionString + ${VERSION} + CFBundleVersion + ${GITHUB_RUN_NUMBER} + LSMinimumSystemVersion + 12.0 + NSHighResolutionCapable + + + + EOF + + printf 'APPL????' > "$CONTENTS/PkgInfo" + plutil -lint "$CONTENTS/Info.plist" + + codesign --force --deep --sign - "$APP" + codesign --verify --deep --strict --verbose=2 "$APP" + + ditto -c -k --sequesterRsrc --keepParent \ + "$APP" "dist/${PACKAGE_BASENAME}-portable.zip" + ditto "$APP" "$DMG_ROOT/ashell.app" + ln -s /Applications "$DMG_ROOT/Applications" + hdiutil create \ + -volname "ashell ${VERSION}" \ + -srcfolder "$DMG_ROOT" \ + -ov \ + -format UDZO \ + "dist/${PACKAGE_BASENAME}.dmg" + + EXPECTED_ARCH="arm64" + ACTUAL_ARCHS="$(lipo -archs "$CONTENTS/MacOS/ashell")" + if [ "$ACTUAL_ARCHS" != "$EXPECTED_ARCH" ]; then + echo "Expected $EXPECTED_ARCH binary, found $ACTUAL_ARCHS" >&2 + exit 1 + fi + + shasum -a 256 dist/* + + - name: Upload workflow artifact + uses: actions/upload-artifact@v4 + with: + name: macos-arm64 + path: dist/* + if-no-files-found: error + retention-days: 14 + publish: name: Publish Release needs: build