Merge pull request 'Use Gitea-compatible canary evidence upload' (#3) from codex/resolve-projectbrain-findings-20260828 into master
Unraid autoredeploy / Deploy mobilityops (push) Failing after 1m11s
Unraid autoredeploy / Deploy mobilityops (push) Failing after 1m11s
Reviewed-on: #3
This commit was merged in pull request #3.
This commit is contained in:
@@ -19,6 +19,14 @@ frontend/node_modules
|
||||
frontend/dist
|
||||
dist
|
||||
artifacts
|
||||
docs
|
||||
deploy
|
||||
n8n/**
|
||||
!n8n/workflows/
|
||||
!n8n/workflows/**
|
||||
frontend
|
||||
*.tgz
|
||||
*.tar.gz
|
||||
coverage
|
||||
playwright-report
|
||||
test-results
|
||||
|
||||
+30
-5
@@ -31,10 +31,19 @@ jobs:
|
||||
echo "Product or test change: running the complete acceptance gate."
|
||||
fi
|
||||
- name: Secret scan
|
||||
uses: trufflesecurity/trufflehog@b9dd330365132cd2d01dd5dc8a857a056a2544e1 # v3.79.0
|
||||
with:
|
||||
path: ./
|
||||
extra_args: --only-verified
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
repository="$PWD"
|
||||
source="file:///repo"
|
||||
workspace=(-v "$repository:/repo" -w /repo)
|
||||
if docker inspect "${HOSTNAME:-}" >/dev/null 2>&1; then
|
||||
source="file://$repository"
|
||||
workspace=(--volumes-from "$HOSTNAME" -w "$repository")
|
||||
fi
|
||||
docker run --rm "${workspace[@]}" \
|
||||
ghcr.io/trufflesecurity/trufflehog@sha256:7104dbb84d1ad2f5f6fa1134e92c6aa6f701f0a4ac2efd5a4c5c96225d899fe3 \
|
||||
git "$source" --fail --no-update --github-actions --only-verified
|
||||
- name: Backend tests in isolated PostgreSQL stack
|
||||
if: steps.scope.outputs.full == 'true'
|
||||
run: sh scripts/run-isolated-tests.sh
|
||||
@@ -44,8 +53,24 @@ jobs:
|
||||
docker compose -p mobilityops-ci -f compose.yaml -f compose.test.yaml run --build --rm api ruff check app tests
|
||||
docker compose -p mobilityops-ci -f compose.yaml -f compose.test.yaml run --rm api mypy app
|
||||
docker compose -p mobilityops-ci -f compose.yaml -f compose.test.yaml run --rm \
|
||||
-v "$PWD:/repo:ro" api python /repo/scripts/check-contracts.py
|
||||
api python scripts/check-contracts.py
|
||||
python scripts/check-source-budgets.py
|
||||
- name: Build production API image for vulnerability scan
|
||||
if: steps.scope.outputs.full == 'true'
|
||||
run: |
|
||||
docker build --target runtime --build-arg VCS_REF="$GITHUB_SHA" \
|
||||
--tag mobilityops-api-ci --file backend/Dockerfile .
|
||||
- name: Production API image vulnerability scan (HIGH/CRITICAL)
|
||||
if: steps.scope.outputs.full == 'true'
|
||||
run: bash scripts/scan-ci-image.sh mobilityops-api-ci
|
||||
- name: Build production web image for vulnerability scan
|
||||
if: steps.scope.outputs.full == 'true'
|
||||
run: |
|
||||
docker build --build-arg VCS_REF="$GITHUB_SHA" \
|
||||
--tag mobilityops-web-ci frontend
|
||||
- name: Production web image vulnerability scan (HIGH/CRITICAL)
|
||||
if: steps.scope.outputs.full == 'true'
|
||||
run: bash scripts/scan-ci-image.sh mobilityops-web-ci
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
if: steps.scope.outputs.full == 'true'
|
||||
with:
|
||||
|
||||
@@ -24,6 +24,9 @@ FROM runtime-base AS test
|
||||
COPY backend/requirements.lock ./requirements.lock
|
||||
RUN pip install --no-cache-dir -r requirements.lock
|
||||
COPY backend/tests ./tests
|
||||
COPY contracts ./contracts
|
||||
COPY scripts/check-contracts.py ./scripts/check-contracts.py
|
||||
COPY n8n/workflows ./n8n/workflows
|
||||
USER app
|
||||
|
||||
FROM runtime-base AS runtime
|
||||
|
||||
@@ -11,6 +11,9 @@ ENV VITE_API_BASE_URL=$VITE_API_BASE_URL
|
||||
RUN npm run build
|
||||
|
||||
FROM nginx:1.30.4-alpine@sha256:97d490c12ba55b4946b01546d1c3ed324e8d41ab1c9fcb2a616aa470620e5b46
|
||||
# The pinned upstream image can lag Alpine security rebuilds. Apply the current
|
||||
# fixes from its pinned Alpine release before shipping the runtime image.
|
||||
RUN apk upgrade --no-cache
|
||||
ARG VCS_REF=development
|
||||
ARG BUILD_DATE=unknown
|
||||
LABEL org.opencontainers.image.title="Fleet Ops Web" \
|
||||
|
||||
@@ -26,6 +26,15 @@ test("non-destructive operator canary covers routes and grounded knowledge", asy
|
||||
await page.goto("/login");
|
||||
await page.getByRole("button", { name: "Verken als Operationsmanager" }).click();
|
||||
await expect(page).toHaveURL(/\/dashboard$/);
|
||||
if (pageErrors.some((message) => message.toLowerCase().includes("dynamically imported module"))) {
|
||||
// A deploy can replace the SPA between loading index.html and its lazy
|
||||
// dashboard chunk. One clean reload must recover; a persistent chunk or
|
||||
// server error is collected again and still fails the canary below.
|
||||
pageErrors.length = 0;
|
||||
await page.reload({ waitUntil: "domcontentloaded" });
|
||||
await expect(page).toHaveURL(/\/dashboard$/);
|
||||
await expect(page.locator("main")).toBeVisible();
|
||||
}
|
||||
|
||||
for (const [path, heading] of [
|
||||
["/vehicles", "Wagenpark"],
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
TARGET_IMAGE="${1:?usage: scan-ci-image.sh <image>}"
|
||||
TRIVY_IMAGE="aquasec/trivy@sha256:be1190afcb28352bfddc4ddeb71470835d16462af68d310f9f4bca710961a41e"
|
||||
SAFE_NAME="$(printf '%s' "$TARGET_IMAGE" | tr -cs 'A-Za-z0-9._-' '-')"
|
||||
ARCHIVE_RELATIVE="artifacts/.${SAFE_NAME}.tar"
|
||||
ARCHIVE="$ROOT/$ARCHIVE_RELATIVE"
|
||||
trap 'rm -f "$ARCHIVE"' EXIT
|
||||
|
||||
mkdir -p "$ROOT/artifacts"
|
||||
docker image inspect "$TARGET_IMAGE" >/dev/null
|
||||
docker save --output "$ARCHIVE" "$TARGET_IMAGE"
|
||||
|
||||
WORKSPACE_ARGS=(-v "$ROOT:/workspace:ro")
|
||||
CONTAINER_ARCHIVE="/workspace/$ARCHIVE_RELATIVE"
|
||||
if docker inspect "${HOSTNAME:-}" >/dev/null 2>&1; then
|
||||
WORKSPACE_ARGS=(--volumes-from "$HOSTNAME")
|
||||
CONTAINER_ARCHIVE="$ROOT/$ARCHIVE_RELATIVE"
|
||||
fi
|
||||
|
||||
docker run --rm "${WORKSPACE_ARGS[@]}" "$TRIVY_IMAGE" image \
|
||||
--input "$CONTAINER_ARCHIVE" \
|
||||
--scanners vuln \
|
||||
--severity HIGH,CRITICAL \
|
||||
--ignore-unfixed \
|
||||
--exit-code 1 \
|
||||
--format table
|
||||
Reference in New Issue
Block a user