diff --git a/.github/workflows/build_orca.yml b/.github/workflows/build_orca.yml index 941e6ed57c..fa53d5916b 100644 --- a/.github/workflows/build_orca.yml +++ b/.github/workflows/build_orca.yml @@ -158,14 +158,6 @@ jobs: run: | ./build_release_macos.sh -u -x ${{ !vars.SELF_HOSTED && '-1' || '' }} -a universal -t 10.15 - - name: Delete intermediate per-arch artifacts - if: runner.os == 'macOS' && inputs.macos-combine-only - uses: geekyeggo/delete-artifact@v6 - with: - name: | - OrcaSlicer_Mac_bundle_arm64_${{ github.sha }} - OrcaSlicer_Mac_bundle_x86_64_${{ github.sha }} - # Thanks to RaySajuuk, it's working now - name: Sign app and notary if: github.repository == 'OrcaSlicer/OrcaSlicer' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/')) && runner.os == 'macOS' && inputs.macos-combine-only @@ -176,6 +168,8 @@ jobs: KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} CERTIFICATE_ID: ${{ secrets.MACOS_CERTIFICATE_ID }} run: | + # Load the `retry` helper (retries flaky commands such as `hdiutil create`). + source ${{ github.workspace }}/scripts/retry.sh CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12 KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode --output $CERTIFICATE_PATH @@ -198,7 +192,7 @@ jobs: rm -rf ${{ github.workspace }}/build/universal/OrcaSlicer_dmg/* cp -R ${{ github.workspace }}/build/universal/OrcaSlicer/OrcaSlicer.app ${{ github.workspace }}/build/universal/OrcaSlicer_dmg/ ln -sfn /Applications ${{ github.workspace }}/build/universal/OrcaSlicer_dmg/Applications - hdiutil create -volname "OrcaSlicer" -srcfolder ${{ github.workspace }}/build/universal/OrcaSlicer_dmg -ov -format UDZO OrcaSlicer_Mac_universal_${{ env.ver }}.dmg + retry hdiutil create -volname "OrcaSlicer" -srcfolder ${{ github.workspace }}/build/universal/OrcaSlicer_dmg -ov -format UDZO OrcaSlicer_Mac_universal_${{ env.ver }}.dmg codesign --deep --force --verbose --options runtime --timestamp --entitlements ${{ github.workspace }}/scripts/disable_validation.entitlements --sign "$CERTIFICATE_ID" OrcaSlicer_Mac_universal_${{ env.ver }}.dmg # Create separate OrcaSlicer_profile_validator DMG if the app exists @@ -207,7 +201,7 @@ jobs: rm -rf ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg/* cp -R ${{ github.workspace }}/build/universal/OrcaSlicer/OrcaSlicer_profile_validator.app ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg/ ln -sfn /Applications ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg/Applications - hdiutil create -volname "OrcaSlicer Profile Validator" -srcfolder ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg -ov -format UDZO OrcaSlicer_profile_validator_Mac_universal_${{ env.ver }}.dmg + retry hdiutil create -volname "OrcaSlicer Profile Validator" -srcfolder ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg -ov -format UDZO OrcaSlicer_profile_validator_Mac_universal_${{ env.ver }}.dmg codesign --deep --force --verbose --options runtime --timestamp --entitlements ${{ github.workspace }}/scripts/disable_validation.entitlements --sign "$CERTIFICATE_ID" OrcaSlicer_profile_validator_Mac_universal_${{ env.ver }}.dmg fi @@ -225,11 +219,13 @@ jobs: if: github.ref != 'refs/heads/main' && runner.os == 'macOS' && inputs.macos-combine-only working-directory: ${{ github.workspace }} run: | + # Load the `retry` helper (retries flaky commands such as `hdiutil create`). + source ${{ github.workspace }}/scripts/retry.sh mkdir -p ${{ github.workspace }}/build/universal/OrcaSlicer_dmg rm -rf ${{ github.workspace }}/build/universal/OrcaSlicer_dmg/* cp -R ${{ github.workspace }}/build/universal/OrcaSlicer/OrcaSlicer.app ${{ github.workspace }}/build/universal/OrcaSlicer_dmg/ ln -sfn /Applications ${{ github.workspace }}/build/universal/OrcaSlicer_dmg/Applications - hdiutil create -volname "OrcaSlicer" -srcfolder ${{ github.workspace }}/build/universal/OrcaSlicer_dmg -ov -format UDZO OrcaSlicer_Mac_universal_${{ env.ver }}.dmg + retry hdiutil create -volname "OrcaSlicer" -srcfolder ${{ github.workspace }}/build/universal/OrcaSlicer_dmg -ov -format UDZO OrcaSlicer_Mac_universal_${{ env.ver }}.dmg # Create separate OrcaSlicer_profile_validator DMG if the app exists if [ -f "${{ github.workspace }}/build/universal/OrcaSlicer/OrcaSlicer_profile_validator.app/Contents/MacOS/OrcaSlicer_profile_validator" ]; then @@ -237,9 +233,19 @@ jobs: rm -rf ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg/* cp -R ${{ github.workspace }}/build/universal/OrcaSlicer/OrcaSlicer_profile_validator.app ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg/ ln -sfn /Applications ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg/Applications - hdiutil create -volname "OrcaSlicer Profile Validator" -srcfolder ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg -ov -format UDZO OrcaSlicer_profile_validator_Mac_universal_${{ env.ver }}.dmg + retry hdiutil create -volname "OrcaSlicer Profile Validator" -srcfolder ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg -ov -format UDZO OrcaSlicer_profile_validator_Mac_universal_${{ env.ver }}.dmg fi + # Delete the per-arch bundles only after signing/DMG creation succeeded, so a + # failed run keeps them available for a re-run instead of forcing a full rebuild. + - name: Delete intermediate per-arch artifacts + if: success() && runner.os == 'macOS' && inputs.macos-combine-only + uses: geekyeggo/delete-artifact@v6 + with: + name: | + OrcaSlicer_Mac_bundle_arm64_${{ github.sha }} + OrcaSlicer_Mac_bundle_x86_64_${{ github.sha }} + - name: Upload artifacts mac if: runner.os == 'macOS' && inputs.macos-combine-only uses: actions/upload-artifact@v7 diff --git a/scripts/retry.sh b/scripts/retry.sh new file mode 100644 index 0000000000..a41667dac0 --- /dev/null +++ b/scripts/retry.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +# Sourceable helper: `retry ` runs a command, retrying up to 3 times +# with a 5-minute wait between attempts. Useful for flaky commands such as +# `hdiutil create` intermittently failing with "Resource busy". +retry() { + local attempt=1 max_attempts=3 delay=300 + until "$@"; do + if [ "$attempt" -ge "$max_attempts" ]; then + echo "::error::Command failed after $attempt attempts: $*" + return 1 + fi + echo "Attempt $attempt failed: $*. Retrying in $((delay / 60)) minutes..." + sleep "$delay" + attempt=$((attempt + 1)) + done +}