Build Agents
CodeAnvil build agents run CI/CD pipelines on your own infrastructure. They communicate with the server via SSH, so they can run behind firewalls and NAT without opening any inbound ports.
AdvancedOverview
Key benefits of CodeAnvil build agents:
🔒 Run Behind Firewalls
Agents initiate outbound SSH connections, so they can run behind NAT/firewalls without opening ports.
🔐 Single Authentication
The agent's SSH key is used for both server authentication and git clone operations.
🚀 On-Premise Builds
Build on your own infrastructure for better security, compliance, and performance.
📝 Git-Native Results
Build results are stored as git notes, traveling with your repository forever.
Architecture
Build agents use a polling architecture over SSH:
- Developer pushes code → Server creates a build job
- Agent polls server → Via SSH every 5 seconds
- Agent claims job → Job is marked as running
- Agent clones repo → Using its SSH key
- Agent runs pipeline → Executes steps from .anvil/config.yml
- Agent reports results → Stored as git note
Why Polling?
Polling allows agents to run behind NAT and firewalls. The agent initiates all connections outbound, so no inbound ports need to be opened. This is more secure and simpler than webhook-based systems.
SSH Key Usage
The agent's SSH key serves dual purposes:
- Authentication: Identifies the agent to the server
- Git Access: Clones repositories from the CodeAnvil server
This means the agent needs appropriate repository access — it must be a member of any repository it builds.
Agent Registration
Register a new build agent in two steps:
Create Registration (Server-side)
Admin creates an agent registration on the server:
# Create agent registration anvil agent new "ci-agent-1" # Output: # Agent registered successfully! # Agent ID: 550e8400-e29b-41d4-a716-446655440000 # Registration Code: ABCD1234EFGH5678
Save the registration code — you'll need it for the agent.
Register Agent (Agent-side)
On your build infrastructure, register the agent:
# Register the agent anvil-agent register \ --code ABCD1234EFGH5678 \ --name ci-agent-1 \ --host codeanvil.io \ --port 2222 # This will: # 1. Generate SSH key pair at ~/.anvil-agent/id_ed25519 # 2. Register the public key with the server # 3. Create config file at ~/.anvil-agent/config.toml
Managing Agents
# List all agents anvil agent list # Remove an agent anvil agent remove 550e8400-e29b-41d4-a716-446655440000
Installation
Download
Download the build agent binary for your platform:
# macOS/Linux curl -sSL https://codeanvil.io/agent-install.sh | sh # Or download directly # https://codeanvil.io/downloads/anvil-agent-linux-amd64 # https://codeanvil.io/downloads/anvil-agent-darwin-amd64 # https://codeanvil.io/downloads/anvil-agent-darwin-arm64
Start the Agent
# Start the agent (foreground) anvil-agent start # Start with custom config anvil-agent start --config /path/to/config.toml # Run in background (Linux/macOS) nohup anvil-agent start > agent.log 2>&1 &
Agent Configuration
The agent configuration is stored at ~/.anvil-agent/config.toml:
# ~/.anvil-agent/config.toml [agent] id = "550e8400-e29b-41d4-a716-446655440000" name = "ci-agent-1" [server] host = "codeanvil.io" port = 2222 [ssh] key_path = "~/.anvil-agent/id_ed25519" [polling] interval_seconds = 5
Pipeline Configuration
Define your build pipeline in .anvil/config.yml:
# .anvil/config.yml
branch_protection:
main:
required_signatures: 2
build:
enabled: true
require_success: true
timeout_seconds: 1800
pipeline:
version: "1.0"
env:
GO_VERSION: "1.21"
steps:
- name: Checkout
commands:
- echo "Checked out $ANVIL_COMMIT_HASH"
- name: Setup Go
commands:
- echo "Setting up Go $GO_VERSION"
- go version
- name: Build
commands:
- cd $ANVIL_WORKSPACE
- go build -v ./...
- name: Test
commands:
- cd $ANVIL_WORKSPACE
- go test -v ./...
- name: Lint
commands:
- cd $ANVIL_WORKSPACE
- go vet ./...
Environment Variables
| Variable | Description |
|---|---|
ANVIL_WORKSPACE |
Directory containing the checked out code |
ANVIL_REPO_NAME |
Repository name |
ANVIL_BRANCH |
Branch being built |
ANVIL_COMMIT_HASH |
Full commit hash being built |
ANVIL_COMMIT_SHORT |
Short commit hash (first 7 characters) |
ANVIL_JOB_ID |
Unique job identifier |
ANVIL_REPO_URL |
Repository URL |
Step Execution
- Steps run sequentially in the order defined
- If a step fails (non-zero exit code), the build fails
- Each step runs in the workspace directory
- Environment variables from
envsection are available
Build Results
Build results are stored as git notes on the commit.
Success Format
Build-Status: SUCCESS Build-Job: 550e8400-e29b-41d4-a716-446655440000 Branch: main Completed-At: 2024-01-15T10:30:00Z Output: [Checkout] Checked out abc1234 [Setup Go] go version go1.21.0 linux/amd64 [Build] Built successfully [Test] PASS: all tests passed [Lint] No issues found
Failure Format
Build-Status: FAILED Build-Job: 550e8400-e29b-41d4-a716-446655440001 Branch: main Completed-At: 2024-01-15T10:35:00Z Output: [Checkout] Checked out abc1234 [Setup Go] go version go1.21.0 linux/amd64 [Build] Built successfully [Test] FAIL: TestUserAuth failed Error: expected 200, got 401 at auth_test.go:45
Fetching Build Results
# Fetch the build-results notes ref git fetch origin refs/notes/build-results:refs/notes/build-results # List all build-result notes git notes --ref=refs/notes/build-results list # Show a specific note git notes --ref=refs/notes/build-results show
Troubleshooting
Agent Not Picking Up Jobs
- Agent not registered: Run
anvil-agent registerfirst - SSH key not loaded: Check
~/.anvil-agent/id_ed25519exists - No repository access: Agent needs read access to the repository
- Network issues: Check connectivity to server host:port
Build Fails to Clone Repository
- No repository access: Add agent as repo member with read access
- SSH key mismatch: Ensure agent's key is registered with server
Build Timeout
- Pipeline too slow: Increase
timeout_secondsin config - Step hanging: Add timeouts to individual commands
Viewing Agent Logs
# If running in foreground, logs appear in terminal # If running in background with nohup tail -f agent.log # Check job logs from CLI anvil job logs