Skip to content

Setup checklist

Two phases: (§1) the one-time GitHub-side setup the user must do, and (§2) the per-PC setup done on each of the 4 home Windows PCs.


§1 — GitHub App setup (USER ACTION — do this once)

You are creating one GitHub App, installing it on the WorkWingman repo, and generating one private key per PC (so each PC's key can be revoked independently). Copy-pasteable steps:

1.1 Create the App

  1. Go to https://github.com/settings/apps (or your org's Developer settings) → New GitHub App.
  2. GitHub App name: workwingman-ci-runner (must be globally unique; append a suffix if taken).
  3. Homepage URL: anything, e.g. https://github.com/andrewjonesdev/WorkWingman.
  4. Webhook: uncheck Active (we don't use webhooks).
  5. Repository permissions — set exactly:
  6. Administration: Read and write ← REQUIRED. This is what lets the App mint runner registration tokens.
  7. (Everything else: leave No access.)

    Rationale: the registration-token endpoint requires repo Administration:write.

  8. Where can this GitHub App be installed?Only on this account.
  9. Click Create GitHub App.

1.2 Record the App ID

  • On the App's General page, note the App ID (a number). You'll put it in each PC's config.psd1 as AppId.

1.3 Install the App on the repo

  1. On the App page → Install App (left nav) → Install next to your account.
  2. Choose Only select repositories → select WorkWingman.
  3. Click Install.
  4. After install, the browser URL is https://github.com/settings/installations/<INSTALLATION_ID>. Note that Installation ID (a number) → InstallationId in config.psd1. (Alternatively: App page → Advanced, or GET /repos/{owner}/{repo}/installation.)

1.4 Generate ONE private key per PC

On the App's General page → Private keysGenerate a private key. This downloads a .pem. Do this 4 times (one per PC): mainpc, gaming, streaming, greatroom. Rename each so you can tell them apart, e.g. ww-app-mainpc.pem, ww-app-gaming.pem, etc.

GitHub keys are PKCS#1 (BEGIN RSA PRIVATE KEY). The watchdog imports both PKCS#1 and PKCS#8, so no conversion is needed.

1.5 Master-store each key in the KeePass vault

Put all 4 .pem files into your KeePass .kdbx vault (one entry per PC, e.g. attach the file or paste the PEM into a protected note). The vault is the master copy. You will export one at a time to each PC in §2, then shred the plaintext there.

Nothing else is required in GitHub. There is no PAT, no repo secret, no self-hosted-runner group config needed for this design.

1.5a ORG MODE variant (org-level registration)

If you are deploying org mode (one pool serving every repo in an org, e.g. andrewjonesdev-tools) instead of the per-repo setup above, §1.1–§1.3 change: the App needs the organization permission "Self-hosted runners: Read and write" (a distinct grant from repo Administration: RW), must be installed on the org, and the org installation has its own InstallationId. Follow the dedicated deploy checklist in docs/ORG-MIGRATION.md — §1.4/§1.5 (per-PC keys + vault custody) and all of §2 below are identical in both modes, except config.psd1 additionally sets Org (see config.example.psd1).


§2 — Per-PC setup (repeat on each of the 4 PCs)

Prereqs on the PC: Docker Desktop (Linux-container mode), git, and PowerShell 7 (pwsh) or Windows PowerShell 5.1.

2.1 Clone this repo (locally; not the WorkWingman repo)

git clone <this-repo> C:\ci\workwingman-ci-runner
cd C:\ci\workwingman-ci-runner

2.2 Create the per-PC config

Copy-Item config.example.psd1 config.psd1
# Edit config.psd1: set AppId, InstallationId, PcName (mainpc|gaming|streaming|greatroom),
# and confirm Repo + KeyRef + label defaults. config.psd1 is .gitignored.

2.3 Provision this PC's App key into DPAPI

Export this PC's .pem from the KeePass vault to a temp path, then:

pwsh ./skill/scripts/Provision-Key.ps1 -PemPath C:\temp\ww-app-<pc>.pem
This DPAPI-encrypts the key to config.KeyRef (bound to this user+machine) and shreds the plaintext PEM. Confirm the temp PEM is gone.

2.4 Build the Linux runner image

docker build -f docker/Dockerfile.linux -t ww-runner:linux .
(Optional: set the real RUNNER_SHA256 build-arg to enforce the checksum gate.)

2.5 Install the Windows host runner

pwsh ./skill/scripts/Install-WindowsRunner.ps1

2.6 Register the watchdogs as scheduled tasks (elevated)

pwsh ./skill/scripts/Register-WatchdogTasks.ps1
Start-ScheduledTask -TaskName WorkWingmanRunner-Linux-<pc>
Start-ScheduledTask -TaskName WorkWingmanRunner-Windows-<pc>
The tasks run at logon, auto-restart on crash, and keep exactly one of each runner alive.

2.7 Verify

pwsh ./skill/scripts/Runner-Status.ps1
You should see this PC's ww-<pc>-<guid> runners appear as online / idle in the pool listing, plus local container/process state. Repeat §2 on all 4 PCs.

Blocked-on-real-App note: steps 2.3–2.7 only fully succeed once §1's real App ID, installation ID, and private key exist. Until then the scripts parse and run up to the first live GitHub call, which will 401/404 with placeholder IDs.