diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a7cacebb..df86f68c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,45 +2,17 @@ name: CI Pipeline on: push: - branches: [ main, develop ] + branches: [ main ] pull_request: - branches: [ main, develop ] + branches: [ main ] env: GO_VERSION: '1.23.x' jobs: - # Lint and Format Check - lint: - name: Lint and Format - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Go - uses: actions/setup-go@v5 - with: - go-version: ${{ env.GO_VERSION }} - - - name: Install golangci-lint - run: | - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.3.1 - - - name: Run golangci-lint - run: golangci-lint run --timeout=5m - - - name: Check Go formatting - run: | - if [ "$(gofmt -s -l . | wc -l)" -gt 0 ]; then - echo "The following files are not properly formatted:" - gofmt -s -l . - exit 1 - fi - - # Build check - build: - name: Build Check + # Build, Lint, and Validate + build-lint-validate: + name: Build, Lint, and Validate runs-on: ubuntu-latest steps: - name: Checkout code @@ -64,20 +36,28 @@ jobs: - name: Download dependencies run: go mod download - - name: Build application + - name: Install golangci-lint run: | - go build -v ./cmd/... + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.3.1 + + - name: Run lint + run: make lint + + - name: Validate schemas and examples + run: make validate + + - name: Build application + run: make build - name: Check for vulnerabilities run: | go install golang.org/x/vuln/cmd/govulncheck@latest govulncheck ./... - # Unit Tests - unit-tests: - name: Unit Tests + # All Tests + tests: + name: Tests runs-on: ubuntu-latest - needs: [lint, build] steps: - name: Checkout code uses: actions/checkout@v4 @@ -100,9 +80,8 @@ jobs: - name: Download dependencies run: go mod download - - name: Run unit tests - run: | - go test -v -race -coverprofile=coverage.out -covermode=atomic ./internal/... + - name: Run all tests + run: make test-all - name: Upload coverage to Codecov uses: codecov/codecov-action@v4 @@ -111,54 +90,3 @@ jobs: flags: unittests name: codecov-unit fail_ci_if_error: false - - # Integration Tests - integration-tests: - name: Integration Tests - runs-on: ubuntu-latest - needs: [lint, build] - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Go - uses: actions/setup-go@v5 - with: - go-version: ${{ env.GO_VERSION }} - - - name: Cache Go modules - uses: actions/cache@v4 - with: - path: | - ~/.cache/go-build - ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-go- - - - name: Download dependencies - run: go mod download - - - name: Run integration tests - run: | - chmod +x ./tests/integration/run.sh - ./tests/integration/run.sh - - # Overall status check - test-summary: - name: Test Summary - runs-on: ubuntu-latest - needs: [unit-tests, integration-tests] - if: always() - steps: - - name: Check test results - run: | - if [[ "${{ needs.unit-tests.result }}" == "success" && "${{ needs.integration-tests.result }}" == "success" ]]; then - echo "✅ All tests passed!" - exit 0 - else - echo "❌ Some tests failed:" - echo " Unit tests: ${{ needs.unit-tests.result }}" - echo " Integration tests: ${{ needs.integration-tests.result }}" - exit 1 - fi diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml deleted file mode 100644 index 83eda0ea..00000000 --- a/.github/workflows/integration-tests.yml +++ /dev/null @@ -1,52 +0,0 @@ -name: Integration Tests - -on: - push: - branches: [ main, develop ] - pull_request: - branches: [ main, develop ] - -jobs: - integration-tests: - name: Run Integration Tests - runs-on: ubuntu-latest - - strategy: - matrix: - go-version: ['1.23.x'] - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Go - uses: actions/setup-go@v5 - with: - go-version: ${{ matrix.go-version }} - - - name: Cache Go modules - uses: actions/cache@v4 - with: - path: | - ~/.cache/go-build - ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-go- - - - name: Download dependencies - run: go mod download - - - name: Verify dependencies - run: go mod verify - - - name: Set up test environment - run: | - # Create any necessary directories for test data - mkdir -p /tmp/test-data - - - name: Run integration tests - run: | - # Run integration tests using the existing script - chmod +x ./tests/integration/run.sh - ./tests/integration/run.sh diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml deleted file mode 100644 index 18d0f5c4..00000000 --- a/.github/workflows/unit-tests.yml +++ /dev/null @@ -1,63 +0,0 @@ -name: Unit Tests - -on: - push: - branches: [ main, develop ] - pull_request: - branches: [ main, develop ] - -jobs: - unit-tests: - name: Run Unit Tests - runs-on: ubuntu-latest - - strategy: - matrix: - go-version: ['1.23.x'] - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Go - uses: actions/setup-go@v5 - with: - go-version: ${{ matrix.go-version }} - - - name: Cache Go modules - uses: actions/cache@v4 - with: - path: | - ~/.cache/go-build - ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-go- - - - name: Download dependencies - run: go mod download - - - name: Verify dependencies - run: go mod verify - - - name: Run unit tests - run: | - # Run unit tests with coverage, excluding integration tests - go test -v -race -coverprofile=coverage.out -covermode=atomic ./internal/... - - - name: Generate coverage report - run: go tool cover -html=coverage.out -o coverage.html - - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v4 - with: - file: ./coverage.out - flags: unittests - name: codecov-umbrella - fail_ci_if_error: false - - - name: Upload coverage artifact - uses: actions/upload-artifact@v4 - with: - name: coverage-report - path: coverage.html diff --git a/.gitignore b/.gitignore index b586d0b4..e9d3da27 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,5 @@ cmd/registry/registry validate-examples validate-schemas .idea/ +coverage.out +coverage.html diff --git a/.golangci.yml b/.golangci.yml index e86a4f39..b50c99ee 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -83,6 +83,11 @@ linters: - return nestif: min-complexity: 8 + revive: + rules: + - name: use-any + severity: error + disabled: false exclusions: generated: lax presets: @@ -122,4 +127,4 @@ formatters: paths: - third_party$ - builtin$ - - examples$ \ No newline at end of file + - examples$ diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..a8c11c23 --- /dev/null +++ b/Makefile @@ -0,0 +1,70 @@ +.PHONY: help build test test-unit test-integration test-endpoints test-publish test-all lint lint-fix validate validate-schemas validate-examples check dev-local dev-compose clean publisher + +# Default target +help: ## Show this help message + @echo "Available targets:" + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " %-20s %s\n", $$1, $$2}' + +# Build targets +build: ## Build the registry application + go build ./cmd/registry + +publisher: ## Build the publisher tool + cd tools/publisher && ./build.sh + +# Test targets +test-unit: ## Run unit tests with coverage + go test -v -race -coverprofile=coverage.out -covermode=atomic ./internal/... + go tool cover -html=coverage.out -o coverage.html + @echo "Coverage report generated: coverage.html" + +test: ## Run unit tests (use 'make test-all' to run all tests) + @echo "⚠️ Running unit tests only. Use 'make test-all' to run both unit and integration tests." + @$(MAKE) test-unit + +test-integration: ## Run integration tests + ./tests/integration/run.sh + +test-endpoints: ## Test API endpoints (requires running server) + ./scripts/test_endpoints.sh + +test-publish: ## Test publish endpoint (requires BEARER_TOKEN env var) + ./scripts/test_publish.sh + +test-all: test-unit test-integration ## Run all tests (unit and integration) + +# Validation targets +validate-schemas: ## Validate JSON schemas + ./tools/validate-schemas.sh + +validate-examples: ## Validate examples against schemas + ./tools/validate-examples.sh + +validate: validate-schemas validate-examples ## Run all validation checks + +# Lint targets +lint: ## Run linter (includes formatting) + golangci-lint run --timeout=5m + +lint-fix: ## Run linter with auto-fix (includes formatting) + golangci-lint run --fix --timeout=5m + +# Combined targets +check: lint validate test-all ## Run all checks (lint, validate, unit tests) + @echo "All checks passed!" + +# Development targets +dev-compose: ## Start development environment with Docker Compose (builds image automatically) + docker compose up --build + +dev-local: ## Run registry locally (requires MongoDB) + go run cmd/registry/main.go + +# Cleanup +clean: ## Clean build artifacts and coverage files + rm -f registry + rm -f coverage.out coverage.html + cd tools/publisher && rm -f publisher + + +.DEFAULT_GOAL := help diff --git a/README.md b/README.md index 6210cc63..b25f539b 100644 --- a/README.md +++ b/README.md @@ -36,11 +36,11 @@ For development: ## Running -The easiest way to get the registry running is to use `docker compose`. This will setup the MCP Registry service, import the seed data and run MongoDB in a local Docker environment. +The easiest way to get the registry running is uses docker compose. This will setup the MCP Registry service, import the seed data and run MongoDB in a local Docker environment. ```bash # Run the registry and MongoDB with docker compose -docker compose up --build +make dev-compose ``` This will start the MCP Registry service and MongoDB with Docker, exposing it on port 8080. @@ -51,7 +51,7 @@ If you prefer to run the service locally without Docker, you can build and run i ```bash # Build a registry executable -go build ./cmd/registry +make build ``` This will create the `registry` binary in the current directory. You'll need to have MongoDB running locally or with Docker. @@ -59,19 +59,58 @@ By default, the service will run on `http://localhost:8080`. ## Development +### Available Make Targets + +To see all available make targets: + +```bash +make help +``` + +Key development commands: + +```bash +# Build targets +make build # Build the registry application +make publisher # Build the publisher tool + +# Development +make dev-compose # Start development environment with Docker Compose +make dev-local # Run registry locally (requires MongoDB) + +# Testing +make test-unit # Run unit tests with coverage report +make test-integration # Run integration tests +make test-endpoints # Test API endpoints (requires running server) +make test-publish # Test publish endpoint (requires BEARER_TOKEN) +make test-all # Run all tests + +# Code quality +make lint # Run linter (same as CI) +make lint-fix # Run linter with auto-fix + +# Validation +make validate-schemas # Validate JSON schemas +make validate-examples # Validate examples against schemas +make validate # Run all validation checks + +# Combined workflows +make check # Run all checks (lint, validate, unit tests) + +# Utilities +make clean # Clean build artifacts and coverage files +``` + ### Linting The project uses golangci-lint with extensive checks. Always run linting before pushing: ```bash # Run all linters (same as CI) -golangci-lint run --timeout=5m +make lint -# Check formatting -gofmt -s -l . - -# Fix formatting -gofmt -s -w . +# Run linter with auto-fix +make lint-fix ``` ### Git Hooks (Optional) @@ -333,19 +372,64 @@ The service can be configured using environment variables: ## Testing -Run the test script to validate API endpoints: +### Unit Tests + +```bash +# Run unit tests with coverage +make test + +# Generate coverage report +make coverage +``` + +### Integration Tests ```bash -./scripts/test_endpoints.sh +# Run integration tests +make integration-test ``` -You can specify specific endpoints to test: +### API Endpoint Testing + +```bash +# Test API endpoints (requires running server) +make test-endpoints +``` + +You can also run the script directly with specific endpoints: ```bash ./scripts/test_endpoints.sh --endpoint health ./scripts/test_endpoints.sh --endpoint servers ``` +### Publish Endpoint Testing + +```bash +# Test publish endpoint (requires BEARER_TOKEN env var) +make test-publish +``` + +### Validation + +```bash +# Validate JSON schemas +make validate-schemas + +# Validate examples against schemas +make validate-examples + +# Run all validation checks +make validate +``` + +### Comprehensive Testing + +```bash +# Run all checks (lint, validate, test) +make check +``` + ## License See the [LICENSE](LICENSE) file for details.