Browse Source

Merge pull request #438 from ionite34/macos-build

macos release CI
pull/438/head
Ionite 11 months ago committed by GitHub
parent
commit
6fd3244b75
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 120
      .github/workflows/release.yml
  2. 10
      Build/AppEntitlements.entitlements
  3. 26
      Build/build_macos_app.sh
  4. 35
      Build/codesign_macos.sh
  5. 32
      Build/notarize_macos.sh
  6. BIN
      StabilityMatrix.Avalonia/Assets/AppIcon.icns
  7. 8
      StabilityMatrix.Avalonia/StabilityMatrix.Avalonia.csproj

120
.github/workflows/release.yml

@ -171,11 +171,111 @@ jobs:
with:
name: StabilityMatrix-${{ env.platform-id }}
path: ./out/${{ env.out-name }}
release-macos:
name: Release (macos-arm64)
env:
platform-id: osx-arm64
app-name: "Stability Matrix.app"
out-name: "Stability Matrix.dmg"
runs-on: macos-13
steps:
- uses: actions/checkout@v3
- uses: olegtarasov/get-tag@v2.1.2
if: github.event_name == 'release'
id: tag_name
with:
tagRegex: "v(.*)"
- name: Set Version from Tag
if: github.event_name == 'release'
run: |
echo "Using tag ${{ env.GIT_TAG_NAME }}"
echo "RELEASE_VERSION=${{ env.GIT_TAG_NAME }}" >> $env:GITHUB_ENV
- name: Set Version from manual input
if: github.event_name == 'workflow_dispatch'
run: |
echo "Using version ${{ github.event.inputs.version }}"
echo "RELEASE_VERSION=${{ github.event.inputs.version }}" >> $env:GITHUB_ENV
- name: Set up .NET 8
uses: actions/setup-dotnet@v3
with:
dotnet-version: '8.0.x'
- name: Install dependencies
run: dotnet restore
- name: .NET Msbuild (App)
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
run: >
dotnet msbuild StabilityMatrix.Avalonia
-t:BundleApp -p:UseAppHost=true -p:SelfContained=true
-p:Configuration=Release -p:RuntimeIdentifier=${{ env.platform-id }}
-p:Version=$env:RELEASE_VERSION
-p:PublishDir=out
-p:PublishReadyToRun=true
-p:CFBundleShortVersionString=$env:RELEASE_VERSION
-p:CFBundleName="Stability Matrix"
-p:CFBundleDisplayName="Stability Matrix"
-p:CFBundleVersion=$env:RELEASE_VERSION
-p:SentryOrg=${{ secrets.SENTRY_ORG }} -p:SentryProject=${{ secrets.SENTRY_PROJECT }}
-p:SentryUploadSymbols=true -p:SentryUploadSources=true
- name: Post Build (App)
run: >
mkdir -p signing
mv "./out/Stability Matrix.app" ./signing/${{ env.app-name }}
- name: Codesign app bundle
env:
MACOS_CERTIFICATE: ${{ secrets.PROD_MACOS_CERTIFICATE }}
MACOS_CERTIFICATE_PWD: ${{ secrets.PROD_MACOS_CERTIFICATE_PWD }}
MACOS_CERTIFICATE_NAME: ${{ secrets.PROD_MACOS_CERTIFICATE_NAME }}
MACOS_CI_KEYCHAIN_PWD: ${{ secrets.PROD_MACOS_CI_KEYCHAIN_PWD }}
run: ./Build/codesign_macos.sh "./signing/${{ env.app-name }}"
- name: Notarize app bundle
env:
MACOS_NOTARIZATION_APPLE_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_APPLE_ID }}
MACOS_NOTARIZATION_TEAM_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_TEAM_ID }}
MACOS_NOTARIZATION_PWD: ${{ secrets.PROD_MACOS_NOTARIZATION_PWD }}
run: ./Build/notarize_macos.sh "./signing/${{ env.app-name }}"
- name: Upload Artifact (App)
uses: actions/upload-artifact@v2
with:
name: StabilityMatrix-${{ env.platform-id }}-app
path: ./signing/${{ env.app-name }}
- uses: actions/setup-node@v4
with:
node-version: '20.x'
- name: Install dependencies for dmg creation
run: >
npm install --global create-dmg
brew install graphicsmagick imagemagick
- name: Create dmg
run: >
cd signing
create-dmg ${{ env.app-name }} --overwrite --identity ${{ secrets.PROD_MACOS_CERTIFICATE_NAME }}
# Rename to remove version number
for f in *.dmg; do mv "$f" "${{ env.out-name }}"; done
- name: Upload Artifact (dmg)
uses: actions/upload-artifact@v2
with:
name: StabilityMatrix-${{ env.platform-id }}-dmg
path: ./signing/${{ env.out-name }}
publish-release:
name: Publish GitHub Release
needs: [ release-linux, release-windows ]
needs: [ release-linux, release-windows, release-macos ]
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.github-release == 'true' }}
runs-on: ubuntu-latest
steps:
@ -194,11 +294,12 @@ jobs:
- name: Download Artifacts
uses: actions/download-artifact@v3
# Zip each build
# Zip each build (except macos which is already dmg)
- name: Zip Artifacts
run: |
cd StabilityMatrix-win-x64 && zip -r ../StabilityMatrix-win-x64.zip ./. && cd $OLDPWD
cd StabilityMatrix-linux-x64 && zip -r ../StabilityMatrix-linux-x64.zip ./. && cd $OLDPWD
mv "StabilityMatrix-macos-arm64-dmg/Stability Matrix.dmg" "../StabilityMatrix-macos-arm64.dmg"
- name: Create Github Release
id: create_release
@ -209,6 +310,7 @@ jobs:
files: |
StabilityMatrix-win-x64.zip
StabilityMatrix-linux-x64.zip
StabilityMatrix-macos-arm64.dmg
fail_on_unmatched_files: true
tag_name: v${{ github.event.inputs.version }}
body: ${{ steps.release_notes.outputs.release_notes }}
@ -217,7 +319,7 @@ jobs:
publish-auto-update-github:
name: Publish Auto-Update Release (GitHub)
needs: [ release-linux, release-windows ]
needs: [ release-linux, release-windows, release-macos ]
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.auto-update-release == 'true' && github.event.inputs.auto-update-release-mode == 'github url' }}
runs-on: ubuntu-latest
steps:
@ -246,7 +348,7 @@ jobs:
publish-auto-update-b2:
name: Publish Auto-Update Release (B2)
needs: [ release-linux, release-windows ]
needs: [ release-linux, release-windows, release-macos ]
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.auto-update-release == 'true' && github.event.inputs.auto-update-release-mode == 'upload to b2' }}
runs-on: ubuntu-latest
steps:
@ -261,11 +363,12 @@ jobs:
- name: Download Artifacts
uses: actions/download-artifact@v3
# Zip each build
# Zip each build (except macos which is already dmg)
- name: Zip Artifacts
run: |
cd StabilityMatrix-win-x64 && zip -r ../StabilityMatrix-win-x64.zip ./. && cd $OLDPWD
cd StabilityMatrix-linux-x64 && zip -r ../StabilityMatrix-linux-x64.zip ./. && cd $OLDPWD
mv "StabilityMatrix-macos-arm64-dmg/Stability Matrix.dmg" "../StabilityMatrix-macos-arm64.dmg"
- uses: actions/setup-python@v4
with:
@ -285,6 +388,10 @@ jobs:
echo "StabilityMatrix-linux-x64.zip not found"
exit 1
fi
if [ ! -f StabilityMatrix-macos-arm64.dmg ]; then
echo "StabilityMatrix-macos-arm64.dmg not found"
exit 1
fi
if [ ! -f CHANGELOG.md ]; then
echo "CHANGELOG.md not found"
exit 1
@ -303,4 +410,5 @@ jobs:
--changelog CHANGELOG.md
--win-x64 StabilityMatrix-win-x64.zip
--linux-x64 StabilityMatrix-linux-x64.zip
--macos-arm64 StabilityMatrix-macos-arm64.dmg
-y

