-
Notifications
You must be signed in to change notification settings - Fork 0
Development
- Go 1.25+ (see
go.mod) - A
.envfile with at leastGOOGLE_CLIENT_ID,GOOGLE_CLIENT_SECRET, andDB_FILEPATH
# Direct
go run .
# Build and run
make run
# With hot reload (installs Air if needed)
make devThe project includes an .air.toml configuration for Air, which watches for file changes and rebuilds automatically:
- Watches:
.go,.html,.css,.jsfiles - Builds to
./tmp/main - Proxy on port 8090 forwarding to app on port 8080
make dev| Target | Command | Description |
|---|---|---|
build |
go build -o ticketpulse . |
Build the binary |
run |
Build + ./ticketpulse
|
Build and run |
dev |
air (installs if missing) |
Hot reload development |
test |
go test -race ./... |
Run all tests with race detector |
cover |
Tests + coverage report | Run tests with coverage and print total |
lint |
golangci-lint run ./... |
Run linter |
vet |
go vet ./... |
Run go vet |
clean |
Remove binary and coverage | Clean build artifacts |
docker-build |
docker build -t tylerconlee/ticketpulse:latest . |
Build Docker image |
# All tests with race detector
go test -race ./...
# With coverage
make cover
# Verbose
go test -v ./...In-memory SQLite: Model and integration tests use db.InitDB(":memory:") for a fresh database with all migrations applied. No external database is needed.
database := db.InitDB(":memory:")
defer database.Close()
models.SetDatabase(database)Mock HTTP servers: Zendesk API tests use httptest.Server to simulate API responses:
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode(responseData)
}))
defer server.Close()
zc := services.NewZendeskClientForTesting("test", "test@test.com", "token", server.Client())Mock Clock: Time-dependent tests use the MockClock interface to control time:
clock := &services.MockClock{}
clock.Set(time.Date(2024, 1, 15, 9, 0, 0, 0, time.UTC))
ps := services.NewPollingServiceWithClock(db, sse, slack, clock, cache)testify: All tests use github.com/stretchr/testify for assertions:
assert.Equal(t, expected, actual)
require.NoError(t, err)httptest for handlers: Handler tests use httptest.NewRecorder and httptest.NewRequest:
req := httptest.NewRequest("GET", "/alerts", nil)
w := httptest.NewRecorder()
handler.AlertsPageHandler(w, req, slackService)
assert.Equal(t, http.StatusOK, w.Code)| Directory | Test Focus |
|---|---|
models/*_test.go |
Database CRUD, data model logic |
services/*_test.go |
Business logic, API interactions, SLA matching |
handlers/*_test.go |
HTTP handlers, middleware, request/response |
db/*_test.go |
Database interface, sqlx operations |
logging/*_test.go |
Logger initialization, file output |
integration/ |
End-to-end flows (SLA, daily summary) |
Integration tests in the integration/ directory test complete flows:
-
sla_flow_test.go-- SLA cache deduplication, label changes, metric types, alert log creation -
daily_summary_flow_test.go-- Summary deduplication, work day settings, filter modes, scheduler timing
These use in-memory SQLite and do not require external services.
The project uses golangci-lint v2 with the following linters enabled:
| Linter | Description |
|---|---|
errcheck |
Check for unchecked errors (includes type assertions) |
govet |
Report suspicious constructs |
staticcheck |
Static analysis checks |
unused |
Find unused code |
ineffassign |
Detect ineffectual assignments |
gosimple |
Suggest code simplifications |
gocritic |
Opinionated linter (diagnostic + performance tags) |
misspell |
Find commonly misspelled words |
Excluded paths: static, templates, testutil
Formatter: gofmt
Limits: 50 issues per linter, 5 same issues
make lintThe project has two CI workflows:
Triggers on push/PR to main:
- Checkout code
- Set up Go (version from
go.mod) go mod tidy- Run tests (
go test ./... -v) - Build binary (
go build -o ticketpulse) - Build Docker image
-
On push to main only: Log in to Docker Hub and push
tylerconlee/ticketpulse:latest
Triggers on push/PR to main/master:
Test job:
- Checkout, setup Go, download and verify dependencies
- Build all packages
- Run tests with race detector and coverage:
go test -v -race -coverprofile=coverage.out ./... - Display coverage report
- Coverage threshold: Fails if total coverage drops below 30%
- Upload coverage artifact
Lint job:
- Checkout, setup Go
- Run golangci-lint v2.11 via
golangci-lint-action@v7
The tylerconlee/ticketpulse:latest image is automatically published on every push to main via the ci.yml workflow. It requires DOCKER_USERNAME and DOCKER_PASSWORD secrets configured in the repository.
TicketPulse -- Zendesk + Slack integration for SLA alerting, tag-based notifications, and daily ticket summaries.
TicketPulse Documentation
Getting Started
Core Concepts
Integrations
Application
Operations
Development