Centralized build orchestration server with web UI
Version 1.0.0
A web-based build orchestration system for Unity projects. Agents register themselves, and you configure everything from the web UI.
ββββββββββββββββββββββββββββββββββββββββββββββββββ
β WEB BROWSER β
β http://buildserver:5000 β
β β
β Pages: β
β - Dashboard (view all agents + jobs) β
β - Agents (configure agents) β
β - Jobs (create/monitor jobs) β
β - Settings (Git, Unity paths, etc.) β
βββββββββββββββββββ¬βββββββββββββββββββββββββββββββ
β HTTP/SignalR
β
ββββββββββββββββββββββββββββββββββββββββββββββββββ
β BUILD SERVER (ASP.NET + Blazor) β
β β
β - REST API β
β - SignalR Hub (real-time) β
β - SQLite Database β
β - Web UI (Blazor Server) β
βββββββββββββββββββ¬βββββββββββββββββββββββββββββββ
β HTTP (polling)
β
ββββββββββββββββββββββββββββββββββββββββββββββββββ
β LOCAL AGENT (Windows Service) β
β β
β - Registers with server on startup β
β - Polls for jobs every 2 seconds β
β - Downloads config from server β
β - Launches Unity β
β - Reports progress β
βββββββββββββββββββ¬βββββββββββββββββββββββββββββββ
β Process
β
ββββββββββββββββββββββββββββββββββββββββββββββββββ
β UNITY EDITOR + BUILD AGENT β
β β
β - Executes builds via Build Wizard β
ββββββββββββββββββββββββββββββββββββββββββββββββββ
β Dashboard - See all agents and jobs at a glance β Agent Management - Register, configure, enable/disable agents β Job Creation - Create builds with web forms β Real-time Progress - Watch builds in real-time (SignalR) β Build History - View past builds and download artifacts β Configuration - All settings via web (no more manual config files!)
β Auto-registration - Agent registers itself on startup β Auto-configuration - Downloads config from server β Heartbeat - Reports status every 5 seconds β Job polling - Checks for new jobs every 2 seconds β Progress reporting - Sends updates in real-time
build-server/
βββ BuildServer/ # Main ASP.NET + Blazor project
β β
β βββ Models/ # Data models
β β βββ Agent.cs # Agent model
β β βββ Job.cs # Job model
β β βββ Build.cs # Build result model
β β βββ AgentConfiguration.cs # Agent config model
β β
β βββ Data/ # Database
β β βββ BuildServerContext.cs # EF Core context
β β βββ Migrations/ # EF migrations
β β
β βββ Controllers/ # REST API
β β βββ AgentsController.cs # Agent endpoints
β β βββ JobsController.cs # Job endpoints
β β βββ ConfigController.cs # Configuration endpoints
β β
β βββ Hubs/ # SignalR
β β βββ BuildHub.cs # Real-time updates
β β
β βββ Services/ # Business logic
β β βββ AgentService.cs # Agent management
β β βββ JobQueueService.cs # Job scheduling
β β βββ ConfigService.cs # Configuration management
β β
β βββ Pages/ # Blazor pages (WEB UI)
β β βββ Index.razor # Dashboard
β β βββ Agents.razor # Agent list + config
β β βββ Jobs.razor # Job creation + monitoring
β β βββ Builds.razor # Build history
β β βββ Settings.razor # Global settings
β β
β βββ Shared/ # Shared components
β β βββ MainLayout.razor # Layout
β β βββ NavMenu.razor # Navigation
β β
β βββ wwwroot/ # Static files
β β βββ css/ # Styles
β β βββ js/ # JavaScript
β β
β βββ appsettings.json # Configuration
β βββ Program.cs # Entry point
β βββ BuildServer.csproj # Project file
β
βββ .gitignore # Git ignore
βββ README.md # This file
βββ LICENSE # License
- .NET 6 SDK
- Windows/Linux/Mac (server can run anywhere)
git clone https://github.com/Eggscape3DAR/build-server.git
cd build-server/BuildServer
dotnet restore
dotnet builddotnet runServer starts at: http://localhost:5000
Open browser: http://localhost:5000
You'll see:
- Dashboard (no agents yet)
- Agents page (empty)
- Jobs page (no jobs yet)
On build machines:
- Download installer from:
http://localhost:5000/download/installer - Run installer
- Enter server URL:
http://localhost:5000 - Agent auto-registers and appears in web UI!
- Go to Agents page
- Click on your agent
- Configure:
- Unity project path
- Git credentials
- Repository URL
- Workspace path
- Artifacts path
- Click Save
Agent downloads config automatically!
- Go to Jobs page
- Click New Job
- Fill form:
- Profile (Android Dev APK, etc.)
- Platform
- Channel
- Branch
- Click Create
Job assigned to available agent automatically!
- Dashboard shows live progress
- SignalR updates every second
- See build status, progress bar, current step
POST /api/agents/register
POST /api/agents/heartbeat
GET /api/agents
GET /api/agents/{id}
PUT /api/agents/{id}
DELETE /api/agents/{id}
POST /api/jobs
GET /api/jobs
GET /api/jobs/{id}
GET /api/jobs/queue # Get next job for agent
POST /api/jobs/{id}/progress # Update progress
POST /api/jobs/{id}/complete # Mark complete
POST /api/jobs/{id}/fail # Mark failed
GET /api/config/{agentId} # Get agent config
POST /api/config/{agentId} # Update agent config
GET /api/builds
GET /api/builds/{id}
GET /api/builds/{id}/download # Download artifacts
CREATE TABLE Agents (
Id INTEGER PRIMARY KEY,
AgentId TEXT UNIQUE NOT NULL,
Name TEXT NOT NULL,
MachineName TEXT,
IpAddress TEXT,
IsOnline BOOLEAN DEFAULT 0,
IsAvailable BOOLEAN DEFAULT 1,
LastHeartbeat DATETIME,
CurrentJobId TEXT,
CreatedAt DATETIME DEFAULT CURRENT_TIMESTAMP
);CREATE TABLE Jobs (
Id INTEGER PRIMARY KEY,
JobId TEXT UNIQUE NOT NULL,
Name TEXT NOT NULL,
ProfileName TEXT NOT NULL,
Platform TEXT NOT NULL,
Channel TEXT NOT NULL,
Status TEXT NOT NULL, -- Queued, Running, Completed, Failed
Progress REAL DEFAULT 0,
AssignedAgentId TEXT,
CreatedAt DATETIME DEFAULT CURRENT_TIMESTAMP,
StartedAt DATETIME,
CompletedAt DATETIME,
ErrorMessage TEXT
);CREATE TABLE AgentConfigurations (
Id INTEGER PRIMARY KEY,
AgentId TEXT UNIQUE NOT NULL,
UnityProjectPath TEXT,
GitUsername TEXT,
GitToken TEXT, -- Encrypted!
RepositoryUrl TEXT,
WorkspacePath TEXT,
ArtifactsPath TEXT,
UpdatedAt DATETIME DEFAULT CURRENT_TIMESTAMP
);CREATE TABLE Builds (
Id INTEGER PRIMARY KEY,
JobId INTEGER NOT NULL,
BuildPath TEXT NOT NULL,
SizeBytes INTEGER,
Duration INTEGER, -- seconds
CreatedAt DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (JobId) REFERENCES Jobs(Id)
);{
"ConnectionStrings": {
"DefaultConnection": "Data Source=buildserver.db"
},
"BuildServer": {
"MaxJobQueueSize": 100,
"AgentTimeoutSeconds": 30,
"JobTimeoutMinutes": 120,
"ArtifactsRetentionDays": 30
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}Shows:
- Total agents (online/offline)
- Total jobs (queued/running/completed)
- Recent builds
- Live activity feed (SignalR)
- List of all agents
- Status indicators (online/offline/busy)
- Configure button β opens config form
- Enable/Disable toggle
- Delete button
- Create new job button β opens form
- Job queue (pending jobs)
- Running jobs with live progress
- Recent jobs
- Build history with filters
- Download artifacts button
- View logs button
- Build details
- Global settings:
- Default Unity version
- Default workspace path
- Git credentials (global)
- Build retention policy
- Notification settings
- Each agent gets unique
AgentIdon first registration - Stored in agent's local config
- Required for all API calls
- Stored encrypted in database
- Never sent to client (web UI)
- Only sent to agent when needed
- Add user accounts
- Login system
- Role-based access (Admin/Builder/Viewer)
From Server to Clients:
// Agent status changed
"AgentUpdated" -> { agentId, isOnline, isAvailable }
// Job progress
"JobProgressUpdated" -> { jobId, progress, currentStep }
// Job completed
"JobCompleted" -> { jobId, success, buildPath }
// New job created
"JobCreated" -> { jobId, name }From Clients to Server:
// Join specific job updates
"JoinJobGroup" -> { jobId }
// Leave job updates
"LeaveJobGroup" -> { jobId }const connection = new signalR.HubConnectionBuilder()
.withUrl("/hubs/build")
.build();
connection.on("JobProgressUpdated", (data) => {
console.log(`Job ${data.jobId}: ${data.progress * 100}%`);
updateProgressBar(data.jobId, data.progress);
});
await connection.start();dotnet run# 1. Publish
dotnet publish -c Release -o /var/www/buildserver
# 2. Create systemd service
sudo nano /etc/systemd/system/buildserver.service[Unit]
Description=Eggscape Build Server
After=network.target
[Service]
Type=notify
WorkingDirectory=/var/www/buildserver
ExecStart=/usr/bin/dotnet /var/www/buildserver/BuildServer.dll
Restart=always
RestartSec=10
SyslogIdentifier=buildserver
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false
[Install]
WantedBy=multi-user.target# 3. Enable and start
sudo systemctl enable buildserver
sudo systemctl start buildserver# 1. Publish
dotnet publish -c Release -o C:\BuildServer
# 2. Install as Windows Service
sc create BuildServer binPath="C:\BuildServer\BuildServer.exe"
sc start BuildServer- Project structure
- Models and database
- REST API controllers
- Blazor web pages
- SignalR hub
- Agent registration
- Job queueing
- Real-time updates
- User authentication (JWT)
- File upload (for keystores, etc.)
- Artifact storage and download
- Email notifications
- Slack/Discord webhooks
- Build statistics and analytics
- Agent scheduling (cron jobs)
- Build templates
- Multi-branch builds
- Pull request builds
- Docker support
- Kubernetes deployment
- Cloud storage (S3/Azure/GCS)
- Advanced metrics
- Custom plugins
- Fork the repo
- Create feature branch
- Commit changes
- Push and create PR
- Documentation: This README
- Issues: GitHub Issues
- Discussions: GitHub Discussions
MIT License - See LICENSE file
Created: October 2025 Version: 1.0.0 Project: Eggscape Build Server Team: Eggscape + Claude
Next: Complete implementation following IMPLEMENTATION_GUIDE.md