Skip to content

feat(budpipeline): add deployment actions with internal auth support #14

feat(budpipeline): add deployment actions with internal auth support

feat(budpipeline): add deployment actions with internal auth support #14

name: "BudPipeline: PR Review"
on:
pull_request:
types: [opened, synchronize, reopened]
paths:
- 'services/budpipeline/**'
env:
PYTHON_VERSION: "3.11"
jobs:
lint:
name: Lint & Type Check
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./services/budpipeline
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Cache pip dependencies
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-lint-${{ hashFiles('**/pyproject.toml') }}
restore-keys: |
${{ runner.os }}-pip-lint-
${{ runner.os }}-pip-
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"
- name: Run ruff linter
run: |
echo "::group::Running ruff linter"
ruff check budpipeline/ tests/
echo "::endgroup::"
- name: Run ruff formatter check
run: |
echo "::group::Running ruff format check"
ruff format --check budpipeline/ tests/
echo "::endgroup::"
- name: Run mypy type check
run: |
echo "::group::Running mypy type check"
mypy budpipeline/ --ignore-missing-imports
echo "::endgroup::"
security:
name: Security Scan
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./services/budpipeline
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Install bandit
run: |
python -m pip install --upgrade pip
pip install bandit[toml]
- name: Run bandit security scan
run: |
echo "::group::Running bandit security scan"
bandit -r budpipeline/ -ll -f json -o bandit-report.json || true
bandit -r budpipeline/ -ll
echo "::endgroup::"
- name: Upload bandit report
if: always()
uses: actions/upload-artifact@v4
with:
name: bandit-security-report
path: ./services/budpipeline/bandit-report.json
test:
name: Run Tests
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./services/budpipeline
services:
postgres:
image: postgres:15
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: budpipeline_test
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
redis:
image: redis:7-alpine
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 6379:6379
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Cache pip dependencies
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-test-${{ hashFiles('**/pyproject.toml') }}
restore-keys: |
${{ runner.os }}-pip-test-
${{ runner.os }}-pip-
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"
- name: Set up environment
run: |
cp .env.sample .env
# Update database connection for CI (uses PSQL_* vars, not DATABASE_URL)
sed -i 's|PSQL_HOST=.*|PSQL_HOST=localhost|' .env
sed -i 's|PSQL_PORT=.*|PSQL_PORT=5432|' .env
sed -i 's|PSQL_USER=.*|PSQL_USER=postgres|' .env
sed -i 's|PSQL_PASSWORD=.*|PSQL_PASSWORD=postgres|' .env
sed -i 's|PSQL_DB_NAME=.*|PSQL_DB_NAME=budpipeline_test|' .env
# Disable Dapr for unit tests
echo "DAPR_HTTP_ENDPOINT=http://localhost:3500" >> .env
echo "DAPR_GRPC_ENDPOINT=localhost:50001" >> .env
echo "APP_API_TOKEN=test-token" >> .env
echo "Environment file setup complete"
- name: Run database migrations
run: |
alembic -c alembic.ini upgrade head
- name: Run tests with coverage
run: |
echo "::group::Running pytest with coverage"
pytest tests/ \
--ignore=tests/e2e \
--ignore=tests/test_integration \
--cov=budpipeline \
--cov-report=xml \
--cov-report=html \
--cov-report=term-missing \
-v \
-x \
--timeout=60
echo "::endgroup::"
- name: Upload coverage reports
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: |
./services/budpipeline/coverage.xml
./services/budpipeline/htmlcov/
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
file: ./services/budpipeline/coverage.xml
flags: budpipeline
name: budpipeline-coverage
fail_ci_if_error: false
dependency-check:
name: Check Dependencies
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./services/budpipeline
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Install pip-audit
run: |
python -m pip install --upgrade pip
pip install pip-audit
- name: Run dependency vulnerability scan
run: |
echo "::group::Checking for vulnerable dependencies"
# Install dependencies first to resolve them
pip install -e . --quiet
# Run audit on installed packages
pip-audit || true
echo "::endgroup::"
pr-status:
name: PR Review Status
runs-on: ubuntu-latest
needs: [lint, security, test, dependency-check]
if: always()
steps:
- name: Check job results
run: |
if [[ "${{ needs.lint.result }}" == "failure" ]]; then
echo "❌ Lint/Type check failed"
exit 1
fi
if [[ "${{ needs.security.result }}" == "failure" ]]; then
echo "❌ Security scan failed"
exit 1
fi
if [[ "${{ needs.test.result }}" == "failure" ]]; then
echo "❌ Tests failed"
exit 1
fi
if [[ "${{ needs.dependency-check.result }}" == "failure" ]]; then
echo "❌ Dependency check failed"
exit 1
fi
echo "✅ All checks passed!"