Skip to content

deps(control-ui): bump starlette from 1.3.1 to 1.6.0 in /services/control-ui #95

deps(control-ui): bump starlette from 1.3.1 to 1.6.0 in /services/control-ui

deps(control-ui): bump starlette from 1.3.1 to 1.6.0 in /services/control-ui #95

Workflow file for this run

# CI: run every service's test suite via its Dockerfile test stage.
# The test stage IS the single source of truth for "tests green" — identical
# locally (docker build --target test services/<name>) and here.
name: ci
on:
push:
branches: [main]
pull_request:
jobs:
# OSS-maturity gate: lint (ruff) + dependency vulnerability audit (pip-audit).
# Real gate — any finding fails CI. Config lives in repo-root ruff.toml.
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with: { python-version: "3.12" }
- name: Install tools
run: pip install ruff==0.15.17 pip-audit==2.10.1 mypy==1.14.1 # pinned — avoid pipeline drift
- name: Ruff lint
run: ruff check .
- name: mypy (scoped, passing gate over the typed cores — see mypy.ini)
# Run PER SERVICE: every service ships a top-level `src` package, so a single mypy
# invocation across services mis-resolves shared module names (e.g. two `src.drivers`).
run: |
mypy --config-file mypy.ini \
services/surplus-controller/src/statemachine.py \
services/surplus-controller/src/threshold.py \
services/surplus-controller/src/config.py \
services/surplus-controller/src/dblog.py \
services/surplus-controller/src/relays/shelly.py \
services/surplus-controller/src/relays/__init__.py
mypy --config-file mypy.ini \
services/energy-exporter/src/sma_decoder.py \
services/energy-exporter/src/tsdb_writer.py \
services/energy-exporter/src/drivers/sma_modbus.py
mypy --config-file mypy.ini \
services/heatpump-exporter/src/extract.py \
services/heatpump-exporter/src/ratebudget.py \
services/heatpump-exporter/src/metrics.py \
services/heatpump-exporter/src/auth.py
mypy --config-file mypy.ini \
services/control-ui/src/validation.py
- name: pip-audit (per service)
run: |
rc=0
for req in services/*/requirements.txt; do
echo "::group::pip-audit $req"
pip-audit -r "$req" || rc=1
echo "::endgroup::"
done
exit $rc
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
service: [energy-exporter, surplus-controller, heatpump-exporter, control-ui]
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
- name: Run test stage
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
with:
context: services/${{ matrix.service }}
target: test
push: false
cache-from: type=gha,scope=test-${{ matrix.service }}
cache-to: type=gha,scope=test-${{ matrix.service }},mode=max
# OS-layer CVE gate: pip-audit only sees Python deps; this scans the BUILT final image's
# Debian base for HIGH/CRITICAL vulnerabilities. --ignore-unfixed so we only fail on CVEs
# that actually have a fix to apply (a base-image bump), not unfixable noise.
image-scan:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
service: [energy-exporter, surplus-controller, heatpump-exporter, control-ui]
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
- name: Build final image
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
with:
context: services/${{ matrix.service }}
target: final
push: false
load: true
tags: sunsteer-scan:${{ matrix.service }}
cache-from: type=gha,scope=test-${{ matrix.service }}
- name: Trivy scan (HIGH/CRITICAL, fixable only)
run: |
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy:0.58.1 image \
--severity HIGH,CRITICAL --ignore-unfixed --exit-code 1 --no-progress \
sunsteer-scan:${{ matrix.service }}
# Real-DB smoke: runs the actual source SQL against a real TimescaleDB with
# db/init.sql + db/migrations/*.sql applied, catching schema/column drift the
# mocked per-service unit suites cannot see.
db-integration:
runs-on: ubuntu-latest
services:
timescaledb:
image: timescale/timescaledb@sha256:22e8a5ae7aef121d1537afe946dd7cc5deeeb63ab36ce19849d671bd3b663509 # latest-pg16, digest-pinned (matches runtime)
env:
POSTGRES_USER: sunsteer
POSTGRES_PASSWORD: sunsteer
POSTGRES_DB: energy
ports: ["5432:5432"]
options: >-
--health-cmd "pg_isready -U sunsteer -d energy"
--health-interval 5s --health-timeout 3s --health-retries 12
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with: { python-version: "3.12" }
- name: Apply schema + migrations
env: { PGPASSWORD: sunsteer }
run: |
sudo apt-get update && sudo apt-get install -y postgresql-client
psql -h localhost -U sunsteer -d energy -v ON_ERROR_STOP=1 -f db/init.sql
for f in $(find db/migrations -name '*.sql' | sort); do
psql -h localhost -U sunsteer -d energy -v ON_ERROR_STOP=1 -f "$f"; done
- name: Run integration smoke
env:
PGHOST: localhost
PGPORT: "5432"
PGDATABASE: energy
PGUSER: sunsteer
PGPASSWORD: sunsteer
run: |
pip install psycopg2-binary pytest
python -m pytest tests/integration -q