Skip to content

Commit afe9711

Browse files
committed
refactor: improve code structure and add Makefile
- Simplify tool descriptions and parameter documentation - Refactor flashduty package for better maintainability - Add Makefile for build automation - Update gitignore and test files
1 parent 9c5e46d commit afe9711

11 files changed

Lines changed: 649 additions & 361 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
.idea
22
bin/
3+
mcpcurl
34

45
# VSCode
56
.vscode/*

Makefile

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
# Build configuration
2+
BINARY_NAME := flashduty-mcp-server
3+
BUILD_DIR := bin
4+
GOLANGCI_LINT_VERSION := v2.2.1
5+
GOLANGCI_LINT := $(BUILD_DIR)/golangci-lint
6+
GCI_VERSION := v0.13.5
7+
GCI := $(BUILD_DIR)/gci
8+
9+
# Go parameters
10+
GOCMD := go
11+
GOBUILD := $(GOCMD) build
12+
GOTEST := $(GOCMD) test
13+
GOFMT := gofmt
14+
MODULE := $(shell go list -m)
15+
16+
# Default target
17+
.PHONY: all
18+
all: check
19+
20+
# ============================================================================
21+
# Development targets
22+
# ============================================================================
23+
24+
.PHONY: build
25+
build: ## Build the binary
26+
$(GOBUILD) -v -o $(BUILD_DIR)/$(BINARY_NAME) ./cmd/$(BINARY_NAME)
27+
28+
.PHONY: run
29+
run: build ## Build and run the server
30+
./$(BUILD_DIR)/$(BINARY_NAME)
31+
32+
# ============================================================================
33+
# Quality assurance targets
34+
# ============================================================================
35+
36+
# Directories to format (excludes openspec which contains reference code)
37+
FMT_DIRS := cmd pkg internal e2e
38+
39+
.PHONY: fmt
40+
fmt: $(GCI) ## Format Go source code and sort imports
41+
$(GOFMT) -s -w $(FMT_DIRS)
42+
$(GCI) write --skip-generated -s standard -s default -s "prefix($(MODULE))" $(FMT_DIRS)
43+
44+
.PHONY: gci
45+
gci: $(GCI) ## Sort imports using gci
46+
$(GCI) write --skip-generated -s standard -s default -s "prefix($(MODULE))" $(FMT_DIRS)
47+
48+
.PHONY: lint
49+
lint: $(GOLANGCI_LINT) ## Run golangci-lint
50+
$(GOLANGCI_LINT) run
51+
52+
.PHONY: lint-fix
53+
lint-fix: $(GOLANGCI_LINT) ## Run golangci-lint with auto-fix
54+
$(GOLANGCI_LINT) run --fix
55+
56+
.PHONY: test
57+
test: ## Run unit tests
58+
$(GOTEST) -race ./...
59+
60+
.PHONY: test-v
61+
test-v: ## Run unit tests with verbose output
62+
$(GOTEST) -race -v ./...
63+
64+
.PHONY: e2e
65+
e2e: ## Run E2E tests (requires FLASHDUTY_E2E_APP_KEY and FLASHDUTY_E2E_BASE_URL)
66+
@if [ -z "$$FLASHDUTY_E2E_APP_KEY" ]; then \
67+
echo "Error: FLASHDUTY_E2E_APP_KEY environment variable is not set"; \
68+
exit 1; \
69+
fi
70+
$(GOTEST) -v --tags e2e ./e2e/... -timeout 10m
71+
72+
.PHONY: e2e-debug
73+
e2e-debug: ## Run E2E tests in debug mode (in-process, no Docker)
74+
@if [ -z "$$FLASHDUTY_E2E_APP_KEY" ]; then \
75+
echo "Error: FLASHDUTY_E2E_APP_KEY environment variable is not set"; \
76+
exit 1; \
77+
fi
78+
FLASHDUTY_E2E_DEBUG=true $(GOTEST) -v --tags e2e ./e2e/... -timeout 10m
79+
80+
# ============================================================================
81+
# Pre-push check (recommended before pushing)
82+
# ============================================================================
83+
84+
.PHONY: check
85+
check: fmt lint test build ## Run all checks (fmt, lint, test, build) - recommended before pushing
86+
87+
.PHONY: ci
88+
ci: check ## Alias for check
89+
90+
# ============================================================================
91+
# Docker targets
92+
# ============================================================================
93+
94+
.PHONY: docker-build
95+
docker-build: ## Build Docker image
96+
docker build -t flashcat/flashduty-mcp-server .
97+
98+
.PHONY: docker-e2e
99+
docker-e2e: docker-build ## Build Docker image and run E2E tests
100+
@if [ -z "$$FLASHDUTY_E2E_APP_KEY" ]; then \
101+
echo "Error: FLASHDUTY_E2E_APP_KEY environment variable is not set"; \
102+
exit 1; \
103+
fi
104+
$(GOTEST) -v --tags e2e ./e2e/... -timeout 10m
105+
106+
# ============================================================================
107+
# Dependency management
108+
# ============================================================================
109+
110+
.PHONY: deps
111+
deps: ## Download Go dependencies
112+
$(GOCMD) mod download
113+
114+
.PHONY: deps-tidy
115+
deps-tidy: ## Tidy Go modules
116+
$(GOCMD) mod tidy
117+
118+
.PHONY: deps-verify
119+
deps-verify: ## Verify Go dependencies
120+
$(GOCMD) mod verify
121+
122+
# ============================================================================
123+
# Tools installation
124+
# ============================================================================
125+
126+
$(BUILD_DIR):
127+
mkdir -p $(BUILD_DIR)
128+
129+
$(GOLANGCI_LINT): $(BUILD_DIR)
130+
@if [ ! -f "$(GOLANGCI_LINT)" ]; then \
131+
echo "Installing golangci-lint $(GOLANGCI_LINT_VERSION)..."; \
132+
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s $(GOLANGCI_LINT_VERSION); \
133+
fi
134+
135+
$(GCI): $(BUILD_DIR)
136+
@if [ ! -f "$(GCI)" ]; then \
137+
echo "Installing gci $(GCI_VERSION)..."; \
138+
GOBIN=$(CURDIR)/$(BUILD_DIR) $(GOCMD) install github.com/daixiang0/gci@$(GCI_VERSION); \
139+
fi
140+
141+
.PHONY: tools
142+
tools: $(GOLANGCI_LINT) $(GCI) ## Install required tools
143+
144+
# ============================================================================
145+
# Cleanup
146+
# ============================================================================
147+
148+
.PHONY: clean
149+
clean: ## Remove build artifacts
150+
rm -rf $(BUILD_DIR)
151+
152+
# ============================================================================
153+
# Help
154+
# ============================================================================
155+
156+
.PHONY: help
157+
help: ## Display this help message
158+
@echo "Available targets:"
159+
@echo ""
160+
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-15s\033[0m %s\n", $$1, $$2}'
161+
@echo ""
162+
@echo "Quick start:"
163+
@echo " make check - Run all pre-push checks (recommended before pushing)"
164+
@echo " make lint - Run linter only"
165+
@echo " make test - Run unit tests only"
166+
@echo " make e2e - Run E2E tests (requires env vars)"

e2e/e2e_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,13 @@ import (
1212
"testing"
1313
"time"
1414

15-
"github.com/flashcatcloud/flashduty-mcp-server/internal/flashduty"
16-
pkgflashduty "github.com/flashcatcloud/flashduty-mcp-server/pkg/flashduty"
17-
"github.com/flashcatcloud/flashduty-mcp-server/pkg/translations"
1815
mcpClient "github.com/mark3labs/mcp-go/client"
1916
"github.com/mark3labs/mcp-go/mcp"
2017
"github.com/stretchr/testify/require"
18+
19+
"github.com/flashcatcloud/flashduty-mcp-server/internal/flashduty"
20+
pkgflashduty "github.com/flashcatcloud/flashduty-mcp-server/pkg/flashduty"
21+
"github.com/flashcatcloud/flashduty-mcp-server/pkg/translations"
2122
)
2223

2324
var (

pkg/flashduty/changes.go

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,7 @@ import (
1212
"github.com/flashcatcloud/flashduty-mcp-server/pkg/translations"
1313
)
1414

15-
const queryChangesDescription = `Query change records with filters.
16-
17-
Change records track deployments, configurations, and other operational changes
18-
that may be correlated with incidents.
19-
20-
**Parameters:**
21-
- change_ids (optional): Comma-separated change IDs for direct lookup
22-
- channel_id (optional): Filter by collaboration space ID
23-
- start_time, end_time (optional): Unix timestamp in seconds.
24-
**Time constraints:**
25-
- start_time must be less than end_time
26-
- Time range (end_time - start_time) must not exceed 31 days (2678400 seconds)
27-
- If not specified, defaults to last 1 hour
28-
- type (optional): Filter by change type
29-
- limit (optional): Max results (1-100, default 20)
30-
31-
**Returns:**
32-
- Change records with enriched channel and creator names`
15+
const queryChangesDescription = `Query change records (deployments, configurations). Useful for correlating changes with incidents.`
3316

3417
// QueryChanges creates a tool to query change records
3518
func QueryChanges(getClient GetFlashdutyClientFn, t translations.TranslationHelperFunc) (tool mcp.Tool, handler server.ToolHandlerFunc) {
@@ -39,12 +22,12 @@ func QueryChanges(getClient GetFlashdutyClientFn, t translations.TranslationHelp
3922
Title: t("TOOL_QUERY_CHANGES_USER_TITLE", "Query changes"),
4023
ReadOnlyHint: ToBoolPtr(true),
4124
}),
42-
mcp.WithString("change_ids", mcp.Description("Comma-separated change IDs")),
43-
mcp.WithNumber("channel_id", mcp.Description("Filter by collaboration space ID")),
44-
mcp.WithNumber("start_time", mcp.Description("Start time (Unix timestamp)")),
45-
mcp.WithNumber("end_time", mcp.Description("End time (Unix timestamp)")),
46-
mcp.WithString("type", mcp.Description("Filter by change type")),
47-
mcp.WithNumber("limit", mcp.Description("Max results (default 20)")),
25+
mcp.WithString("change_ids", mcp.Description("Comma-separated change IDs for direct lookup.")),
26+
mcp.WithNumber("channel_id", mcp.Description("Filter by collaboration space ID.")),
27+
mcp.WithNumber("start_time", mcp.Description("Query start time in Unix timestamp (seconds). Must be < end_time. Max range: 31 days. Defaults to 1 hour ago.")),
28+
mcp.WithNumber("end_time", mcp.Description("Query end time in Unix timestamp (seconds). Defaults to now.")),
29+
mcp.WithString("type", mcp.Description("Filter by change type.")),
30+
mcp.WithNumber("limit", mcp.Description("Maximum number of results to return."), mcp.DefaultNumber(20), mcp.Min(1), mcp.Max(100)),
4831
), func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
4932
ctx, client, err := getClient(ctx)
5033
if err != nil {

0 commit comments

Comments
 (0)