CI #14
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 | |
on: | |
push: | |
branches: | |
- 'main' | |
- '[0-9].[0-9]' | |
pull_request: | |
branches: | |
- 'main' | |
- '[0-9].[0-9]' | |
schedule: | |
- cron: '0 1 * * *' # nightly build | |
permissions: | |
contents: read | |
jobs: | |
lint-and-format: | |
runs-on: ubuntu-latest | |
steps: | |
- name: ⚙️ Harden Runner | |
uses: step-security/harden-runner@v2 | |
with: | |
egress-policy: audit | |
- name: ⚙️ Checkout the project | |
uses: actions/checkout@v4 | |
- name: ⚙️ Install uv | |
uses: astral-sh/setup-uv@v4 | |
with: | |
version: "latest" | |
- name: ⚙️ Set Python up and add dependencies | |
run: | | |
uv python install 3.12 | |
uv sync --all-extras --dev | |
uv add --dev ruff mypy | |
- name: ⚙️ Run linters and formatters | |
run: | | |
uv run ruff check src/ tests/ | |
uv run ruff format --check src/ tests/ | |
# uv run mypy src/ --ignore-missing-imports | |
security-scan: | |
runs-on: ubuntu-latest | |
steps: | |
- name: ⚙️ Harden Runner | |
uses: step-security/harden-runner@v2 | |
with: | |
egress-policy: audit | |
- name: ⚙️ Checkout the project | |
uses: actions/checkout@v4 | |
- name: ⚙️ Install uv | |
uses: astral-sh/setup-uv@v4 | |
with: | |
version: "latest" | |
- name: ⚙️ Set Python up and add dependencies | |
run: | | |
uv python install 3.12 | |
uv sync --all-extras --dev | |
uv add --dev bandit | |
- name: ⚙️ Run security scan with bandit | |
run: | | |
uv run bandit -r src/ -f json -o bandit-report.json || true | |
uv run bandit -r src/ | |
- name: ⚙️ Upload security reports | |
uses: actions/upload-artifact@v4 | |
if: always() | |
with: | |
name: security-reports | |
path: | | |
bandit-report.json | |
retention-days: 30 | |
test-ubuntu: | |
runs-on: ubuntu-latest | |
strategy: | |
fail-fast: false | |
matrix: | |
python-version: ["3.10", "3.11", "3.12", "3.13"] | |
services: | |
redis: | |
image: redis:latest | |
ports: | |
- 6379:6379 | |
options: >- | |
--health-cmd "redis-cli ping" | |
--health-interval 10s | |
--health-timeout 5s | |
--health-retries 5 | |
steps: | |
- name: ⚙️ Harden Runner | |
uses: step-security/harden-runner@v2 | |
with: | |
egress-policy: audit | |
- name: ⚙️ Checkout the project | |
uses: actions/checkout@v4 | |
- name: ⚙️ Install uv | |
uses: astral-sh/setup-uv@v4 | |
with: | |
version: "latest" | |
- name: ⚙️ Set Python ${{ matrix.python-version }} up and add dependencies | |
run: | | |
uv python install ${{ matrix.python-version }} | |
uv sync --all-extras --dev | |
uv add --dev pytest pytest-cov pytest-asyncio coverage | |
- name: ⚙️ Run tests with coverage | |
run: | | |
uv run pytest tests/ -v --cov=src --cov-report=xml --cov-report=html --cov-report=term | |
env: | |
REDIS_HOST: localhost | |
REDIS_PORT: 6379 | |
- name: ⚙️ Test MCP server startup | |
run: | | |
timeout 10s uv run python src/main.py || test $? = 124 | |
env: | |
REDIS_HOST: localhost | |
REDIS_PORT: 6379 | |
- name: ⚙️ Upload coverage reports | |
uses: codecov/codecov-action@v4 | |
if: matrix.python-version == '3.12' | |
with: | |
file: ./coverage.xml | |
flags: unittests | |
name: codecov-umbrella | |
test-other-os: | |
runs-on: ${{ matrix.os }} | |
strategy: | |
fail-fast: false | |
matrix: | |
os: [windows-latest, macos-latest] | |
python-version: ["3.10", "3.11", "3.12", "3.13"] | |
steps: | |
- name: ⚙️ Checkout the project | |
uses: actions/checkout@v4 | |
- name: ⚙️ Install uv | |
uses: astral-sh/setup-uv@v4 | |
with: | |
version: "latest" | |
- name: ⚙️ Set Python ${{ matrix.python-version }} up and add dependencies | |
run: | | |
uv python install ${{ matrix.python-version }} | |
uv sync --all-extras --dev | |
uv add --dev pytest pytest-cov pytest-asyncio coverage | |
- name: ⚙️ Run tests (without Redis services) | |
run: | | |
uv run pytest tests/ -v | |
env: | |
REDIS_HOST: localhost | |
REDIS_PORT: 6379 | |
- name: ⚙️ Test MCP server startup (macOS) | |
run: | | |
brew install coreutils | |
gtimeout 10s uv run python src/main.py || test $? = 124 | |
env: | |
REDIS_HOST: localhost | |
REDIS_PORT: 6379 | |
if: matrix.os == 'macos-latest' | |
- name: ⚙️ Test MCP server startup (Windows) | |
run: | | |
Start-Process -FilePath "uv" -ArgumentList "run", "python", "src/main.py" -PassThru | Wait-Process -Timeout 10 -ErrorAction SilentlyContinue | |
env: | |
REDIS_HOST: localhost | |
REDIS_PORT: 6379 | |
if: matrix.os == 'windows-latest' | |
build-test: | |
runs-on: ubuntu-latest | |
needs: [lint-and-format, security-scan, test-ubuntu, test-other-os] | |
steps: | |
- name: ⚙️ Harden Runner | |
uses: step-security/harden-runner@v2 | |
with: | |
egress-policy: audit | |
- name: ⚙️ Checkout the project | |
uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 # Full history for UV build | |
- name: ⚙️ Install uv | |
uses: astral-sh/setup-uv@v4 | |
with: | |
version: "latest" | |
- name: ⚙️ Set up Python | |
run: uv python install 3.12 | |
- name: ⚙️ Build package | |
run: | | |
uv build --sdist --wheel | |
- name: ⚙️ Check package | |
run: | | |
uv add --dev twine | |
uv run twine check dist/* | |
- name: ⚙️ Test package installation | |
run: | | |
uv venv test-env | |
source test-env/bin/activate | |
pip install dist/*.whl | |
redis-mcp-server --help | |
- name: ⚙️ Upload build artifacts | |
uses: actions/upload-artifact@v4 | |
with: | |
name: dist-files | |
path: dist/ | |
retention-days: 7 | |
docker-test: | |
runs-on: ubuntu-latest | |
needs: [lint-and-format, security-scan] | |
steps: | |
- name: ⚙️ Harden Runner | |
uses: step-security/harden-runner@v2 | |
with: | |
egress-policy: audit | |
- name: ⚙️ Checkout the project | |
uses: actions/checkout@v4 | |
- name: ⚙️ Build Docker image | |
run: docker build -t redis-mcp-server:test . | |
- name: ⚙️ Test Docker image | |
run: | | |
docker run --rm redis-mcp-server:test uv run python -c "import src.main; print('Docker build successful')" |