# Builds gitea-macos-runner on the macOS runners gitea-macos-runner itself # provides. The repo is its own integration test: if this workflow goes green, # a guest image really can check out a repo, run a Swift toolchain, and produce # a signed .app. name: build on: push: branches: [main] pull_request: workflow_dispatch: jobs: build: # The bare label the daemon registers with. There is no container image # here: jobs run in `:host` mode, directly in an ephemeral macOS 27 guest # as the admin account, and the guest is destroyed afterwards. runs-on: macos-arm64 # Well under the scheduler's 120-minute job ceiling. A clean release build # plus the test suite is a few minutes; anything approaching an hour means # something is wedged and the VM should be reclaimed rather than left # holding one of the host's two guest slots. timeout-minutes: 60 steps: # Needs Node.js in the guest, which the base image provisions. - uses: actions/checkout@v4 # First thing in the log, deliberately. Every plausible failure of this # workflow that is not the code's fault is a toolchain that did not make # it into the image — Command Line Tools missing, or present but not # selected. Printing this up front turns "swift: command not found" # forty lines down into a one-glance diagnosis. - name: toolchain versions run: | sw_vers swift --version xcode-select -p # RunnerCoreTests only. RunnerHost is compiled (it is a dependency) but # never exercised: nothing here touches Virtualization.framework at # runtime, which matters because the guest cannot nest VMs. - name: unit tests run: swift test # Release build, .app assembly, signature. `make sign` looks for a # Developer ID identity and falls back to ad-hoc when there is none — which # is always the case here, since this runs in a throwaway guest with no # keychain and no certificate. That fallback is why this step works # unattended, and it is deliberately not treated as a failure: the point of # the CI signature is to prove the entitlement survives, not to produce a # distributable artifact. Release builds are signed on a real host. - name: build and sign the app bundle run: make all # Proves the two things a bare `swift build` cannot: that the entitlement # survived signing, and that the runtime resources were copied in. An # .app missing either compiles perfectly and then fails at the first # `image build` — exactly the class of breakage worth catching in CI. - name: verify the bundle # `grep … && echo` would be a check that cannot fail: bash exempts # every command in an `&&` list except the last one from `set -e`, so a # bundle signed with no entitlements at all would sail through. The # grep therefore stands alone, as the step's own pass/fail. run: | codesign -d --entitlements - --xml .build/GiteaMacosRunner.app | grep -q virtualization echo "entitlement OK" ls .build/GiteaMacosRunner.app/Contents/Resources/ # Deliberately absent: `doctor`, `vm`, `daemon`, and `image` steps. # # All four either start a VM or check the host's ability to start one, and this # job is already running inside a guest. Virtualization.framework does not # nest, so those steps would not be a stricter test — they would be a # guaranteed failure that says nothing about the code. The host-side behaviour # they cover is verified on a real host, not here.