10
Build/AppEntitlements.entitlements

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.automation.apple-events</key>
<true/>
</dict>
</plist>

26
Build/build_macos_app.sh

@ -0,0 +1,26 @@
#!/bin/sh
while getopts v: flag
do
case "${flag}" in
v) version=${OPTARG};;
*) echo "Invalid option";;
esac
done
dotnet \
msbuild \
StabilityMatrix.Avalonia \
-t:BundleApp \
-p:RuntimeIdentifier=osx-arm64 \
-p:UseAppHost=true \
-p:Configuration=Release \
-p:CFBundleShortVersionString="$version" \
-p:SelfContained=true \
-p:CFBundleName="Stability Matrix" \
-p:CFBundleDisplayName="Stability Matrix" \
-p:CFBundleVersion="$version" \
-p:PublishDir="$(pwd)/out/osx-arm64/bin" \
# Copy the app out of bin
cp -r ./out/osx-arm64/bin/Stability\ Matrix.app ./out/osx-arm64/Stability\ Matrix.app

35
Build/codesign_macos.sh

@ -0,0 +1,35 @@
#!/bin/sh
echo "Signing file: $1"
# Setup keychain in CI
if [ -n "$CI" ]; then
# Turn our base64-encoded certificate back to a regular .p12 file
echo "$MACOS_CERTIFICATE" | base64 --decode -o certificate.p12
# We need to create a new keychain, otherwise using the certificate will prompt
# with a UI dialog asking for the certificate password, which we can't
# use in a headless CI environment
security create-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain
security import certificate.p12 -k build.keychain -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CI_KEYCHAIN_PWD" build.keychain
fi
# Sign all files
ENTITLEMENTS="AppEntitlements.entitlements"
find "$1/Contents/MacOS/"|while read fname; do
if [[ -f $fname ]]; then
echo "[INFO] Signing $fname"
codesign --force --timestamp -s "$MACOS_CERTIFICATE_NAME" --options=runtime --entitlements "$ENTITLEMENTS" "$fname"
fi
done
echo "[INFO] Signing app file"
codesign --force --timestamp -s "$MACOS_CERTIFICATE_NAME" --options=runtime --entitlements "$ENTITLEMENTS" "$1" -v

