Merge pull request #17 from unplugged12/dependabot/github_actions/anc… #48
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: CI Pipeline | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| workflow_dispatch: | |
| jobs: | |
| lint-powershell: | |
| name: Lint PowerShell Scripts | |
| runs-on: windows-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Ensure PSScriptAnalyzer | |
| shell: pwsh | |
| run: | | |
| if (-not (Get-Module -ListAvailable -Name PSScriptAnalyzer)) { | |
| Install-Module -Name PSScriptAnalyzer -Force -Scope CurrentUser | |
| } | |
| - name: Check PowerShell formatting | |
| shell: pwsh | |
| run: | | |
| ./tools/lint.ps1 -Mode FormatCheck | |
| - name: Run PSScriptAnalyzer | |
| shell: pwsh | |
| run: | | |
| ./tools/lint.ps1 -Mode Analyze -FailOnNewWarnings | |
| lint-bash: | |
| name: Lint Bash Scripts | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Install shellcheck | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y shellcheck | |
| - name: Run shellcheck | |
| run: | | |
| find . -name "*.sh" -type f | while read -r script; do | |
| echo "Analyzing: $script" | |
| shellcheck "$script" || exit 1 | |
| done | |
| echo "✓ All Bash scripts passed linting" | |
| validate-scripts: | |
| name: Validate Scripts (Windows) | |
| runs-on: windows-latest | |
| needs: [lint-powershell] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Check Docker availability | |
| shell: pwsh | |
| run: | | |
| $dockerCmd = Get-Command docker -ErrorAction SilentlyContinue | |
| if (-not $dockerCmd) { | |
| Write-Warning "Docker executable not found. Skipping Docker version check." | |
| } | |
| else { | |
| docker --version | |
| } | |
| - name: Run pre-deployment validation | |
| shell: pwsh | |
| run: | | |
| # Skip checks that require network access in CI | |
| Write-Host "Running syntax validation..." | |
| # Validate PowerShell scripts execute without errors | |
| $scripts = Get-ChildItem -Path scripts -Filter *.ps1 -Recurse | |
| foreach ($script in $scripts) { | |
| Write-Host "Syntax check: $($script.Name)" | |
| $null = [System.Management.Automation.PSParser]::Tokenize((Get-Content $script.FullName -Raw), [ref]$null) | |
| } | |
| Write-Host "✓ All scripts are syntactically valid" | |
| security-sast: | |
| name: Security - SAST Scanning | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| security-events: write | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Run Trivy vulnerability scanner | |
| uses: aquasecurity/[email protected] | |
| with: | |
| scan-type: 'fs' | |
| scan-ref: '.' | |
| format: 'sarif' | |
| output: 'trivy-results.sarif' | |
| severity: 'CRITICAL,HIGH' | |
| - name: Upload Trivy results to GitHub Security | |
| uses: github/codeql-action/upload-sarif@v3 | |
| if: always() | |
| with: | |
| sarif_file: 'trivy-results.sarif' | |
| - name: Run Semgrep SAST | |
| uses: returntocorp/semgrep-action@v1 | |
| with: | |
| config: >- | |
| p/security-audit | |
| p/secrets | |
| validate-docker-compose: | |
| name: Validate Docker Compose Files | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| stack: [common, desktop, laptop] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Validate compose file - ${{ matrix.stack }} | |
| run: | | |
| cd stacks/${{ matrix.stack }} | |
| # Create dummy env file for validation | |
| echo "MCP_ENV_FILE=/tmp/mcp.env" > .env.test | |
| echo "HUB_USERNAME=testuser" >> .env.test | |
| echo "HUB_PAT_TOKEN=testtoken" >> .env.test | |
| echo "CONTEXT7_TOKEN=testtoken" >> .env.test | |
| echo "ENVIRONMENT=ci" >> .env.test | |
| # Create dummy secret file referenced by MCP_ENV_FILE so docker compose validation succeeds | |
| printf "# dummy MCP env file for CI validation\n" > /tmp/mcp.env | |
| # Validate compose file syntax | |
| docker compose --env-file .env.test config > /dev/null | |
| if [ $? -eq 0 ]; then | |
| echo "✓ ${{ matrix.stack }}/docker-compose.yml is valid" | |
| else | |
| echo "✗ ${{ matrix.stack }}/docker-compose.yml validation failed" | |
| exit 1 | |
| fi | |
| security-sbom: | |
| name: Generate SBOM | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Generate SBOM with Syft | |
| uses: anchore/[email protected] | |
| with: | |
| path: ./ | |
| format: 'cyclonedx-json' | |
| output-file: 'sbom.json' | |
| upload-artifact: false | |
| - name: Upload SBOM as artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: sbom | |
| path: sbom.json | |
| retention-days: 90 | |
| - name: Scan SBOM with Grype | |
| uses: anchore/scan-action@v3 | |
| with: | |
| sbom: 'sbom.json' | |
| fail-build: false | |
| severity-cutoff: high | |
| docker-image-checks: | |
| name: Docker Image Security Scan | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| image: | |
| - mcp/context7:latest | |
| - mcp/dockerhub:latest | |
| - mcp/mcp-playwright:latest | |
| - mcp/sequentialthinking:latest | |
| steps: | |
| - name: Run Trivy vulnerability scanner on image | |
| uses: aquasecurity/[email protected] | |
| with: | |
| image-ref: ${{ matrix.image }} | |
| format: 'table' | |
| severity: 'CRITICAL,HIGH' | |
| ignore-unfixed: true | |
| exit-code: 1 | |
| test-scripts-linux: | |
| name: Test Scripts (Linux) | |
| runs-on: ubuntu-latest | |
| needs: [lint-bash] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Install Docker | |
| run: | | |
| docker --version | |
| - name: Test script execution | |
| run: | | |
| # Make scripts executable | |
| find scripts -name "*.sh" -type f -exec chmod +x {} \; | |
| # Test that scripts don't have syntax errors | |
| find scripts -name "*.sh" -type f | while read -r script; do | |
| echo "Testing: $script" | |
| bash -n "$script" || exit 1 | |
| done | |
| echo "✓ All Bash scripts are executable and valid" | |
| test-scripts-windows: | |
| name: Test Scripts (Windows) | |
| runs-on: windows-latest | |
| needs: [lint-powershell, validate-scripts] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Install Pester | |
| shell: pwsh | |
| run: | | |
| if (-not (Get-Module -ListAvailable -Name Pester -ErrorAction Ignore | Where-Object { $_.Version.Major -ge 5 })) { | |
| Install-Module -Name Pester -Force -SkipPublisherCheck -Scope CurrentUser | |
| } | |
| - name: Run PowerShell test suite | |
| shell: pwsh | |
| run: | | |
| ./scripts/run-tests.ps1 -CI | |
| - name: Publish Pester results | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: pester-results | |
| path: TestResults/test-results.xml | |
| retention-days: 14 | |
| summary: | |
| name: CI Summary | |
| runs-on: ubuntu-latest | |
| needs: | |
| - lint-powershell | |
| - lint-bash | |
| - validate-scripts | |
| - security-sast | |
| - validate-docker-compose | |
| - security-sbom | |
| - docker-image-checks | |
| - test-scripts-linux | |
| - test-scripts-windows | |
| if: always() | |
| steps: | |
| - name: Check job results | |
| run: | | |
| echo "## CI Pipeline Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### Job Results:" >> $GITHUB_STEP_SUMMARY | |
| echo "- Lint PowerShell: ${{ needs.lint-powershell.result }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- Lint Bash: ${{ needs.lint-bash.result }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- Validate Scripts: ${{ needs.validate-scripts.result }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- Security SAST: ${{ needs.security-sast.result }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- Validate Docker Compose: ${{ needs.validate-docker-compose.result }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- Generate SBOM: ${{ needs.security-sbom.result }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- Docker Image Security: ${{ needs.docker-image-checks.result }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- Test Scripts (Linux): ${{ needs.test-scripts-linux.result }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- Test Scripts (Windows): ${{ needs.test-scripts-windows.result }}" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| if [ "${{ needs.lint-powershell.result }}" != "success" ] || \ | |
| [ "${{ needs.lint-bash.result }}" != "success" ] || \ | |
| [ "${{ needs.validate-scripts.result }}" != "success" ] || \ | |
| [ "${{ needs.validate-docker-compose.result }}" != "success" ] || \ | |
| [ "${{ needs.test-scripts-linux.result }}" != "success" ] || \ | |
| [ "${{ needs.test-scripts-windows.result }}" != "success" ]; then | |
| echo "❌ CI Pipeline Failed" >> $GITHUB_STEP_SUMMARY | |
| exit 1 | |
| else | |
| echo "✅ CI Pipeline Passed" >> $GITHUB_STEP_SUMMARY | |
| fi | |