When creating a pull-request you should:
- Open an issue first: Confirm that the change or feature will be accepted
- Update API documentation: If your pull-request adding/modifying an API request, make sure you update the Swagger documentation (
api-docs.yml) - Run API Tests: If your pull request modifies the API make sure you run the integration tests using dredd.
- Check out the
developbranch - Install Go. Go must be >= v1.21 for all the tools we use to work
- Install MySQL / MariaDB (Optional)
- Install node.js
-
Set up
GOPATH-
Set
GOPATHin your shell (for example, in your.bashrcor.zshrc):export GOPATH=$HOME/go export PATH=$PATH:$GOPATH/bin
-
Create required directory and switch to it:
mkdir -p $GOPATH/src/github.com/semaphoreui cd $GOPATH/src/github.com/semaphoreui
-
-
Clone semaphore (with submodules)
git clone --recursive git@github.com:semaphoreui/semaphore.git && cd semaphore -
Install dev dependencies
go install github.com/go-task/task/v3/cmd/task@latest task depsWindows users will additionally need to manually install goreleaser from https://github.com/goreleaser/goreleaser/releases
-
Create database if you want to use MySQL or PostgreSQL (Semaphore also supports SQLite, which does not require additional setup)
BoltDB removed in 2.19: The embedded BoltDB backend was removed. Use SQLite for local development or MySQL/PostgreSQL for production. Existing
database.boltdbfiles must be migrated before upgrading.echo "create database semaphore;" | mysql -uroot -p -
Compile, set up & run
task build go run cli/main.go setup go run cli/main.go service --config ./config.json
Open localhost:3000
Note: for Windows, you may need Cygwin to run certain commands because the reflex package probably doesn't work on Windows.
You may encounter issues when running task watch, but running task build etc... will still be OK.
Dredd is used for API integration tests, if you alter the API in any way you must make sure that the information in the api docs matches the responses.
As Dredd and the application database config may differ it expects it's own config.json in the .dredd folder.
-
Build Dredd hooks:
task dredd:hooks
-
Install Dredd globally
npm install -g dredd
-
Create
./dredd/config.jsonfor Dredd. It must contain database connection same as used in Semaphore server. You can use any supported database dialect for tests. For example SQLite.{ "sqlite": { "host": "/tmp/database.sqlite" }, "dialect": "sqlite" } -
Start Semaphore server (add
--configoption if required): -
./bin/semaphore server
-
Start Dredd tests
dredd --config ./.dredd/dredd.local.yml
Semaphore uses logrus for structured logging. Log level and selective debug filtering are controlled via CLI flags or environment variables (flags take precedence).
| Flag / env var | Values |
|---|---|
--log-level / SEMAPHORE_LOG_LEVEL |
DEBUG, INFO, WARN, ERROR, FATAL, PANIC |
SEMAPHORE_LOG_LEVEL=DEBUG ./bin/semaphore server --config ./config.jsonWhen the log level is DEBUG, you can narrow output to specific subsystems using a
Node.js debug-style namespace filter. The filter
only acts on DEBUG-level entries; it does not raise the log level on its own.
| Flag / env var | Example values |
|---|---|
--debug-filter / SEMAPHORE_DEBUG_FILTER |
runner, task_*, *,-db |
Syntax: comma- or space-separated patterns; * is a wildcard; a leading - excludes a
namespace (exclusions win over includes).
# Only runner subsystem debug output
SEMAPHORE_LOG_LEVEL=DEBUG SEMAPHORE_DEBUG_FILTER=runner ./bin/semaphore server
# All task-related namespaces except database tracing
SEMAPHORE_LOG_LEVEL=DEBUG SEMAPHORE_DEBUG_FILTER='task_*,*,-db' ./bin/semaphore serverDebug entries use a context field as the namespace. Common namespaces:
| Namespace | Subsystem |
|---|---|
runner |
Runner registration, job hand-off, polling |
task_pool |
Task queueing, scheduling, capacity |
task_runner |
Individual task lifecycle |
git |
Repository clone/checkout |
terraform |
Terraform/OpenTofu invocation |
schedule |
Cron schedules, dedup, fire/skip |
db / migration |
Database queries and migrations |
websocket |
Real-time UI sockets |
When syslog is enabled (syslog in config.json), the same filter applies to syslog
output as well as stdout.
-
Install Semaphore MCP
pipx install semaphore-mcp
Upgrade:
pipx upgrade semaphore-mcp
-
Install Cursor Agent CLI
curl https://cursor.com/install -fsSL | bashYou can check the agent using command:
cursor-agent --version
-
Set up MCP server for Cursor
Add following block to
~/.cursor/mcp.json:{ "mcpServers": { "semaphore": { "command": "semaphore-mcp", "args": [], "env": { "SEMAPHORE_URL": "http://localhost:3000", "SEMAPHORE_API_TOKEN": "<TOKEN>" } } } } -
Run tests
cd tests/manual ./run.sh