OpenClaw 포크·플러그인을 유지보수하는 팀이라면, 2026년에는 보통 두 갈래를 동시에 봅니다. 업스트림 OpenClaw CI는 macos-node, macos-swift, checks-node-compat-node22에 실제 macOS가 필요하고, GitHub 호스트형 macOS 분·대기열은 계속 부담이 됩니다. 이 글은 전용 원격 Mac 위 GitHub Actions 셀프호스티드 macOS Runner로 위 lane만 돌리고, macOS 라벨 풀과 읽기 전용 Webhook + Lobster 다단계 워크플로로 실패를 triage하는 방법에만 집중합니다. Gateway 18789·온보딩·6개 리전 TCO는 다루지 않습니다(리전·일·월 비용은 macOS Runner 노드·TCO 글 참고). 요금: Mac mini 요금 · 미 동부/서부 결제: 미 동부, 미 서부 · Runner 운영: 도움말 센터.
1) 호스트형 macOS Runner vs 원격 Mac 셀프호스티드: OpenClaw CI 결정표
OpenClaw CI 문서에 따르면 macos-node는 macOS 관련 소스 변경 시 TypeScript 테스트를, macos-swift는 Swift lint/build/test를 담당합니다. 수동 workflow_dispatch는 스마트 범위를 건너뛰고 Node 22 호환을 포함한 전체 그래프를 돌립니다. 업스트림은 Blacksmith macos-latest급 Runner를 쓰기 좋지만, 포크 메인테이너는 그 큐·캐시에 의존하기 어렵고 자체 macOS 태그가 필요합니다.
호스트형 macOS는 PR 빈도가 낮을 때 유리합니다. 원격 M4에 셀프호스티드를 두면 고정 임대 대신 node_modules·DerivedData를 유지해 매일 main·플러그인 계약 shard·로컬에 가까운 pnpm check에 맞추기 쉽습니다. 장기 Gateway/에이전트 배포는 원격 Mac OpenClaw 실전 가이드가 담당하고, 본문은 CI Runner만 다룹니다(한 줄: Gateway는 채팅·도구, Runner는 컴파일·테스트).
| 경로 | OpenClaw CI 적합도 | 주요 비용 |
|---|---|---|
GitHub 호스트형 macos-latest |
업스트림 workflow는 제로옵스; 포크는 큐·캐시 공유 어려움. | 분 과금; 콜드 macos-swift; 피크 대기열. |
| 원격 Mac 셀프호스티드 Runner | label로 macos-node / macos-swift 매핑; Node 22·pnpm store 고정. |
Runner 업그레이드·디스크·병렬 mutex. |
| Linux 호스트만, macOS lane 생략 | 문서·순수 Node PR에는 OK; Swift/macOS 테스트 대체 불가. | 머지 전 수동·스케줄 full macOS dispatch 필요. |
workflow_dispatch full CI를 돌리거나, 포크에서 macos-node 대기가 15분을 넘기면 openclaw-macos-node 태그 1대를 먼저 계획하세요. 플러그인 팀은 dispatch가 일상이면 M4 1석이 약 90일 안에 회수되는 경우가 많습니다(워크플로 크기에 따르며 SLA 약속 아님).셀프호스티드가 맞는 또 다른 신호: preflight가 플러그인 터치마다 macOS lane을 예약하는데, 호스트 Runner는 job 간 캐시를 버려 TypeScript·Swift가 다운로드에 시간을 씁니다. 원격 Mac에서 따뜻한 pnpm store·DerivedData는 CPU가 비슷해도 wall-clock을 줄이는 경우가 많습니다—리포에서 측정 후 좌석을 잡으세요.
2) 환경 체크리스트: Xcode CLT, Node 22, CI 사용자 격리
OpenClaw는 대부분 Node shard를 Linux에서 돌리지만 macos-node·checks-node-compat-node22는 호스트에 Node 22가 필요합니다(CI 문서·로컬 pnpm check와 동일). Runner 호스트에서:
- Xcode Command Line Tools + 팀이 고정한 Xcode minor; Swift lane은 CLT만으로는 부족하고 전체 Xcode 필요.
- CI 사용자 셸에서
fnm또는mise로 Node 22.x; workflow에는actions/setup-node병행. - 업스트림
packageManager와 맞는 pnpm; 캐시는 일상 개발 계정이 아닌 CI 홈 아래. actions-runner전용 Unix 사용자(예:runner)—브라우저·채팅 시크릿과 분리.- 리소스 상한:
memory_pressure관찰; 24GB에서도 두 번째 job 병렬은 측정 후.
xcode-select -p,xcodebuild -version이 문서와 일치.node -v가 v22.x;pnpm -v가 lockfile 정책과 일치.- SSH 로그아웃 후에도
launchd로 Runner 유지. - 여유 디스크 > 25%(DerivedData + pnpm store 급증).
- PAT 분리: Webhook/추론 시크릿 vs 서명 인증서용 GitHub Secrets.
플랫폼 API: Apple Developer Documentation · Node 정책: nodejs.org.
3) Runner 등록 및 macOS 라벨 풀(HowTo)
GitHub 셀프호스티드 Runner 가이드를 따릅니다. OpenClaw 포크에서는 모호한 self-hosted 하나가 아니라 lane별 label을 명시하세요.
# ~/actions-runner ./config.sh --url https://github.com/YOUR_ORG/YOUR_FORK \ --token YOUR_REGISTRATION_TOKEN \ --labels self-hosted,macOS,ARM64,openclaw-macos-node,openclaw-m4-16 \ --name nuv-openclaw-macos-node-01 sudo ./svc.sh install sudo ./svc.sh start
라벨 풀(lane 분리):
openclaw-macos-node— 업스트림macos-node(TypeScript/Vitest macOS 경로).openclaw-macos-swift—macos-swift; CPU/RAM 부담 큼—16GB에서 node와 기본 병렬 금지.openclaw-node22— dispatch 호환·로컬pnpm check스모크용(선택).openclaw-m4-16/openclaw-m4-24— matrix·용량 계획용 하드웨어 tier.
jobs:
macos-node:
runs-on: [self-hosted, macOS, openclaw-macos-node]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- run: pnpm test --filter macos-relevant
코드사인·공증이 있으면 concurrency: { group: codesign-macos, cancel-in-progress: false }로 키체인 동시 잠금을 막으세요. SSH·Runner 추가 메모: 도움말 센터.
리포 vs 조직 Runner: 단일 포크는 위 label의 리포 Runner 1대로 충분합니다. 여러 플러그인이 한 결제 그룹을 쓰면 조직 Runner + 접근 제한을 검토하고, 실험 리포가 Swift lane을 빼앗지 않게 runner group을 쓰세요(Enterprise에서 제공 시).
업그레이드: runbook에 Runner 앱 버전을 고정하세요. GitHub Runner 릴리스마다 job을 drain(./svc.sh stop) → 바이너리 업그레이드 → 재시작 → Idle 확인 후 자동 할당을 다시 켭니다. 오래된 Runner는 「로컬 OK, CI만 실패」의 흔한 원인입니다.
4) OpenClaw CI / dispatch 연동 및 읽기 전용 Webhook
업스트림 preflight는 push/PR 그대로 두고 macOS runs-on만 풀로 바꿉니다. 전체 검증은 CI 문서의 수동 dispatch를 사용합니다:
gh workflow run ci.yml --ref main gh workflow run ci.yml --ref main -f target_ref=your-branch -f include_android=true
읽기 전용 Webhook 추론(단계적): 실패 triage용으로 먼저 읽기 전용 이벤트—workflow_run.completed, check_run.completed, workflow_job.completed—만 구독하고 메타데이터(리포, 브랜치, conclusion, URL)만 저장합니다. Phase 0에서 Contents 쓰기·자동 머지는 요청하지 마세요. 서명 검증 후 에이전트가 로그 URL·Actions API 읽기 scope로 가져가고, 코멘트·label 확장은 승인 정책과 함께 Phase 2로.
| 단계 | Webhook / 권한 | 목적 |
|---|---|---|
| Phase 0 | 읽기 전용 + workflow_run / check_run |
실패 알림, 큐 관찰, Lobster triage 입력. |
| Phase 1 | Actions 로그 읽기 PAT | 실패 job 로그 조각; macos-node shard 연결. |
| Phase 2 | 제한적 쓰기(이슈 코멘트, label) | 자동 ci-failure, 페이저 멘션—리뷰 게이트 필수. |
수신기에는 안정 필드만 로그: workflow_run.id, head_branch, conclusion, run HTML URL. HMAC 실패와 인증 실패를 분리해 on-call이 secret 오설정과 재전송을 구분하게 하세요. Lobster를 붙일 때는 이 필드를 JSON stdin으로 넘기고, 악의적 PR 제목이 도구 선택에 영향을 주는 전체 webhook body는 채팅 프롬프트에 붙이지 마세요.
5) M4 16GB / 24GB 병렬 치트시트(단일 머신 라벨 풀)
OpenClaw macOS lane 기준 실무 가이드(SLA 아님, 리포 의존). 추가 좌석·리전 비용은 Runner 노드·TCO 글—여기서는 6개 리전 표를 넣지 않습니다.
| 구성 | 권장 병렬 | label | 리스크 |
|---|---|---|---|
| M4 16GB | macos-node 1개 또는 가벼운 Swift 1개—동시에 둘 다 아님. |
openclaw-macos-node, openclaw-m4-16 |
Vitest OOM; DerivedData vs pnpm store 디스크 경쟁. |
| M4 24GB | 비피크에 macos-node 1 + Swift check 1; 또는 시차 2× node shard. |
openclaw-m4-24; Swift는 별도 runner 이름 유지. |
병렬 Swift 컴파일도 memory 경고—concurrency group 사용. |
| 머신 2대 | node 1대, swift 1대—label로 라우팅, 한 Runner에 섞지 않음. | 전용 openclaw-macos-swift |
캐시 비공유—호스트마다 deps 예열. |
Nuvcloud는 다중 노드 M4 베어 메탈·RAM/SSD 업그레이드로 고정 CI 좌석에 맞춥니다. 가용·가격: 요금·결제 페이지; 본문은 큐 SLA를 약속하지 않습니다.
SSD는 DerivedData, pnpm store, _work/ 세 곡선을 봅니다. 256GB 단일 lane 포크는 주간 DerivedData 정리로 가능; Swift 무거운 포크는 512GB·요금 마법사 1TB 옵션을 검토하세요. 16GB에서 Vitest 중 node 자식이 죽으면 jetsam을 의심하고, shard를 쪼개기 전에 24GB 호스트로 Swift를 옮기세요.
6) Lobster 워크플로: 재현 가능한 CI 실패 로그 triage
Lobster는 다단계 도구 체인을 승인 지점·resumeToken이 있는 결정적 한 번의 호출로 묶습니다. 「CI 빨강 → 로그 수집 → 분류 → 사람 OK → 요약 게시」에 LLM이 도구를 마음대로 호출하는 것보다 적합합니다. 에이전트 설정에 alsoAllow: ["lobster"] 후 파이프라인을 실행하세요.
{
"action": "run",
"pipeline": "exec --json --shell 'gh run list --workflow ci.yml --limit 5 --json databaseId,conclusion,headBranch' | exec --stdin json --shell 'gh run view $ID --log-failed' | exec --stdin json --shell 'node scripts/ci-triage-summarize.mjs' | approve --preview-from-stdin --limit 3 --prompt '온콜 채널에 요약 게시?'",
"timeoutMs": 120000,
"maxStdoutBytes": 512000
}
.lobster 워크플로 파일로 collect → classify → approval → notify를 나누세요(Lobster 「workflow files」 참고). needs_approval이면:
{
"action": "resume",
"token": "<resumeToken>",
"approve": true
}
재현 triage 습관: 실패마다 run_id, 트리거 label(예: openclaw-macos-node), stderr 첫 블록 해시를 위키에 남기세요. 이슈에 올리기 전 Lobster JSON에서 시크릿을 제거하세요. timeout이면 timeoutMs를 올리거나 「로그 가져오기」와 「LLM 요약」을 분리하세요. 실패 run 7일 읽기 전용 아카이브로 flaky와 회귀를 구분합니다.
팀은 종종 빠른 Lobster(실패 유형만: Node vs Swift vs 인프라)와 느린 Lobster(사람 승인 후 전체 로그) 두 개를 둡니다. OpenClaw CI의 「저렴한 preflight, 필요할 때만 무거운 lane」과 같고, 녹색 run에 토큰을 쓰지 않습니다.
CI에서 이미 gh를 쓰면 같은 PAT scope를 Runner 호스트 Lobster에 쓸 수 있습니다. Phase 0은 actions:read·metadata:read만; 퇴사 시 PAT 교체, Runner 등록 토큰을 API 자격증명으로 재사용하지 마세요.
7) FAQ
Q1: Runner가 Offline?launchd, 토큰 만료, 디스크 full을 확인하세요. GitHub → Settings → Actions → Runners에서 제거 후 config.sh 재실행. 셀프호스티드 Runner 문서 참고.
Q2: macos-node가 Node를 불평?
호스트·setup-node·checks-node-compat-node22를 Node 22로 맞추고, 오래된 global npm 캐시를 비우세요.
Q3: Swift / SDK를 못 찾음?
전체 Xcode 설치, sudo xcodebuild -license accept; CLT만 있는 호스트에서 macos-swift 금지.
Q4: 읽기 전용 Webhook이 403?
secret, TLS, 리버스 프록시 경로, App 이벤트 권한 확인; 게이트웨이가 PR 본문을 명령으로 실행하지 않게 하세요.
Q5: openclaw doctor vs CI 빨강?doctor는 설치/게이트웨이 건강; CI는 Actions 로그. Lobster + gh run view로 triage, onboard로 workflow 디버깅 대체 금지.
Q6: macOS 없이 Linux만?
순수 Node/문서 PR에는 가능하지만 macOS/Swift 변경 머지 전 최소 1회 workflow_dispatch full graph 또는 upstream preflight 의도와 어긋납니다.
Q7: 업스트림과 포크가 Runner 공유?
비권장—runner group·Secrets를 나눠 신뢰 못 하는 포크 스크립트가 서명 재료에 닿지 않게 하세요.
Q8: Lobster invalid JSON?
각 단계 stdout은 JSON; maxStdoutBytes 상향; --json 없이 사람 로그를 다음 단계에 넣지 마세요.
Q9: 호스트와 셀프호스티드 혼합?
가능—예: PR은 호스트, main의 macos-swift는 셀프호스티드(if: 또는 workflow 분리).
더 읽기: 기술 블로그 인덱스. 리전·병렬 좌석·일·월 비용은 macOS Runner 노드·TCO 글을 이어서 보세요.
클라우드 Mac mini에서 OpenClaw CI 풀이 더 안정적
macos-node / macos-swift를 전용 원격 M4에 두면 예측 가능한 연산과 라벨 풀 탄력을 얻습니다. Nuvcloud 베어 메탈 Mac mini는 네이티브 Unix, 24/7 Runner에 낮은 유휴 전력, 24GB RAM·SSD 업그레이드, Swift 전용 2번째 머신 병렬에 맞습니다. 읽기 전용 Webhook + Lobster triage와 맞추면 호스트 큐를 덜 지켜도 됩니다.
OpenClaw 포크 CI 풀을 계획 중이라면 openclaw-macos-node 태그 M4 1대부터—요금·리전 보기, 위 체크리스트대로 Runner·Webhook을 등록하세요.