32
Build/notarize_macos.sh

@ -0,0 +1,32 @@
#!/bin/sh
echo "Notarizing file: $1"
# Store the notarization credentials so that we can prevent a UI password dialog
# from blocking the CI
echo "Create keychain profile"
xcrun notarytool store-credentials "notarytool-profile" \
--apple-id "$MACOS_NOTARIZATION_APPLE_ID" \
--team-id "$MACOS_NOTARIZATION_TEAM_ID" \
--password "$MACOS_NOTARIZATION_PWD"
# We can't notarize an app bundle directly, but we need to compress it as an archive.
# Therefore, we create a zip file containing our app bundle, so that we can send it to the
# notarization service
echo "Creating temp notarization archive"
ditto -c -k --keepParent "$1" "notarization.zip"
# Here we send the notarization request to the Apple's Notarization service, waiting for the result.
# This typically takes a few seconds inside a CI environment, but it might take more depending on the App
# characteristics. Visit the Notarization docs for more information and strategies on how to optimize it if
# you're curious
echo "Notarize app"
xcrun notarytool submit "notarization.zip" --keychain-profile "notarytool-profile" --wait
# Finally, we need to "attach the staple" to our executable, which will allow our app to be
# validated by macOS even when an internet connection is not available.
echo "Attach staple"
xcrun stapler staple "$1"

BIN
StabilityMatrix.Avalonia/Assets/AppIcon.icns

Binary file not shown.

8
StabilityMatrix.Avalonia/StabilityMatrix.Avalonia.csproj

@ -1,6 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<CFBundleName>Stability Matrix</CFBundleName>
<CFBundleIconFile>Assets/AppIcon.icns</CFBundleIconFile>
<CFBundlePackageType>APPL</CFBundlePackageType>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64;osx-arm64</RuntimeIdentifiers>
@ -138,6 +140,12 @@
<!-- Only for osx-arm64 -->
<AvaloniaResource Include="Assets\macos-arm64\**" Condition="'$(RuntimeIdentifier)' == 'osx-arm64'" />
</ItemGroup>
<ItemGroup>
<None Update="Assets\AppIcon.icns" Condition="'$(RuntimeIdentifier)' == 'osx-arm64'">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Languages\Resources.resx">

Loading…
Cancel
Save