Merge pull request #1 from d3v07/feat/reach-readiness #17
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
| # ============================================================================= | |
| # DocWeave Graph Updater Service - CI/CD Pipeline | |
| # ============================================================================= | |
| # Triggers: Push to main/develop, Pull Requests, Manual dispatch | |
| # Stages: Test, Build, Security Scan, Deploy | |
| name: Graph Updater CI/CD | |
| on: | |
| push: | |
| branches: | |
| - main | |
| - develop | |
| paths: | |
| - 'services/graph_updater/**' | |
| - 'shared/**' | |
| - '.github/workflows/graph-updater.yml' | |
| pull_request: | |
| branches: | |
| - main | |
| - develop | |
| paths: | |
| - 'services/graph_updater/**' | |
| - 'shared/**' | |
| workflow_dispatch: | |
| inputs: | |
| deploy_env: | |
| description: 'Environment to deploy to' | |
| required: false | |
| default: 'staging' | |
| type: choice | |
| options: | |
| - staging | |
| - production | |
| env: | |
| SERVICE_NAME: graph-updater | |
| PYTHON_VERSION: '3.11' | |
| REGISTRY: ghcr.io | |
| IMAGE_NAME: ${{ github.repository }}/graph-updater | |
| jobs: | |
| # =========================================================================== | |
| # Test Job - Run unit tests and generate coverage | |
| # =========================================================================== | |
| test: | |
| name: Test | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| services: | |
| neo4j: | |
| image: neo4j:5.17.0-community | |
| ports: | |
| - 7687:7687 | |
| - 7474:7474 | |
| env: | |
| NEO4J_AUTH: neo4j/testpassword | |
| NEO4J_PLUGINS: '["apoc"]' | |
| options: >- | |
| --health-cmd "wget -q --spider http://localhost:7474 || exit 1" | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 10 | |
| --health-start-period 30s | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| cache: 'pip' | |
| cache-dependency-path: | | |
| services/graph_updater/requirements.txt | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -r services/graph_updater/requirements.txt | |
| pip install pytest pytest-asyncio | |
| - name: Run tests | |
| run: | | |
| python -m compileall -q services/graph_updater shared | |
| pytest services/graph_updater/tests -v --tb=short | |
| # =========================================================================== | |
| # Lint Job - Code quality checks | |
| # =========================================================================== | |
| lint: | |
| name: Lint | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| cache: 'pip' | |
| - name: Install linting tools | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -r services/graph_updater/requirements.txt | |
| pip install ruff mypy black isort | |
| - name: Run Ruff linter | |
| run: | | |
| ruff check services/graph_updater/*.py --output-format=github | |
| - name: Check formatting with Black | |
| run: | | |
| black --check services/graph_updater/*.py | |
| - name: Check import sorting with isort | |
| run: | | |
| isort --check-only services/graph_updater/*.py | |
| - name: Type check with mypy | |
| run: | | |
| mypy services/graph_updater/*.py --ignore-missing-imports --no-error-summary | |
| # =========================================================================== | |
| # Security Scan Job | |
| # =========================================================================== | |
| security: | |
| name: Security Scan | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| permissions: | |
| security-events: write | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| - name: Install security tools | |
| run: | | |
| pip install bandit safety pip-audit | |
| - name: Run Bandit security scan | |
| run: | | |
| bandit services/graph_updater/*.py -f json -o bandit-results.json | |
| bandit services/graph_updater/*.py -f txt | |
| - name: Check dependencies for vulnerabilities | |
| run: | | |
| pip-audit -r services/graph_updater/requirements.txt --desc | |
| - name: Upload security scan results | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: security-scan-results | |
| path: bandit-results.json | |
| retention-days: 30 | |
| # =========================================================================== | |
| # Build Job - Build and push Docker image | |
| # =========================================================================== | |
| build: | |
| name: Build Docker Image | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| needs: [test, lint, security] | |
| permissions: | |
| contents: read | |
| packages: write | |
| outputs: | |
| image_tag: ${{ steps.meta.outputs.tags }} | |
| image_digest: ${{ steps.build.outputs.digest }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Login to GitHub Container Registry | |
| if: github.event_name != 'pull_request' | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Extract metadata for Docker | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} | |
| tags: | | |
| type=ref,event=branch | |
| type=ref,event=pr | |
| type=sha,prefix=sha-,format=long | |
| type=semver,pattern={{version}} | |
| type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }} | |
| - name: Build and push Docker image | |
| id: build | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| file: services/graph_updater/Dockerfile | |
| push: ${{ github.event_name != 'pull_request' }} | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| build-args: | | |
| BUILD_DATE=${{ github.event.head_commit.timestamp }} | |
| VCS_REF=${{ github.sha }} | |
| VERSION=${{ github.ref_name }} | |
| - name: Build Summary | |
| run: | | |
| echo "## Docker Build Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "**Image:** \`${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}\`" >> $GITHUB_STEP_SUMMARY | |
| echo "**Tags:** ${{ steps.meta.outputs.tags }}" >> $GITHUB_STEP_SUMMARY | |
| echo "**Digest:** ${{ steps.build.outputs.digest }}" >> $GITHUB_STEP_SUMMARY |