Add template config #6
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | name: Build Template and Validate | |
| on: | |
| push: | |
| branches: [ main, develop ] | |
| pull_request: | |
| branches: [ main ] | |
| workflow_dispatch: | |
| jobs: | |
| validate-template: | |
| name: Validate MCP Server Template | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| dotnet-version: ['8.0.x'] | |
| test-scenario: | |
| - name: "Default Parameters" | |
| project-name: "DefaultMcpServer" | |
| args: "" | |
| - name: "Custom Parameters" | |
| project-name: "CustomMcpServer" | |
| args: "--ServerName 'Custom MCP Server' --Port 5001" | |
| - name: "Different Port" | |
| project-name: "PortTestServer" | |
| args: "--Port 8080" | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: ${{ matrix.dotnet-version }} | |
| - name: Display .NET info | |
| run: dotnet --info | |
| - name: Install template | |
| run: dotnet new install ./ | |
| - name: List installed templates | |
| run: dotnet new list | grep mcp-server | |
| - name: Create test project - ${{ matrix.test-scenario.name }} | |
| run: | | |
| cd /tmp | |
| dotnet new mcp-server -n ${{ matrix.test-scenario.project-name }} ${{ matrix.test-scenario.args }} | |
| - name: Verify project structure | |
| run: | | |
| cd /tmp/${{ matrix.test-scenario.project-name }} | |
| echo "Checking project structure..." | |
| test -f "${{ matrix.test-scenario.project-name }}.csproj" || (echo "Project file missing" && exit 1) | |
| test -f "Program.cs" || (echo "Program.cs missing" && exit 1) | |
| test -f "Dockerfile" || (echo "Dockerfile missing" && exit 1) | |
| test -f "README.md" || (echo "README.md missing" && exit 1) | |
| test -d "Tools" || (echo "Tools directory missing" && exit 1) | |
| test -d "Prompts" || (echo "Prompts directory missing" && exit 1) | |
| test -d "Resources" || (echo "Resources directory missing" && exit 1) | |
| test -d "Extensions" || (echo "Extensions directory missing" && exit 1) | |
| echo "✅ Project structure validated" | |
| - name: Verify namespace replacement | |
| run: | | |
| cd /tmp/${{ matrix.test-scenario.project-name }} | |
| echo "Checking namespace replacement..." | |
| # Check namespace declarations in class files | |
| grep -q "namespace ${{ matrix.test-scenario.project-name }}.Tools" Tools/*.cs || (echo "Namespace not replaced in Tools" && exit 1) | |
| grep -q "namespace ${{ matrix.test-scenario.project-name }}.Prompts" Prompts/*.cs || (echo "Namespace not replaced in Prompts" && exit 1) | |
| grep -q "namespace ${{ matrix.test-scenario.project-name }}.Resources" Resources/*.cs || (echo "Namespace not replaced in Resources" && exit 1) | |
| grep -q "namespace ${{ matrix.test-scenario.project-name }}.Extensions" Extensions/*.cs || (echo "Namespace not replaced in Extensions" && exit 1) | |
| echo "✅ Namespace replacement validated" | |
| - name: Restore dependencies | |
| run: | | |
| cd /tmp/${{ matrix.test-scenario.project-name }} | |
| dotnet restore | |
| - name: Build project | |
| run: | | |
| cd /tmp/${{ matrix.test-scenario.project-name }} | |
| dotnet build --configuration Release --no-restore | |
| - name: Test project startup | |
| run: | | |
| cd /tmp/${{ matrix.test-scenario.project-name }} | |
| echo "Testing project startup..." | |
| timeout 10s dotnet run --configuration Release --no-build || true | |
| echo "✅ Project startup test completed" | |
| - name: Check Docker build | |
| run: | | |
| cd /tmp/${{ matrix.test-scenario.project-name }} | |
| echo "Testing Docker build..." | |
| docker build -t test-mcp-server . | |
| echo "✅ Docker build successful" | |
| - name: Test Docker run | |
| run: | | |
| cd /tmp/${{ matrix.test-scenario.project-name }} | |
| echo "Testing Docker container..." | |
| docker run -d --name test-container -p 5000:5000 test-mcp-server | |
| sleep 5 | |
| docker logs test-container | |
| docker stop test-container | |
| docker rm test-container | |
| echo "✅ Docker container test completed" | |
| validate-source-template: | |
| name: Validate Source Template | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: '8.0.x' | |
| - name: Build source template | |
| run: dotnet build --configuration Release | |
| - name: Test source template startup | |
| run: | | |
| echo "Testing source template startup..." | |
| timeout 10s dotnet run --configuration Release || true | |
| echo "✅ Source template startup test completed" | |
| - name: Check source Docker build | |
| run: | | |
| echo "Testing source Docker build..." | |
| docker build -t source-mcp-server . | |
| echo "✅ Source Docker build successful" | |
| validate-template-config: | |
| name: Validate Template Configuration | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Validate template.json | |
| run: | | |
| echo "Validating template.json structure..." | |
| if ! command -v jq &> /dev/null; then | |
| sudo apt-get update && sudo apt-get install -y jq | |
| fi | |
| template_file=".template.config/template.json" | |
| # Check if file exists | |
| test -f "$template_file" || (echo "template.json missing" && exit 1) | |
| # Validate JSON syntax | |
| jq empty "$template_file" || (echo "Invalid JSON in template.json" && exit 1) | |
| # Check required fields | |
| jq -e '.name' "$template_file" > /dev/null || (echo "Missing 'name' field" && exit 1) | |
| jq -e '.shortName' "$template_file" > /dev/null || (echo "Missing 'shortName' field" && exit 1) | |
| jq -e '.identity' "$template_file" > /dev/null || (echo "Missing 'identity' field" && exit 1) | |
| jq -e '.sourceName' "$template_file" > /dev/null || (echo "Missing 'sourceName' field" && exit 1) | |
| echo "✅ Template configuration validated" | |
| - name: Check template exclusions | |
| run: | | |
| echo "Checking template exclusions..." | |
| template_file=".template.config/template.json" | |
| # Verify common exclusions are present | |
| jq -e '.sources[0].modifiers[0].exclude | map(select(. == "**/[Bb]in/**"))' "$template_file" > /dev/null || (echo "Missing bin exclusion" && exit 1) | |
| jq -e '.sources[0].modifiers[0].exclude | map(select(. == "**/[Oo]bj/**"))' "$template_file" > /dev/null || (echo "Missing obj exclusion" && exit 1) | |
| jq -e '.sources[0].modifiers[0].exclude | map(select(. == "**/.vs/**"))' "$template_file" > /dev/null || (echo "Missing .vs exclusion" && exit 1) | |
| echo "✅ Template exclusions validated" | |
| validate-documentation: | |
| name: Validate Documentation | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Check README.md | |
| run: | | |
| echo "Validating README.md..." | |
| test -f "README.md" || (echo "README.md missing" && exit 1) | |
| # Check for required sections | |
| grep -q "# MCP Server Template" README.md || (echo "Missing main title" && exit 1) | |
| grep -q "## What is MCP?" README.md || (echo "Missing MCP explanation" && exit 1) | |
| grep -q "## Quick Start" README.md || (echo "Missing Quick Start section" && exit 1) | |
| grep -q "## Creating Custom Tools" README.md || (echo "Missing Tools documentation" && exit 1) | |
| grep -q "## Creating Custom Prompts" README.md || (echo "Missing Prompts documentation" && exit 1) | |
| grep -q "## Creating Custom Resources" README.md || (echo "Missing Resources documentation" && exit 1) | |
| grep -q "## Docker Support" README.md || (echo "Missing Docker documentation" && exit 1) | |
| echo "✅ Documentation validated" | |
| - name: Check for dead links (if link checker available) | |
| run: | | |
| echo "Note: Link checking would require additional tools" | |
| echo "✅ Documentation structure check completed" | |
| security-scan: | |
| name: Security Scan | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Run security scan on Dockerfile | |
| run: | | |
| echo "Scanning Dockerfile for security issues..." | |
| # Check for non-root user | |
| grep -q "USER" Dockerfile || echo "⚠️ Warning: Dockerfile doesn't explicitly set USER" | |
| # Check for specific security practices | |
| grep -q "aspnet:8.0" Dockerfile || (echo "❌ Not using ASP.NET Core runtime" && exit 1) | |
| echo "✅ Basic security scan completed" | |
| - name: Check for secrets in code | |
| run: | | |
| echo "Scanning for potential secrets..." | |
| # Simple patterns for common secrets (not exhaustive) | |
| if grep -r -i "password\|secret\|key\|token" --include="*.cs" --include="*.json" .; then | |
| echo "⚠️ Warning: Found potential secret patterns - please review" | |
| fi | |
| echo "✅ Secret scan completed" | |
| notify-completion: | |
| name: Notify Completion | |
| runs-on: ubuntu-latest | |
| needs: [validate-template, validate-source-template, validate-template-config, validate-documentation, security-scan] | |
| if: always() | |
| steps: | |
| - name: Check results | |
| run: | | |
| if [[ "${{ needs.validate-template.result }}" == "success" && | |
| "${{ needs.validate-source-template.result }}" == "success" && | |
| "${{ needs.validate-template-config.result }}" == "success" && | |
| "${{ needs.validate-documentation.result }}" == "success" && | |
| "${{ needs.security-scan.result }}" == "success" ]]; then | |
| echo "🎉 All validation checks passed!" | |
| echo "✅ Template is ready for use" | |
| else | |
| echo "❌ Some validation checks failed" | |
| echo "Template validation results:" | |
| echo "- Template Generation: ${{ needs.validate-template.result }}" | |
| echo "- Source Template: ${{ needs.validate-source-template.result }}" | |
| echo "- Template Config: ${{ needs.validate-template-config.result }}" | |
| echo "- Documentation: ${{ needs.validate-documentation.result }}" | |
| echo "- Security Scan: ${{ needs.security-scan.result }}" | |
| exit 1 | |
| fi |