Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions roles/github_runner_macos_actions_runner/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ github_runner_macos_actions_runner_private_key: ""
github_runner_macos_actions_runner_private_key_op_reference: ""
github_runner_macos_actions_runner_label: exadev-macos
github_runner_macos_actions_runner_name: "{{ inventory_hostname }}-macos"
github_runner_macos_actions_runner_user: github-runner
github_runner_macos_actions_runner_uid: 401
# macOS role accounts require a leading underscore and a UID in 450-499; they do not need an interactive password.
github_runner_macos_actions_runner_user: _github-runner
github_runner_macos_actions_runner_uid: 498
github_runner_macos_actions_runner_version: "2.338.2"
github_runner_macos_actions_runner_sha256: 25a065af409ffa317ab4d5a3b614dd15fc9c40f2172bc1b35a1b1258e919a388
# Repository identity is part of the directory. Changing the repository therefore creates a new unregistered runner rather than leaving a runner enrolled in the old scope.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ argument_specs:
default: ""
github_runner_macos_actions_runner_user:
type: str
default: github-runner
default: _github-runner
github_runner_macos_actions_runner_uid:
type: int
default: 401
default: 498
github_runner_macos_actions_runner_version:
type: str
default: "2.338.2"
Expand Down
13 changes: 9 additions & 4 deletions roles/github_runner_macos_actions_runner/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,16 +84,21 @@
- /usr/bin/false
- -home
- "{{ github_runner_macos_actions_runner_root }}"
- -password
- '*'
no_log: true
- -roleAccount
changed_when: true
when: github_runner_macos_actions_runner_account.rc != 0

- name: Read the runner account after creation
ansible.builtin.command:
argv: [dscl, ., -read, "/Users/{{ github_runner_macos_actions_runner_user }}", UniqueID]
register: github_runner_macos_actions_runner_verified_account
changed_when: false
when: not ansible_check_mode

- name: Require the runner account's expected identity
ansible.builtin.assert:
that:
- "github_runner_macos_actions_runner_account.rc != 0 or github_runner_macos_actions_runner_account.stdout is regex('UniqueID: ' ~ (github_runner_macos_actions_runner_uid | string) ~ '$')"
- "github_runner_macos_actions_runner_verified_account.stdout is regex('UniqueID: ' ~ (github_runner_macos_actions_runner_uid | string) ~ '$')"
quiet: true
when: not ansible_check_mode

Expand Down
29 changes: 29 additions & 0 deletions tests/unit/test_macos_runner_role_account.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""Regression coverage for the native macOS runner's non-interactive account."""

from pathlib import Path
import unittest

import yaml

ROOT = Path(__file__).resolve().parents[2]
ROLE = ROOT / "roles" / "github_runner_macos_actions_runner"


class RunnerRoleAccountTest(unittest.TestCase):
def test_role_account_has_macos_required_name_and_uid(self) -> None:
defaults = yaml.safe_load((ROLE / "defaults" / "main.yml").read_text())
self.assertTrue(defaults["github_runner_macos_actions_runner_user"].startswith("_"))
self.assertIn(defaults["github_runner_macos_actions_runner_uid"], range(450, 500))

def test_creation_is_verified_instead_of_trusting_sysadminctl_exit(self) -> None:
tasks = yaml.safe_load((ROLE / "tasks" / "main.yml").read_text())
block = next(task["block"] for task in tasks if task["name"] == "Configure the enabled macOS runner")
entries = {task["name"]: task for task in block}
argv = entries["Create the unprivileged runner account"]["ansible.builtin.command"]["argv"]
self.assertIn("-roleAccount", argv)
self.assertNotIn("-password", argv)
self.assertIn("github_runner_macos_actions_runner_verified_account.stdout", str(entries["Require the runner account's expected identity"]["ansible.builtin.assert"]))


if __name__ == "__main__":
unittest.main()
Loading