CI/CD Pipeline
Nebula uses GitHub Actions for continuous integration and deployment with semantic versioning.
Overview
┌─────────────────────────────────────────────────────────────────┐
│ GitHub Repository │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Push to main / PR Push tag v* │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ CI Pipeline │ │ Release │ │
│ │ │ │ Pipeline │ │
│ │ • Lint │ │ │ │
│ │ • Test │ │ • Build │ │
│ │ • Build │ │ • Release │ │
│ │ (verify) │ │ • Deploy │ │
│ └─────────────┘ └─────────────┘ │
│ │ │
│ ┌───────────┼───────────┐ │
│ ▼ ▼ ▼ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ GitHub │ │ Deploy │ │ Deploy │ │
│ │ Release │ │ Agent │ │ Daemon │ │
│ │ │ │ (auto) │ │ (manual) │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │ │ │
│ ▼ ▼ │
│ nebulactl.com Production │
│ Server │
└─────────────────────────────────────────────────────────────────┘
Workflows
1. CI Pipeline (.github/workflows/ci.yml)
Triggers:
- Push to
mainbranch - Pull requests to
main
Jobs:
| Job | Description | Duration |
|---|---|---|
lint | Run golangci-lint (v1.64) | ~1-2 min |
test | Run tests with race detector | ~1-2 min |
build | Build verification (4 platforms) | ~2-3 min |
# Matrix build for all platforms
strategy:
matrix:
include:
- goos: linux, goarch: amd64
- goos: linux, goarch: arm64
- goos: darwin, goarch: amd64
- goos: darwin, goarch: arm64
2. Release Pipeline (.github/workflows/release.yml)
Triggers:
- Push tag matching
v*(e.g.,v1.0.0,v1.1.0-beta.1)
Jobs:
┌─────────────────────────────────────────────────────────────────┐
│ Release Pipeline │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ build-linux-amd64│ │ build-other │ │
│ │ │ │ │ │
│ │ Docker + CGO │ │ Cross-compile │ │
│ │ (NVML support) │ │ CGO_ENABLED=0 │ │
│ │ │ │ │ │
│ │ • nebula-agent │ │ • linux/arm64 │ │
│ │ • nebulad │ │ • darwin/amd64 │ │
│ │ • nebulactl │ │ • darwin/arm64 │ │
│ └────────┬─────────┘ └────────┬─────────┘ │
│ │ │ │
│ └──────────┬─────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────┐ │
│ │ release │ │
│ │ │ │
│ │ • Create archives│ │
│ │ • SHA256 checksums │
│ │ • GitHub Release │ │
│ └────────┬─────────┘ │
│ │ │
│ ┌───────────┴───────────┐ │
│ ▼ ▼ │
│ ┌──────────────┐ ┌───────────────┐ │
│ │ deploy-agent │ │ deploy-daemon │ │
│ │ │ │ │ │
│ │ Auto deploy │ │ Manual │ │
│ │ to nebulactl │ │ approval │ │
│ │ .com │ │ required │ │
│ │ │ │ │ │
│ │ Skip for │ │ Environment: │ │
│ │ pre-releases │ │ production │ │
│ └──────────────┘ └───────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
Build Strategy
CGO-enabled Build (linux/amd64)
For full GPU monitoring support via NVIDIA NVML:
# scripts/Dockerfile.release
FROM golang:1.24.0-bookworm AS builder
RUN apt-get update && apt-get install -y gcc libc6-dev
# Build with CGO for NVML
RUN CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build \
-ldflags="-s -w -X 'nebula/version.Version=${VERSION}'" \
-o /dist/nebula-agent ./cmd/nebula-agent
Cross-compilation (other platforms)
Pure Go build without CGO:
CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build \
-ldflags="-s -w -X 'nebula/version.Version=${VERSION}'" \
-o nebula-agent ./cmd/nebula-agent
| Platform | CGO | GPU Support |
|---|---|---|
| linux/amd64 | Enabled | Full (NVML) |
| linux/arm64 | Disabled | Stub |
| darwin/amd64 | Disabled | Stub |
| darwin/arm64 | Disabled | Stub |
Version Injection
Version info is injected at build time via ldflags:
LDFLAGS="-s -w \
-X 'nebula/version.Version=$VERSION' \
-X 'nebula/version.Commit=$COMMIT' \
-X 'nebula/version.BuildDate=$DATE'"
Check version:
./nebula-agent --version
# nebula-agent version 1.0.0 (abc1234) built 2024-01-15T10:30:00Z
Semantic Versioning
Tag Format
| Pattern | Example | Type | Deploy to Server |
|---|---|---|---|
vX.Y.Z | v1.0.0 | Stable | Yes |
vX.Y.Z-* | v1.1.0-beta.1 | Pre-release | No |
vX.Y.Z-rc.N | v2.0.0-rc.1 | Release Candidate | No |
Creating a Release
# Stable release
git tag -a v1.0.0 -m "Release v1.0.0: Initial release"
git push origin v1.0.0
# Pre-release (for testing)
git tag v1.1.0-beta.1
git push origin v1.1.0-beta.1
Release Artifacts
Each release creates:
nebula-v1.0.0-linux-amd64.tar.gz
nebula-v1.0.0-linux-arm64.tar.gz
nebula-v1.0.0-darwin-amd64.tar.gz
nebula-v1.0.0-darwin-arm64.tar.gz
checksums.txt
Archive contents:
nebula-v1.0.0-linux-amd64.tar.gz
├── nebula-agent
├── nebulactl
└── nebulad (Linux only)
Deployment
Agent Deployment (Automatic)
On stable releases, agent binaries are deployed to:
https://nebulactl.com/linux/amd64/nebula-agent
https://nebulactl.com/linux/arm64/nebula-agent
https://nebulactl.com/darwin/amd64/nebula-agent
https://nebulactl.com/darwin/arm64/nebula-agent
Daemon Deployment (Manual Approval)
Nebulad deployment requires manual approval:
- Release workflow runs
deploy-daemonjob waits for approval- Reviewer approves in GitHub Actions
- Binary deployed to production server
First-time setup:
- Creates
/var/lib/nebuladdirectory - Installs systemd service
- Enables autostart
Updates:
- Stops service
- Replaces binary
- Restarts service
GitHub Configuration
Required Secrets
| Secret | Description |
|---|---|
DEPLOY_SSH_KEY | SSH private key (ed25519) for server access |
Required Variables
| Variable | Value |
|---|---|
DEPLOY_HOST | Server IP (e.g., 193.8.184.128) |
Environment Setup
Create production environment:
- Settings → Environments → New environment
- Name:
production - Configure protection rules:
- Required reviewers: Add yourself or team
- Deployment branches: Select
main
SSH Key Setup
# Generate key
ssh-keygen -t ed25519 -C "github-actions-deploy" -f github_deploy_key -N ""
# Add public key to server
ssh root@your-server "cat >> ~/.ssh/authorized_keys" < github_deploy_key.pub
# Add private key to GitHub Secrets as DEPLOY_SSH_KEY
cat github_deploy_key
Local Development
Run CI Locally
# Lint
make ci-lint
# Test
make ci-test
# Build all platforms
make dist
# Show version info
make version
Manual Deploy
# Deploy agent to nebulactl.com
make deploy
# Deploy daemon
make deploy-daemon HOST=192.168.1.100
# Deploy daemon with systemd setup
make deploy-daemon-full HOST=192.168.1.100
Troubleshooting
CI Failed
# Check lint locally
make ci-lint
# Check tests
go test -v -race ./...
# Verify build
go build ./...
Deploy Failed
# Check SSH connection
ssh -i ~/.ssh/deploy_key root@SERVER "echo OK"
# Check service status
ssh root@SERVER "systemctl status nebulad"
# View logs
ssh root@SERVER "journalctl -u nebulad -n 100"
Release Not Deploying
- Check tag format: must be
vX.Y.Z(notv1.0.0-beta) - Check
DEPLOY_HOSTvariable is set - Check
DEPLOY_SSH_KEYsecret is valid - For daemon: approve in GitHub Actions UI
Files Reference
| File | Purpose |
|---|---|
.github/workflows/ci.yml | CI pipeline (lint, test, build) |
.github/workflows/release.yml | Release and deployment |
.github/workflows/deploy-daemon.yml | Manual daemon deploy |
scripts/Dockerfile.release | Docker build for CGO |
scripts/templates/nebulad.service | Systemd unit file |
.golangci.yml | Linter configuration |
Makefile | Build and deploy commands |