Adds automatic release after successful build #23
Workflow file for this run
This file contains 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: Build Packages | ||
on: | ||
push: | ||
tags: | ||
- "v*.*" # Triggers on tags like v1.0.0, v0.1.0, etc. | ||
jobs: | ||
build: | ||
timeout-minutes: 60 | ||
strategy: | ||
matrix: | ||
os: [windows-latest, macos-13, macos-latest] | ||
runs-on: ${{ matrix.os }} | ||
outputs: | ||
artifact_paths: ${{ steps.collect_artifacts.join(', ') }} | ||
Check failure on line 19 in .github/workflows/build.yml
|
||
steps: | ||
- name: Set required env vars (Unix) | ||
if: runner.os == 'macOS' | ||
env: | ||
ARTIFACT_PATH: "BDRC Tibetan OCR.dmg" | ||
shell: bash | ||
run: | | ||
OS=$(echo "$RUNNER_OS" | tr '[:upper:]' '[:lower:]') | ||
ARCH=$(echo "$RUNNER_ARCH" | tr '[:upper:]' '[:lower:]') | ||
VERSION="${GITHUB_REF_NAME#v}" | ||
ARTIFACT_NAME="bdrc_ocr_${OS}_${ARCH}_${VERSION}" | ||
echo "VERSION=$VERSION" >> $GITHUB_ENV | ||
echo "ARTIFACT_NAME=$ARTIFACT_NAME" >> $GITHUB_ENV | ||
echo "ARTIFACT_PATH=$ARTIFACT_PATH" >> $GITHUB_ENV | ||
- name: Set required env vars (Windows) | ||
if: runner.os == 'Windows' | ||
env: | ||
ARTIFACT_PATH: WindowsBuild/BDRC Tibetan OCR.exe | ||
shell: pwsh | ||
run: | | ||
$OS = $env:RUNNER_OS.ToLower() | ||
$ARCH = $env:RUNNER_ARCH.ToLower() | ||
$VERSION = $env:GITHUB_REF_NAME -replace '^v','' | ||
$ARTIFACT_NAME = "bdrc_ocr_${OS}_${ARCH}_${VERSION}" | ||
echo "VERSION=${VERSION}" | Out-File -FilePath $env:GITHUB_ENV -Append | ||
echo "ARTIFACT_NAME=${ARTIFACT_NAME}" | Out-File -FilePath $env:GITHUB_ENV -Append | ||
echo "ARTIFACT_PATH=$env:ARTIFACT_PATH" | Out-File -FilePath $env:GITHUB_ENV -Append | ||
- name: Cache Git LFS files | ||
uses: actions/cache@v4 | ||
with: | ||
path: .git/lfs | ||
key: lfs-${{ hashFiles('.git/objects/info/lfs/**') }} | ||
restore-keys: | | ||
lfs- | ||
- uses: actions/checkout@v4 | ||
with: | ||
lfs: true | ||
- name: Pull LFS objects | ||
run: git lfs pull | ||
- name: ccache | ||
uses: hendrikmuhs/[email protected] | ||
- name: Cache Nuitka | ||
uses: actions/cache@v4 | ||
with: | ||
path: ${{ github.workspace }}/.nuitka_cache | ||
key: ${{ runner.os }}-nuitka | ||
- name: Set up Python | ||
uses: actions/setup-python@v5 | ||
with: | ||
python-version: "3.10" | ||
- name: Install dependencies | ||
run: | | ||
python -m pip install --upgrade pip | ||
pip install nuitka | ||
pip install pyside6 | ||
pip install -r requirements.txt | ||
pyside6-rcc resources.qrc -o resources.py | ||
- name: Install create-dmg (macOS) and set up certificate for | ||
if: ${{ runner.os == 'macOS' }} | ||
env: | ||
CERTIFICATE_BASE64: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_P12_BASE64 }} | ||
CERTIFICATE_PASSWORD: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_PASSWORD }} | ||
run: | | ||
brew install create-dmg | ||
echo $CERTIFICATE_BASE64 | base64 --decode > certificate.p12 | ||
security create-keychain -p "" build.keychain | ||
security default-keychain -s build.keychain | ||
security unlock-keychain -p "" build.keychain | ||
security set-keychain-settings -t 3600 -u build.keychain | ||
security import certificate.p12 -k build.keychain -P $CERTIFICATE_PASSWORD -T /usr/bin/codesign | ||
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "" build.keychain | ||
security find-identity -v -p codesigning build.keychain | ||
- name: Build with Nuitka (macOS) | ||
if: ${{ runner.os == 'macOS' }} | ||
env: | ||
APPLE_DEVELOPER_ID: ${{ secrets.APPLE_DEVELOPER_ID }} | ||
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} | ||
APPLE_PASSWORD: ${{ secrets.APPLE_JF_PASSWORD }} | ||
run: | | ||
# Build app | ||
python -m nuitka --standalone \ | ||
--output-dir=macOSBuild \ | ||
--plugin-enable=pyside6 \ | ||
--company-name="Buddhist Digital Resource Center" \ | ||
--product-name="BDRC Tibetan OCR" \ | ||
--file-version='${{ env.VERSION }}' \ | ||
--product-version='${{ env.VERSION }}' \ | ||
--macos-app-name="BDRC Tibetan OCR" \ | ||
--macos-create-app-bundle \ | ||
--include-data-dir=./Assets=Assets \ | ||
--include-data-dir=./Models=Models \ | ||
main.py | ||
mv "macOSBuild/main.app" "macOSBuild/BDRC Tibetan OCR.app" | ||
# Set up icon | ||
RESOURCES_PATH="macOSBuild/BDRC Tibetan OCR.app/Contents/Resources" | ||
mkdir -p "$RESOURCES_PATH" | ||
cp "logo.icns" "$RESOURCES_PATH/" | ||
/usr/libexec/PlistBuddy -c "Add :CFBundleIconFile string logo" "macOSBuild/BDRC Tibetan OCR.app/Contents/Info.plist" | ||
touch "macOSBuild/BDRC Tibetan OCR.app" | ||
# Sign components | ||
find "macOSBuild/BDRC Tibetan OCR.app" -type f \( -name "*.dylib" -o -name "*.so" -o -name "*.onnx" \) -exec \ | ||
codesign --force --verify --options=runtime --timestamp \ | ||
--sign "Developer ID Application: Jeremy Frere ($APPLE_TEAM_ID)" \ | ||
--identifier "io.bdrc.ocrapp" {} + | ||
# Sign app bundle | ||
codesign --force --verify --options=runtime --timestamp --deep \ | ||
--sign "Developer ID Application: Jeremy Frere ($APPLE_TEAM_ID)" \ | ||
--identifier "io.bdrc.ocrapp" \ | ||
"macOSBuild/BDRC Tibetan OCR.app" | ||
# Create and notarize zip | ||
ditto -c -k --keepParent "macOSBuild/BDRC Tibetan OCR.app" "macOSBuild/app.zip" | ||
# Function to retry notarization | ||
retry_notarize() { | ||
local file="$1" | ||
local max_attempts=3 | ||
local attempt=1 | ||
local wait_time=30 | ||
while [ $attempt -le $max_attempts ]; do | ||
echo "Notarization attempt $attempt of $max_attempts for $file..." | ||
if xcrun notarytool submit "$file" \ | ||
--apple-id "$APPLE_DEVELOPER_ID" \ | ||
--password "$APPLE_PASSWORD" \ | ||
--team-id "$APPLE_TEAM_ID" \ | ||
--wait; then | ||
echo "Notarization successful for $file" | ||
return 0 | ||
fi | ||
echo "Notarization attempt $attempt failed for $file" | ||
if [ $attempt -lt $max_attempts ]; then | ||
echo "Waiting $wait_time seconds before next attempt..." | ||
sleep $wait_time | ||
# Increase wait time for next attempt | ||
wait_time=$((wait_time * 2)) | ||
fi | ||
attempt=$((attempt + 1)) | ||
done | ||
echo "All notarization attempts failed for $file" | ||
return 1 | ||
} | ||
# Notarize app with retry | ||
if ! retry_notarize "macOSBuild/app.zip"; then | ||
echo "Failed to notarize app after all attempts" | ||
exit 1 | ||
fi | ||
# Staple app | ||
xcrun stapler staple "macOSBuild/BDRC Tibetan OCR.app" | ||
# Create and sign DMG | ||
create-dmg \ | ||
--volname "BDRC Tibetan OCR" \ | ||
--volicon "logo.icns" \ | ||
--window-pos 200 120 \ | ||
--window-size 800 400 \ | ||
--icon-size 100 \ | ||
--icon "BDRC Tibetan OCR.app" 200 190 \ | ||
--hide-extension "BDRC Tibetan OCR.app" \ | ||
--app-drop-link 600 185 \ | ||
"BDRC Tibetan OCR.dmg" \ | ||
"macOSBuild/BDRC Tibetan OCR.app" | ||
# Sign and notarize DMG | ||
codesign --force --verify --options=runtime --timestamp \ | ||
--sign "Developer ID Application: Jeremy Frere ($APPLE_TEAM_ID)" \ | ||
--identifier "io.bdrc.ocrapp" \ | ||
"BDRC Tibetan OCR.dmg" | ||
# Notarize DMG with retry | ||
if ! retry_notarize "BDRC Tibetan OCR.dmg"; then | ||
echo "Failed to notarize DMG after all attempts" | ||
exit 1 | ||
fi | ||
xcrun stapler staple "BDRC Tibetan OCR.dmg" | ||
- name: Build with Nuitka (Windows) | ||
if: ${{ runner.os == 'Windows' }} | ||
run: | | ||
python -m nuitka --standalone ` | ||
--onefile ` | ||
--windows-console-mode=disable ` | ||
--assume-yes-for-downloads ` | ||
--output-dir=WindowsBuild ` | ||
--output-filename="BDRC Tibetan OCR.exe" ` | ||
--plugin-enable=pyside6 ` | ||
--windows-icon-from-ico=logo.ico ` | ||
--company-name="Buddhist Digital Resource Center" ` | ||
--product-name="Tibetan OCR App" ` | ||
--file-version=${{ env.VERSION }} ` | ||
--product-version=${{ env.VERSION }} ` | ||
--include-data-dir=./Assets=Assets ` | ||
--include-data-dir=./Models=Models ` | ||
main.py | ||
- name: Upload artifact | ||
uses: actions/upload-artifact@v4 | ||
id: upload | ||
with: | ||
name: ${{ env.ARTIFACT_NAME }} | ||
path: ${{ env.ARTIFACT_PATH }} | ||
compression-level: 0 | ||
- name: Collect artifact path | ||
id: collect_artifacts | ||
run: echo "::set-output name=path::${{ steps.upload.outputs.artifact-path }}" | ||
create-release: | ||
needs: build | ||
runs-on: ubuntu-latest | ||
permissions: | ||
contents: write | ||
steps: | ||
- name: Download all artifacts | ||
uses: actions/download-artifact@v4 | ||
with: | ||
path: artifacts | ||
- name: Create Release | ||
uses: softprops/action-gh-release@v1 | ||
with: | ||
name: Release ${{ github.ref_name }} | ||
draft: false | ||
prerelease: false | ||
generate_release_notes: true | ||
files: artifacts/**/* |