Add helpful targets via Makefile (#211)

## Motivation and Context
<!-- Why is this change needed? What problem does it solve? -->
The following PR:
* Adds a Makefile with the most common project-related commands
* Updates the CI workflow to leverage that (people testing locally will
use the same commands as the CI)
* Switches to using the official Golangci-lint action instead of
downloading it via curl
* Bumps the golangci version (supersedes #144)
* Fixes any formatting/linting issues found
* Updates the README to reference the new make targets
* Runs the schema validation scripts as part of the CI

**Next:**
* If you are okay I can file a follow up PR afterwards where I can tidy
up the CI workflows a bit, it feels there's some overlap.

## How Has This Been Tested?
<!-- Have you tested this in a real application? Which scenarios were
tested? -->
Locally by running the make targets

## Breaking Changes
<!-- Will users need to update their code or configurations? -->

## Types of changes
<!-- What types of changes does your code introduce? Put an `x` in all
the boxes that apply: -->
- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update

## Checklist
<!-- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [ ] I have added appropriate error handling
- [ ] I have added or updated documentation as needed

## Additional context
<!-- Add any other context, implementation notes, or design decisions
-->

---------

Signed-off-by: Radoslav Dimitrov <radoslav@stacklok.com>
Co-authored-by: Adam Jones <adamj+git@anthropic.com>
This commit is contained in:
Radoslav Dimitrov 2025-08-06 16:51:15 +03:00 • committed by GitHub
commit f5bf542697
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 195 additions and 221 deletions

View file

@ -2,45 +2,17 @@ name: CI Pipeline
on: on:
push: push:
branches: [ main, develop ] branches: [ main ]
pull_request: pull_request:
branches: [ main, develop ] branches: [ main ]
env: env:
GO_VERSION: '1.23.x' GO_VERSION: '1.23.x'
jobs: jobs:
# Lint and Format Check # Build, Lint, and Validate
lint: build-lint-validate:
name: Lint and Format name: Build, Lint, and Validate
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
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout code - name: Checkout code
@ -64,20 +36,28 @@ jobs:
- name: Download dependencies - name: Download dependencies
run: go mod download run: go mod download
- name: Build application - name: Install golangci-lint
run: | 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 - name: Check for vulnerabilities
run: | run: |
go install golang.org/x/vuln/cmd/govulncheck@latest go install golang.org/x/vuln/cmd/govulncheck@latest
govulncheck ./... govulncheck ./...
# Unit Tests # All Tests
unit-tests: tests:
name: Unit Tests name: Tests
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: [lint, build]
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v4
@ -100,9 +80,8 @@ jobs:
- name: Download dependencies - name: Download dependencies
run: go mod download run: go mod download
- name: Run unit tests - name: Run all tests
run: | run: make test-all
go test -v -race -coverprofile=coverage.out -covermode=atomic ./internal/...
- name: Upload coverage to Codecov - name: Upload coverage to Codecov
uses: codecov/codecov-action@v4 uses: codecov/codecov-action@v4
@ -111,54 +90,3 @@ jobs:
flags: unittests flags: unittests
name: codecov-unit name: codecov-unit
fail_ci_if_error: false 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

View file

@ -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

View file

@ -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

2
.gitignore vendored
View file

@ -8,3 +8,5 @@ cmd/registry/registry
validate-examples validate-examples
validate-schemas validate-schemas
.idea/ .idea/
coverage.out
coverage.html

View file

@ -83,6 +83,11 @@ linters:
- return - return
nestif: nestif:
min-complexity: 8 min-complexity: 8
revive:
rules:
- name: use-any
severity: error
disabled: false
exclusions: exclusions:
generated: lax generated: lax
presets: presets:

70
Makefile Normal file
View file

@ -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

108
README.md
View file

@ -36,11 +36,11 @@ For development:
## Running ## 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 ```bash
# Run the registry and MongoDB with docker compose # 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. 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 ```bash
# Build a registry executable # 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. 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 ## 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 ### Linting
The project uses golangci-lint with extensive checks. Always run linting before pushing: The project uses golangci-lint with extensive checks. Always run linting before pushing:
```bash ```bash
# Run all linters (same as CI) # Run all linters (same as CI)
golangci-lint run --timeout=5m make lint
# Check formatting # Run linter with auto-fix
gofmt -s -l . make lint-fix
# Fix formatting
gofmt -s -w .
``` ```
### Git Hooks (Optional) ### Git Hooks (Optional)
@ -333,19 +372,64 @@ The service can be configured using environment variables:
## Testing ## Testing
Run the test script to validate API endpoints: ### Unit Tests
```bash ```bash
./scripts/test_endpoints.sh # Run unit tests with coverage
make test
# Generate coverage report
make coverage
``` ```
You can specify specific endpoints to test: ### Integration Tests
```bash
# Run integration tests
make integration-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 ```bash
./scripts/test_endpoints.sh --endpoint health ./scripts/test_endpoints.sh --endpoint health
./scripts/test_endpoints.sh --endpoint servers ./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 ## License
See the [LICENSE](LICENSE) file for details. See the [LICENSE](LICENSE) file for details.