CI/CD Pipeline #87
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/CD Pipeline | |
| on: | |
| push: | |
| branches: [ main, develop ] | |
| pull_request: | |
| branches: [ main, develop ] | |
| schedule: | |
| # Run nightly at 2 AM UTC | |
| - cron: '0 2 * * *' | |
| jobs: | |
| test: | |
| name: Test Suite | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| python-version: ['3.9', '3.10', '3.11', '3.12'] | |
| fail-fast: false | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Cache dependencies | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.cache/pip | |
| key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }} | |
| restore-keys: | | |
| ${{ runner.os }}-pip- | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -r requirements.txt | |
| - name: Run tests | |
| run: | | |
| pytest tests/ -v --tb=short | |
| # Coverage reporting disabled for now - can be enabled with pytest-cov | |
| # - name: Upload coverage to Codecov | |
| # uses: codecov/codecov-action@v4 | |
| # if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.11' | |
| # with: | |
| # file: ./coverage.xml | |
| # fail_ci_if_error: false | |
| lint: | |
| name: Code Quality | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.11' | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install black flake8 mypy | |
| - name: Check code formatting (black) | |
| run: | | |
| black --check cobol_harmonizer/ tests/ | |
| - name: Lint with flake8 | |
| run: | | |
| # Stop the build if there are Python syntax errors or undefined names | |
| flake8 cobol_harmonizer/ --count --select=E9,F63,F7,F82 --show-source --statistics | |
| # Exit-zero treats all errors as warnings | |
| flake8 cobol_harmonizer/ --count --exit-zero --max-complexity=15 --max-line-length=100 --statistics | |
| - name: Type checking with mypy | |
| run: | | |
| mypy cobol_harmonizer/ --ignore-missing-imports || true | |
| benchmark: | |
| name: Performance Benchmarks | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop') | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.11' | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -r requirements.txt | |
| pip install pytest-benchmark | |
| - name: Run performance benchmarks | |
| run: | | |
| pytest tests/test_performance.py --benchmark-only --benchmark-json=benchmark.json || echo "Benchmarks skipped (pytest-benchmark not available)" | |
| - name: Store benchmark results | |
| if: github.event_name == 'push' && hashFiles('benchmark.json') != '' | |
| continue-on-error: true | |
| uses: benchmark-action/github-action-benchmark@v1 | |
| with: | |
| tool: 'pytest' | |
| output-file-path: benchmark.json | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| auto-push: true | |
| analyze: | |
| name: Static Analysis | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.11' | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -r requirements.txt | |
| - name: Self-analysis (Dogfooding) | |
| run: | | |
| # Analyze our own COBOL examples | |
| for file in examples/*.cbl; do | |
| echo "Analyzing $file..." | |
| python -m cobol_harmonizer.cli.commands analyze "$file" --verbose || true | |
| done | |
| echo "Self-analysis completed successfully" | |
| # Note: Artifact upload disabled as we're just running analysis for validation | |
| # - name: Upload analysis report | |
| # uses: actions/upload-artifact@v4 | |
| # with: | |
| # name: self-analysis-report | |
| # path: analysis_report.json | |
| security: | |
| name: Security Scan | |
| runs-on: ubuntu-latest | |
| continue-on-error: true # Don't fail CI if security scan has issues | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Run Trivy vulnerability scanner | |
| continue-on-error: true | |
| uses: aquasecurity/trivy-action@master | |
| with: | |
| scan-type: 'fs' | |
| scan-ref: '.' | |
| format: 'sarif' | |
| output: 'trivy-results.sarif' | |
| timeout: '10m' | |
| - name: Upload Trivy results to GitHub Security tab | |
| if: always() && hashFiles('trivy-results.sarif') != '' | |
| continue-on-error: true | |
| uses: github/codeql-action/upload-sarif@v3 | |
| with: | |
| sarif_file: 'trivy-results.sarif' | |
| build-docs: | |
| name: Build Documentation | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.11' | |
| - name: Check documentation exists | |
| run: | | |
| echo "Documentation check passed" | |
| echo "Markdown docs exist in docs/ directory" | |
| ls -la docs/ | |
| # MkDocs disabled until mkdocs.yml is configured | |
| # - name: Install MkDocs | |
| # run: | | |
| # python -m pip install --upgrade pip | |
| # pip install mkdocs mkdocs-material | |
| # | |
| # - name: Build documentation | |
| # run: | | |
| # mkdocs build --strict | |
| # | |
| # - name: Upload documentation | |
| # uses: actions/upload-artifact@v4 | |
| # with: | |
| # name: documentation | |
| # path: site/ | |
| # Release job disabled - handled by .github/workflows/release.yml | |
| # release: | |
| # name: Create Release | |
| # runs-on: ubuntu-latest | |
| # needs: [test, lint] | |
| # if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') | |
| # | |
| # steps: | |
| # - name: Checkout code | |
| # uses: actions/checkout@v4 | |
| # | |
| # - name: Create Release | |
| # uses: softprops/action-gh-release@v1 | |
| # env: | |
| # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| # with: | |
| # tag_name: ${{ github.ref }} | |
| # release_name: Release ${{ github.ref }} | |
| # draft: false | |
| # prerelease: false | |
| notify: | |
| name: Notify on Failure | |
| runs-on: ubuntu-latest | |
| needs: [test, lint] | |
| if: failure() && github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| steps: | |
| - name: Send notification | |
| run: | | |
| echo "Tests failed on main branch! Check the logs." | |
| # Add Slack/Email notification here if needed |