|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +This is a **composite GitHub Action** (not a standalone application) that provides the Mission Critical Vulnerability Scanner (MCVS) for Python projects. The action performs security scanning, linting, testing, and optional binary building for Python codebases. |
| 8 | + |
| 9 | +## Architecture |
| 10 | + |
| 11 | +### Composite Action Structure |
| 12 | + |
| 13 | +The action is defined in `action.yml` and executes as a series of composite steps: |
| 14 | + |
| 15 | +1. **YAML Linting**: Validates YAML files using yamllint |
| 16 | +2. **Python Environment Setup**: Installs Python version from `.python-version` |
| 17 | +3. **Security Scanning**: Uses Anchore scan-action to detect vulnerabilities |
| 18 | +4. **Dependency Installation**: Installs packages from `requirements.txt` if present |
| 19 | +5. **Testing**: Runs pytest if tests are detected |
| 20 | +6. **Code Linting**: Uses Flake8 with a configurable error threshold |
| 21 | +7. **Binary Building**: Conditionally builds PyInstaller binaries on tag releases |
| 22 | + |
| 23 | +### Key Design Decisions |
| 24 | + |
| 25 | +- **Composite vs Docker**: Uses `using: composite` to avoid Docker overhead and enable caching |
| 26 | +- **Conditional Execution**: Steps like testing and binary building only run when applicable |
| 27 | +- **Token Authentication**: Requires GitHub token for package registry and Docker registry access |
| 28 | +- **Version Pinning**: All tools are pinned to specific versions for reproducibility |
| 29 | + |
| 30 | +## Version Constraints |
| 31 | + |
| 32 | +**CRITICAL**: The following versions are pinned in `action.yml`: |
| 33 | + |
| 34 | +- `yamllint==1.37.1` (action.yml:21) |
| 35 | +- `actions/setup-python@v5.6.0` (action.yml:28) |
| 36 | +- `anchore/scan-action@v6.2.0` (action.yml:34) |
| 37 | +- `flake8==7.2.0` (action.yml:75) |
| 38 | +- `pyinstaller==v6.13.0` (action.yml:102) |
| 39 | +- `svenstaro/upload-release-action@2.9.0` (action.yml:106) |
| 40 | + |
| 41 | +When updating dependencies: |
| 42 | +- Update the version in `action.yml` |
| 43 | +- Dependabot automatically creates PRs for GitHub Actions updates (see `.github/dependabot.yml`) |
| 44 | +- Python package versions must be updated manually |
| 45 | + |
| 46 | +## Testing Changes |
| 47 | + |
| 48 | +This action is tested via PR validation: |
| 49 | + |
| 50 | +```yaml |
| 51 | +# Validation happens automatically on PRs via .github/workflows/mcvs-pr-validation.yml |
| 52 | +# Uses schubergphilis/mcvs-pr-validation-action@v0.2.0 |
| 53 | +``` |
| 54 | + |
| 55 | +To test locally before committing: |
| 56 | + |
| 57 | +```bash |
| 58 | +# Test YAML linting (matches action behavior) |
| 59 | +pip install yamllint==1.37.1 |
| 60 | +yamllint . |
| 61 | + |
| 62 | +# Validate action.yml structure |
| 63 | +# No local validation tool - rely on PR validation workflow |
| 64 | +``` |
| 65 | + |
| 66 | +## Dependency Management |
| 67 | + |
| 68 | +### Dependabot Configuration |
| 69 | + |
| 70 | +Dependabot is configured for GitHub Actions only (`.github/dependabot.yml`): |
| 71 | +- Runs weekly checks |
| 72 | +- 5-day cooldown between updates |
| 73 | +- Groups all GitHub Actions updates together |
| 74 | + |
| 75 | +**Note**: Python package dependencies (yamllint, flake8, pyinstaller) are NOT managed by Dependabot and must be updated manually in `action.yml`. |
| 76 | + |
| 77 | +## Flake8 Configuration |
| 78 | + |
| 79 | +The action has a **configurable error threshold** for Flake8: |
| 80 | + |
| 81 | +```bash |
| 82 | +# Current threshold: 4 errors/warnings maximum |
| 83 | +--max-line-length=150 |
| 84 | +--exclude=client/,.venv/,venv/ |
| 85 | +``` |
| 86 | + |
| 87 | +Pipeline fails if error count > 4 (action.yml:81-83). This threshold may need adjustment when adding strict linting rules. |
| 88 | + |
| 89 | +## PyInstaller Binary Building |
| 90 | + |
| 91 | +Binary building is **conditional** and requires: |
| 92 | +1. Push event to a tag (`refs/tags/*`) |
| 93 | +2. Non-empty `pyinstaller-binary-name` input |
| 94 | + |
| 95 | +The binary is automatically attached to GitHub releases (action.yml:89-111). |
| 96 | + |
| 97 | +## Action Inputs |
| 98 | + |
| 99 | +Required inputs when using this action: |
| 100 | + |
| 101 | +| Input | Required | Purpose | |
| 102 | +|-------|----------|---------| |
| 103 | +| `token` | Yes | GitHub token for package registry and Docker login | |
| 104 | +| `pyinstaller-binary-name` | No | If set, builds and releases a binary | |
| 105 | + |
| 106 | +## Important Workflow Notes |
| 107 | + |
| 108 | +- Projects using this action must have a `.python-version` file to specify Python version |
| 109 | +- `requirements.txt` is optional - only installed if present |
| 110 | +- Tests only run if `import pytest` is found in Python files |
| 111 | +- Security scanning uses severity cutoff of "high" (action.yml:39) |
| 112 | +- Docker login required for security scanning (action.yml:40-44) |
0 commit comments