Merge pull request #383 from sidick/feat/hostsocket-import #2
This file contains hidden or 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: macOS | |
| # Builds the macOS disk image (a universal Copperline.app in a .dmg) and | |
| # uploads it as a workflow artifact on every qualifying change, and attaches it | |
| # to the GitHub Release when a v* tag is pushed. The main CI already builds and | |
| # tests on macOS; this workflow adds the packaging path plus a smoke test of | |
| # the packaged bundle itself (both architectures, including the x86_64 slice | |
| # under Rosetta, which no other job executes), so it is scoped to the code and | |
| # packaging surface that affects the bundle. | |
| # | |
| # The image is intentionally unsigned (no Developer ID, no notarization), so it | |
| # trips Gatekeeper on first launch; the bundled README.txt documents the | |
| # right-click-Open workaround. | |
| on: | |
| push: | |
| branches: [main] | |
| tags: ["v*"] | |
| paths: | |
| - "src/**" | |
| - "vendor/**" | |
| - "assets/**" | |
| - "Cargo.lock" | |
| - "Cargo.toml" | |
| - ".cargo/**" | |
| - "packaging/macos/**" | |
| - ".github/workflows/macos.yml" | |
| pull_request: | |
| paths: | |
| - "src/**" | |
| - "vendor/**" | |
| - "assets/**" | |
| - "Cargo.lock" | |
| - "Cargo.toml" | |
| - ".cargo/**" | |
| - "packaging/macos/**" | |
| - ".github/workflows/macos.yml" | |
| # Manual rebuild. Use this to attach a dmg to a release whose tag predates | |
| # this workflow (the v* tag tree has no macos.yml, so a tag push cannot | |
| # trigger it): run it against a branch with the source parity you want and set | |
| # release_tag to push the built dmg onto that existing release. | |
| workflow_dispatch: | |
| inputs: | |
| release_tag: | |
| description: "Existing release tag to attach the dmg to (e.g. v0.7.0). Leave blank to only upload a workflow artifact." | |
| required: false | |
| default: "" | |
| concurrency: | |
| group: macos-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| build: | |
| name: Build macOS dmg | |
| runs-on: macos-latest | |
| # Needed only by the release-attach step on v* tags. | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: dtolnay/rust-toolchain@stable | |
| with: | |
| # Both Apple architectures so build-dmg.sh can lipo a universal binary. | |
| targets: aarch64-apple-darwin,x86_64-apple-darwin | |
| - uses: Swatinem/rust-cache@v2 | |
| - name: Build dmg | |
| run: packaging/macos/build-dmg.sh | |
| - name: Locate artifact | |
| id: artifact | |
| run: echo "path=$(ls Copperline-*-macos-universal.dmg | head -n1)" >> "$GITHUB_OUTPUT" | |
| - name: Smoke test the packaged app | |
| # The main CI already runs the full suites against the working tree | |
| # on macOS; what it never touches is the artifact users download. | |
| # Mount the freshly built image and boot the app binary straight off | |
| # the read-only volume, working from an empty directory so the | |
| # bundled AROS ROM must be found through the .app's | |
| # Contents/Resources/aros lookup (romsearch.rs), not the source | |
| # tree's assets/aros fallback. Runs the arm64 slice natively and the | |
| # x86_64 slice under Rosetta -- the only place the Intel half of the | |
| # universal binary is ever executed. A capture run opens no window | |
| # or audio device, so a clean exit plus a non-empty PNG proves the | |
| # shipped bundle boots. | |
| run: | | |
| mnt="$RUNNER_TEMP/dmg-mount" | |
| hdiutil attach -nobrowse -readonly -mountpoint "$mnt" \ | |
| "${{ steps.artifact.outputs.path }}" | |
| # Never leave the image mounted for the rest of the job if a | |
| # check below fails; the clean path detaches explicitly. | |
| trap 'hdiutil detach "$mnt" -force 2>/dev/null || true' EXIT | |
| app="$mnt/Copperline.app" | |
| bin="$app/Contents/MacOS/copperline" | |
| # Both slices present, and the ad-hoc signature survived the | |
| # lipo/dmg round-trip (an unsigned arm64 binary will not launch). | |
| lipo -archs "$bin" | |
| lipo -archs "$bin" | grep -q arm64 | |
| lipo -archs "$bin" | grep -q x86_64 | |
| codesign --verify --deep --strict "$app" | |
| smoke="$RUNNER_TEMP/dmg-smoke" | |
| mkdir -p "$smoke" | |
| cd "$smoke" | |
| "$bin" --noaudio --screenshot-after 10 smoke-arm64.png | |
| test -s smoke-arm64.png | |
| # Rosetta is preinstalled on some runner images; this is a fast | |
| # no-op there and installs it where it is not. | |
| sudo softwareupdate --install-rosetta --agree-to-license | |
| arch -x86_64 "$bin" --noaudio --screenshot-after 10 smoke-x86_64.png | |
| test -s smoke-x86_64.png | |
| trap - EXIT | |
| hdiutil detach "$mnt" | |
| - name: Upload smoke screenshots | |
| if: always() | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: macos-smoke-screenshots | |
| path: ${{ runner.temp }}/dmg-smoke/ | |
| if-no-files-found: ignore | |
| - uses: actions/upload-artifact@v7 | |
| with: | |
| name: copperline-macos | |
| path: ${{ steps.artifact.outputs.path }} | |
| if-no-files-found: error | |
| - name: Attach to release | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| files: ${{ steps.artifact.outputs.path }} | |
| - name: Attach to existing release (manual run) | |
| if: github.event_name == 'workflow_dispatch' && inputs.release_tag != '' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| # --clobber so a re-run replaces the asset instead of failing on a | |
| # name clash. | |
| run: gh release upload "${{ inputs.release_tag }}" "${{ steps.artifact.outputs.path }}" --clobber |