Mac CI agent — Woodpecker iOS build infrastructure #166
Labels
No labels
domain:backend
domain:devops
domain:frontend
status:approved
status:in-progress
status:needs-fix
status:qa
type:bug
type:devops
type:feature
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
forgejo_admin/pal-e-platform#166
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Type
Infra
Lineage
project-capacitor-mobile→ Board item (platform infrastructure)Repo
forgejo_admin/pal-e-platformUser Story
As a dev agent
I want CI to build iOS binaries on a Mac agent
So that push-to-TestFlight is automated
Context
MacBook Air M1 registered as Woodpecker agent with
WOODPECKER_FILTER_LABELS=platform=darwin. iOS pipelines route to this agent. Requires: Xcode (App Store), Fastlane (brew install fastlane), Node.js (brew install node).Blocked by: Apple Developer enrollment (pal-e-platform #164).
File Targets
Files to create/modify:
Files NOT to touch:
Acceptance Criteria
platform=darwinlabelTest Expectations
labels: platform: darwin— runs on Macxcodebuild -versionsucceeds on agentfastlane --versionsucceeds on agentConstraints
Checklist
Related
project-capacitor-mobile— iOS Build Pipeline architectureTicket Scope Review -- Issue #166
TEMPLATE COMPLIANCE
Checked against
template-issue(pal-e-docs).### Lineageproject-capacitor-mobile-> Board item. Correct for kanban-over-plans workflow.### Repoforgejo_admin/pal-e-platform### User Story### Contextplatform=darwinlabel routing, tool requirements, blocker noted### File Targets### Acceptance Criteria### Test Expectations### Constraints### Checklist### RelatedExtra section
### Type(Infra) -- additive, no issue.LABEL TRACEABILITY
story:cap-buildproject-capacitor-mobileUser Stories table, keycap-build: "I want CI to build an iOS binary and upload to TestFlight automatically"arch:mac-agentproject-capacitor-mobileArchitecture Component IDs table: "Mac CI Agent -- Woodpecker agent on MacBook M1, platform=darwin label routing"type:infra### Type: Infraconsumer:westsideAll four labels trace to documented entries.
FILE TARGETS ASSESSMENT
Current file targets:
Finding: File targets are vague for an agent to execute. Specific gaps:
No repo file paths listed. This issue lives on
pal-e-platformbut doesn't specify whether any Terraform changes are needed. The Woodpecker agent secret is already managed interraform/main.tf(variablewoodpecker_agent_secret, set viaserver.env.WOODPECKER_AGENT_SECRETandagent.env.WOODPECKER_AGENT_SECRET). The issue should clarify: does the Mac agent use the same shared secret (already in tfvars), or does it need a new agent token generated via the Woodpecker admin API?Mac-side config paths not specified. For a launchd service, the agent needs to know: where does the plist live (
~/Library/LaunchAgents/vs/Library/LaunchDaemons/)? What is the working directory? Where does the binary get installed?"Woodpecker server admin -- add agent token" is ambiguous. Is this a Woodpecker admin UI action, a
woodpecker-clicommand, or a Terraform resource? An agent needs to know which tool to use.Recommendation: Since this is physical-machine setup (not code in a repo), consider whether this is truly agent-executable or if it's a manual checklist for Lucas. If agent-executable, add specific paths and commands. If manual, label it accordingly.
ACCEPTANCE CRITERIA ASSESSMENT
All 4 criteria are testable and verifiable:
DEPENDENCY CHECK
matchsetup requires it). Consider whether the blocker should be relaxed to allow agent registration work to proceed in parallel.ITEMS TO FIX
File Targets need specificity. Either:
Clarify agent secret handling. State whether the Mac agent uses the existing
woodpecker_agent_secretfromterraform/variables.tfor needs a new token.Consider relaxing #164 blocker. Agent registration + Xcode/Node install do not require Apple Developer enrollment. Only Fastlane match setup does. This could unblock the bulk of the work.
VERDICT: NEEDS WORK
Three items above need addressing before this ticket moves to next_up. The user story and acceptance criteria are solid. The label traceability is perfect. The gap is in file targets specificity -- an agent picking this up would not know whether to write Terraform, run shell commands on a Mac, or click through a web UI.
Ticket Fix (QA review remediation)
File Targets (updated)
Files to create/modify on MacBook Air M1 (not archbox):
/Library/LaunchDaemons/com.woodpecker.agent.plist— launchd service definition/usr/local/bin/woodpecker-agent(or Homebrew-managed)Files to verify on archbox (Woodpecker server):
Files NOT to touch:
terraform/— agent registration is API-only, not IaCAgent Secret Handling (clarified)
Generate a NEW agent token via Woodpecker admin API (
POST /api/agents). Do NOT reuse the existing Linux agent secret — each agent gets its own token. Store the token in the launchd plist environment variables.Blocker Scope (corrected)
Apple Developer enrollment (#164) is NOT a blocker for this ticket. Xcode installs from the Mac App Store with a free Apple ID. Node.js installs via Homebrew. Fastlane installs via Homebrew. Agent registration doesn't need Apple Developer.
Removed dependency on #164. This ticket is unblocked.
Ticket Re-Review -- Issue #166
Re-review of the fix comment (2026-03-26T14:35:06Z) against the 3 findings from the original scope review (2026-03-26T10:00:43Z).
FINDING 1: File Targets Need Specificity
Original finding: File targets were vague ("Woodpecker agent config on MacBook", "Woodpecker server admin -- add agent token"). An agent would not know whether to write Terraform, run shell commands, or use a web UI.
Fix assessment: RESOLVED.
The fix comment now specifies:
/Library/LaunchDaemons/com.woodpecker.agent.plist-- concrete launchd path on MacBook/usr/local/bin/woodpecker-agent-- concrete binary path (with Homebrew alternative noted)I verified the "no Terraform changes" claim against the codebase. The existing Woodpecker config in
terraform/main.tf(lines 742-782) manages an in-cluster Linux agent via Helm values. The Mac agent is external to the cluster and would be registered via the Woodpecker admin API -- no.tffile changes required. Claim is accurate.FINDING 2: Agent Secret Handling Ambiguous
Original finding: Unclear whether the Mac agent uses the existing
woodpecker_agent_secretfromterraform/variables.tfor needs a new token.Fix assessment: RESOLVED.
The fix explicitly states: "Generate a NEW agent token via Woodpecker admin API (
POST /api/agents). Do NOT reuse the existing Linux agent secret -- each agent gets its own token."This is the correct approach. The existing
woodpecker_agent_secret(described interraform/variables.tf:157-161as "Persistent shared secret for Woodpecker JWT signing") is used by the in-cluster Linux agent. Woodpecker supports per-agent tokens alongside the shared secret. The Mac agent using its own API-generated token is cleaner and more auditable than sharing the cluster secret with an external machine.FINDING 3: Blocker Scope Too Broad
Original finding: Issue claimed #164 (Apple Developer enrollment) was a blocker, but Xcode, Node.js, Fastlane, and agent registration all work without an Apple Developer account. Only Fastlane
match(signing) requires enrollment.Fix assessment: RESOLVED.
The fix states: "Apple Developer enrollment (#164) is NOT a blocker for this ticket. Xcode installs from the Mac App Store with a free Apple ID. Node.js installs via Homebrew. Fastlane installs via Homebrew. Agent registration doesn't need Apple Developer. Removed dependency on #164."
This is correct. The original issue body still contains "Blocked by: Apple Developer enrollment (pal-e-platform #164)" in the Context section, but the fix comment serves as the amendment. The ticket is unblocked.
LABEL TRACEABILITY
Verified board item #369 on
board-capacitor-mobile:story:cap-buildproject-capacitor-mobileUser Stories, keycap-build: "I want CI to build an iOS binary and upload to TestFlight automatically"arch:mac-agentproject-capacitor-mobileArchitecture Component IDs: "Mac CI Agent -- Woodpecker agent on MacBook M1, platform=darwin label routing"type:infra### Type: Infraconsumer:westsideAll labels trace cleanly to documented entries in
project-capacitor-mobile.REMAINING NITS
Original issue body not amended. The fix lives in a comment, but the issue body still says "Blocked by: Apple Developer enrollment (pal-e-platform #164)" and has the old vague file targets. For an agent picking this up, they would need to read both the body AND the fix comment. Consider editing the issue body to incorporate the fixes. Not a blocker -- the fix comment is authoritative.
Agent binary installation method. The fix mentions
/usr/local/bin/woodpecker-agentwith "(or Homebrew-managed)" but does not specify which. Homebrew does not have a Woodpecker agent formula -- the binary is typically downloaded from the Woodpecker releases page. Minor ambiguity, but an agent could resolve this from Woodpecker docs.VERDICT: APPROVED
All 3 original findings are resolved. File targets are concrete with specific paths. Agent secret handling is explicitly per-agent via API. Blocker dependency on #164 is correctly removed. Label traceability to
project-capacitor-mobileis confirmed for bothstory:cap-buildandarch:mac-agent. Ticket is ready fornext_up.Progress (2026-03-26)
Completed via SSH from archbox → lucass-macbook-air-1 (Tailscale)
ldraney@lucass-macbook-air-1via Tailscale SSH (required one-time browser auth)/usr/bin/xcodebuild/opt/homebrew/bin/node(Homebrew)brew install fastlane~/bin/woodpecker-agent(downloaded from GitHub releases, darwin_arm64)~/Library/LaunchAgents/com.woodpecker.agent.plistwrite attempted, SSH dropped before confirmationlaunchctl loadafter plist verifiedAgent Configuration
Key Decisions
~/bin/install path — avoids sudo for/usr/local/binWOODPECKER_AGENT_SECRETshared between server and agent (not per-agent tokens)WOODPECKER_BACKEND=local— runs build steps natively on macOS (not Docker), required forxcodebuildRemaining
launchctl load ~/Library/LaunchAgents/com.woodpecker.agent.plistplatform: darwin