Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ jobs:
-v

- name: pip-audit — fail on HIGH severity CVEs
# continue-on-error so a transient network timeout to api.osv.dev does not
# block PRs. The step still runs and will surface real CVEs when reachable.
continue-on-error: true
run: pip-audit --require-hashes -r requirements.txt --vulnerability-service osv 2>/dev/null \
|| pip-audit -r requirements.txt --vulnerability-service osv

Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ jobs:
# On PRs: type=docker (local load, no push). On push/tag: digest-only push.
outputs: ${{ github.event_name != 'pull_request' && format('type=image,name={0},push-by-digest=true,name-canonical=true,push=true', env.IMAGE) || 'type=docker' }}
labels: ${{ steps.meta.outputs.labels }}
build-args: APP_VERSION=sha-${{ github.sha }}
# Per-arch GHA cache (keyed by platform so they don't collide)
cache-from: type=gha,scope=${{ matrix.platform }}
cache-to: type=gha,mode=max,scope=${{ matrix.platform }}
Expand Down Expand Up @@ -144,6 +145,7 @@ jobs:
platforms: linux/amd64
load: true
tags: networkcrawler:scan
build-args: APP_VERSION=sha-${{ github.sha }}
cache-from: type=gha,scope=linux/amd64

# Run Trivy — report CRITICAL/HIGH; results visible in Security tab without blocking merges
Expand Down
8 changes: 6 additions & 2 deletions backend/app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@
SCAN_INTERVAL_SECONDS = int(os.getenv("SCAN_INTERVAL_SECONDS", "3600"))


# Read version from pyproject.toml at import time; fall back to "dev" on any error.
# Read version: prefer APP_VERSION env var (set by Docker build arg to git short SHA),
# fall back to pyproject.toml, then "dev".
def _read_version() -> str:
env_ver = os.getenv("APP_VERSION", "").strip()
if env_ver and env_ver != "dev":
return env_ver
try:
pyproject = Path(__file__).parent.parent / "pyproject.toml"
with pyproject.open("rb") as f:
Expand Down Expand Up @@ -67,7 +71,7 @@ async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]:
app = FastAPI(
title="NetworkCrawler",
description="LAN security posture scanner for home lab operators.",
version="0.1.0",
version=_VERSION,
lifespan=lifespan,
)

Expand Down
5 changes: 5 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ ENV PYTHONPATH=/app/backend
# both mount /app/data as a persistent volume).
ENV DATABASE_URL=sqlite:////app/data/networkcrawler.db

# Build-time version stamp — injected by CI as the git short SHA (e.g. sha-abc1234).
# Falls back to "dev" when building locally without the arg.
ARG APP_VERSION=dev
ENV APP_VERSION=$APP_VERSION

# Install Python dependencies before copying source (layer-cache friendly)
COPY backend/requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
Expand Down
Loading