Added Makefile #12

Merged
robin merged 3 commits from dev into main 2026-08-21 09:25:05 +02:00
5 changed files with 107 additions and 12 deletions
+1
View File
@@ -1 +1,2 @@
.env .env
bin/
+4 -3
View File
@@ -7,15 +7,16 @@ RUN go mod download
COPY "./internal" "./internal" COPY "./internal" "./internal"
COPY "./cmd" "./cmd" COPY "./cmd" "./cmd"
COPY "Makefile" "./Makefile"
RUN go build -o ./server github.com/robindittmar/dttmr-api/cmd/api-server RUN make build
FROM debian:latest FROM debian:latest
WORKDIR /app WORKDIR /app
COPY .env.docker .env COPY .env.docker .env
COPY --from=build /app/server /app/server COPY --from=build /app/bin/dttmr-api /app/dttmr-api
EXPOSE 8080 EXPOSE 8080
CMD ["/app/server"] CMD ["/app/dttmr-api"]
+84
View File
@@ -0,0 +1,84 @@
# Variables
APP_NAME := dttmr-api
MAIN_DIR := ./cmd/api
BIN_DIR := ./bin
# Dynamically pull version and commit hash from Git
VERSION := $(shell git describe --tags --always --dirty)
COMMIT := $(shell git rev-parse --short HEAD)
BUILD_TIME := $(shell date -u +"%Y-%m-%dT%H:%M:%SZ")
# Linker flags to strip symbols (-s -w) and inject build data into the binary
LDFLAGS := -w -s \
-X 'main.Version=$(VERSION)' \
-X 'main.Commit=$(COMMIT)' \
-X 'main.BuildTime=$(BUILD_TIME)'
# Targets
.PHONY: all help build run test test-cover lint fmt mod clean docker
all: help
## help: Show this help message
help:
@echo "Usage: make [target]"
@echo ""
@echo "Targets:"
@sed -n 's/^##//p' $(MAKEFILE_LIST) | column -t -s ':' | sed -e 's/^/ /'
## build: Compile the binary
build:
@echo "Building $(APP_NAME) version $(VERSION)..."
@CGO_ENABLED=0 go build -ldflags="$(LDFLAGS)" -o $(BIN_DIR)/$(APP_NAME) $(MAIN_DIR)
## run: Run the application directly
run: build
@echo "Starting $(APP_NAME)..."
@$(BIN_DIR)/$(APP_NAME)
## test: Run tests with race detector
test:
@echo "Running tests..."
@go test -v -race -timeout 30s ./...
## test-cover: Run tests and generate coverage report
test-cover:
@echo "Running tests with coverage..."
@go test -coverprofile=coverage.out ./...
@go tool cover -html=coverage.out -o coverage.html
@echo "Coverage report generated at coverage.html"
## lint: Run golangci-lint
lint:
@echo "Running linter..."
@golangci-lint run ./...
## fmt: Format code and organize imports
fmt:
@echo "Formatting code..."
@go fmt ./...
@go run golang.org/x/tools/cmd/goimports@latest -w .
## mod: Tidy and verify dependencies
mod:
@echo "Tidying and verifying module dependencies..."
@go mod tidy
@go mod verify
## clean: Remove build artifacts
clean:
@echo "Cleaning up..."
@rm -rf $(BIN_DIR)
@rm -f coverage.out coverage.html
@go clean
## docker: Build a Docker image
docker:
@echo "Building Docker image for $(APP_NAME):$(VERSION)..."
@docker build -t $(APP_NAME):$(VERSION) -t $(APP_NAME):latest .
## swag: Create swagger documentation
swag:
@echo "Creating swagger documentation for $(APP_NAME)"
@swag init --outputTypes json,yaml -g $(MAIN_DIR)/main.go
+17 -8
View File
@@ -19,6 +19,12 @@ import (
"github.com/robindittmar/dttmr-api/internal/telemetry" "github.com/robindittmar/dttmr-api/internal/telemetry"
) )
var (
Version = "dev"
Commit = "none" // In the Makefile, we called this 'Commit' instead of 'Hash'
BuildTime = "unknown"
)
// @title dttmr-api // @title dttmr-api
// @version 0.1.0 // @version 0.1.0
// @description API documentation for dttmr-api service. // @description API documentation for dttmr-api service.
@@ -37,29 +43,32 @@ import (
// @in Header // @in Header
// @name Authorization // @name Authorization
func main() { func main() {
serviceName := "dttmr-api" if err := run(); err != nil {
serviceVersion := "0.1.0"
if err := run(serviceName, serviceVersion); err != nil {
slog.Error("service crashed") slog.Error("service crashed")
os.Exit(1) os.Exit(1)
} }
} }
func run(serviceName string, serviceVersion string) error { func run() error {
serivceName := "dttmr-api"
time.Local, _ = time.LoadLocation("UTC") time.Local, _ = time.LoadLocation("UTC")
_ = godotenv.Load(".env") _ = godotenv.Load(".env")
setupLogging() setupLogging()
slog.Info("starting service", slog.String("service", serviceName), slog.String("version", serviceVersion)) slog.Info("starting service",
slog.String("service", serivceName),
slog.String("version", Version),
slog.String("commit", Commit),
slog.String("build_time", BuildTime),
)
defer slog.Info("service shutdown!") defer slog.Info("service shutdown!")
cfg := config.Load() cfg := config.Load()
telCfg := telemetry.Config{ telCfg := telemetry.Config{
ServiceName: serviceName, ServiceName: serivceName,
ServiceVersion: serviceVersion, ServiceVersion: Version,
Endpoint: cfg.OTLPEndpoint, Endpoint: cfg.OTLPEndpoint,
Environment: cfg.Environment, Environment: cfg.Environment,
} }
+1 -1
View File
@@ -104,7 +104,7 @@ func (h *ListHandler) AddUserToList(w http.ResponseWriter, r *http.Request) {
// @Tags List // @Tags List
// @Accept json // @Accept json
// @Produce json // @Produce json
// @Param payload body request.RemoveUserFromList true "Remove user from list payload" // @Param payload body request.RemoveUserFromListPayload true "Remove user from list payload"
// @Success 204 {object} nil // @Success 204 {object} nil
// @Error 400 {object} response.ErrorResponse "failed to decode request body" // @Error 400 {object} response.ErrorResponse "failed to decode request body"
// @Error 500 {object} response.ErrorResponse "failed to remove user from list" // @Error 500 {object} response.ErrorResponse "failed to remove user from list"