Compare commits
15
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0458403e67 | ||
|
|
885dff413c | ||
|
|
f8a30c0f5c | ||
|
|
2d92084489 | ||
|
|
a42012d9c0 | ||
|
|
0de9177e7c | ||
|
|
48147465b5 | ||
|
|
92bdfb421b | ||
|
|
4257fea9d6 | ||
|
|
e8eed3e641 | ||
|
|
2918608240 | ||
|
|
a99aed9a5f | ||
|
|
00e8ec001b | ||
|
|
d20ff7a243 | ||
|
|
bc0951115b |
@@ -19,6 +19,14 @@ frontend/node_modules
|
|||||||
frontend/dist
|
frontend/dist
|
||||||
dist
|
dist
|
||||||
artifacts
|
artifacts
|
||||||
|
docs
|
||||||
|
deploy
|
||||||
|
n8n/**
|
||||||
|
!n8n/workflows/
|
||||||
|
!n8n/workflows/**
|
||||||
|
frontend
|
||||||
|
*.tgz
|
||||||
|
*.tar.gz
|
||||||
coverage
|
coverage
|
||||||
playwright-report
|
playwright-report
|
||||||
test-results
|
test-results
|
||||||
|
|||||||
@@ -86,6 +86,10 @@ N8N_ENCRYPTION_KEY=replace-me
|
|||||||
N8N_BASIC_AUTH_ACTIVE=true
|
N8N_BASIC_AUTH_ACTIVE=true
|
||||||
N8N_BASIC_AUTH_USER=admin
|
N8N_BASIC_AUTH_USER=admin
|
||||||
N8N_BASIC_AUTH_PASSWORD=change-me
|
N8N_BASIC_AUTH_PASSWORD=change-me
|
||||||
|
# Recipient and sender used by the importable alert workflow. Configure real,
|
||||||
|
# monitored addresses in the deployment environment; repository defaults stay synthetic.
|
||||||
|
MOBILITYOPS_ALERT_RECIPIENT=alerts@example.test
|
||||||
|
MOBILITYOPS_ALERT_SENDER=n8n@example.test
|
||||||
MOBILITYOPS_CALLBACK_TOKEN=replace-me-n8n-callback-token
|
MOBILITYOPS_CALLBACK_TOKEN=replace-me-n8n-callback-token
|
||||||
# Sent as the X-Fleet-Ops-Trigger-Token header when Fleet Ops calls the n8n return-
|
# Sent as the X-Fleet-Ops-Trigger-Token header when Fleet Ops calls the n8n return-
|
||||||
# processing webhook, so the webhook trigger can require Header Auth instead of being
|
# processing webhook, so the webhook trigger can require Header Auth instead of being
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ permissions:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
chromium:
|
chromium:
|
||||||
runs-on: ubuntu-latest
|
runs-on: linux-validation
|
||||||
timeout-minutes: 15
|
timeout-minutes: 15
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
|
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
|
||||||
|
|||||||
+33
-6
@@ -12,7 +12,9 @@ permissions:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
acceptance:
|
acceptance:
|
||||||
runs-on: ubuntu-latest
|
# Never execute code from an untrusted public fork on the private runner.
|
||||||
|
if: ${{ gitea.event.pull_request.head.repo.full_name == gitea.repository }}
|
||||||
|
runs-on: linux-validation
|
||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
|
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
|
||||||
@@ -31,10 +33,19 @@ jobs:
|
|||||||
echo "Product or test change: running the complete acceptance gate."
|
echo "Product or test change: running the complete acceptance gate."
|
||||||
fi
|
fi
|
||||||
- name: Secret scan
|
- name: Secret scan
|
||||||
uses: trufflesecurity/trufflehog@b9dd330365132cd2d01dd5dc8a857a056a2544e1 # v3.79.0
|
shell: bash
|
||||||
with:
|
run: |
|
||||||
path: ./
|
set -euo pipefail
|
||||||
extra_args: --only-verified
|
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
|
- name: Backend tests in isolated PostgreSQL stack
|
||||||
if: steps.scope.outputs.full == 'true'
|
if: steps.scope.outputs.full == 'true'
|
||||||
run: sh scripts/run-isolated-tests.sh
|
run: sh scripts/run-isolated-tests.sh
|
||||||
@@ -44,8 +55,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 --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 api mypy app
|
||||||
docker compose -p mobilityops-ci -f compose.yaml -f compose.test.yaml run --rm \
|
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
|
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
|
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||||
if: steps.scope.outputs.full == 'true'
|
if: steps.scope.outputs.full == 'true'
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ permissions:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
public-probe:
|
public-probe:
|
||||||
runs-on: ubuntu-latest
|
runs-on: linux-validation
|
||||||
timeout-minutes: 3
|
timeout-minutes: 3
|
||||||
steps:
|
steps:
|
||||||
- name: Verify HTTPS readiness and certificate horizon
|
- name: Verify HTTPS readiness and certificate horizon
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
name: Managed validation
|
name: Managed validation
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
push:
|
||||||
|
branches: [master]
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
inputs:
|
inputs:
|
||||||
profile:
|
profile:
|
||||||
@@ -20,7 +22,7 @@ concurrency:
|
|||||||
jobs:
|
jobs:
|
||||||
full:
|
full:
|
||||||
name: full
|
name: full
|
||||||
runs-on: ubuntu-latest
|
runs-on: linux-validation
|
||||||
timeout-minutes: 30
|
timeout-minutes: 30
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
release-evidence:
|
release-evidence:
|
||||||
runs-on: ubuntu-latest
|
runs-on: linux-validation
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
|
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
|
||||||
- name: Build commit-labelled release images
|
- name: Build commit-labelled release images
|
||||||
@@ -29,8 +29,8 @@ jobs:
|
|||||||
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
|
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
|
||||||
-v "$PWD:/work" -w /work \
|
-v "$PWD:/work" -w /work \
|
||||||
aquasec/trivy:0.74.0@sha256:62b1e65e8869bc4b4c6aa4fa2b21595256c7c2f6018a9d9ad61caf87187c1969 \
|
aquasec/trivy:0.74.0@sha256:62b1e65e8869bc4b4c6aa4fa2b21595256c7c2f6018a9d9ad61caf87187c1969 \
|
||||||
image --format cyclonedx --output "mobilityops-${component}-sbom.cdx.json" \
|
image --format cyclonedx --output "mobilityops-${component}-sbom.cdx.json" \
|
||||||
"mobilityops-${component}-release"
|
"mobilityops-${component}-release"
|
||||||
done
|
done
|
||||||
- name: Record immutable image metadata
|
- name: Record immutable image metadata
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ permissions:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
images:
|
images:
|
||||||
runs-on: ubuntu-latest
|
runs-on: linux-validation
|
||||||
timeout-minutes: 30
|
timeout-minutes: 30
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
|
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
name: Unraid autoredeploy
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [master]
|
|
||||||
paths-ignore:
|
|
||||||
- ".gitea/**"
|
|
||||||
- "docs/**"
|
|
||||||
- "**/*.md"
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: unraid-production-mobilityops
|
|
||||||
cancel-in-progress: false
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
deploy:
|
|
||||||
name: Deploy mobilityops
|
|
||||||
runs-on: unraid-deploy
|
|
||||||
timeout-minutes: 180
|
|
||||||
steps:
|
|
||||||
- name: Deploy exact Gitea revision
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
docker exec gitea-deploy-control \
|
|
||||||
/opt/gitea-deploy/deploy.py deploy \
|
|
||||||
"$GITHUB_REPOSITORY" "$GITHUB_SHA"
|
|
||||||
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
81e3fd63bdbcb2e9c4ae1d709ea46f40537b6f62:backend/tests/test_data_quality.py:generic-api-key:869
|
||||||
|
0091c57c7fd82ffda16da1edfe5fa5589c8f1e13:backend/tests/test_return.py:generic-api-key:93
|
||||||
|
0091c57c7fd82ffda16da1edfe5fa5589c8f1e13:backend/tests/test_return.py:generic-api-key:122
|
||||||
|
0091c57c7fd82ffda16da1edfe5fa5589c8f1e13:backend/tests/test_return.py:generic-api-key:127
|
||||||
+1
-1
@@ -15,7 +15,7 @@ release line only.
|
|||||||
|
|
||||||
Do not disclose suspected vulnerabilities through a public issue.
|
Do not disclose suspected vulnerabilities through a public issue.
|
||||||
|
|
||||||
Report them privately to `jens@itworx.tech` with:
|
Report them privately to `security@itworx.tech` with:
|
||||||
|
|
||||||
- the affected revision, endpoint or component;
|
- the affected revision, endpoint or component;
|
||||||
- reproduction steps and prerequisites;
|
- reproduction steps and prerequisites;
|
||||||
|
|||||||
@@ -24,6 +24,9 @@ FROM runtime-base AS test
|
|||||||
COPY backend/requirements.lock ./requirements.lock
|
COPY backend/requirements.lock ./requirements.lock
|
||||||
RUN pip install --no-cache-dir -r requirements.lock
|
RUN pip install --no-cache-dir -r requirements.lock
|
||||||
COPY backend/tests ./tests
|
COPY backend/tests ./tests
|
||||||
|
COPY contracts ./contracts
|
||||||
|
COPY scripts/check-contracts.py ./scripts/check-contracts.py
|
||||||
|
COPY n8n/workflows ./n8n/workflows
|
||||||
USER app
|
USER app
|
||||||
|
|
||||||
FROM runtime-base AS runtime
|
FROM runtime-base AS runtime
|
||||||
|
|||||||
@@ -107,6 +107,8 @@ services:
|
|||||||
N8N_BASIC_AUTH_PASSWORD: ${N8N_BASIC_AUTH_PASSWORD:-change-me}
|
N8N_BASIC_AUTH_PASSWORD: ${N8N_BASIC_AUTH_PASSWORD:-change-me}
|
||||||
N8N_SECURE_COOKIE: "false"
|
N8N_SECURE_COOKIE: "false"
|
||||||
N8N_BLOCK_ENV_ACCESS_IN_NODE: "false"
|
N8N_BLOCK_ENV_ACCESS_IN_NODE: "false"
|
||||||
|
MOBILITYOPS_ALERT_RECIPIENT: ${MOBILITYOPS_ALERT_RECIPIENT:-alerts@example.test}
|
||||||
|
MOBILITYOPS_ALERT_SENDER: ${MOBILITYOPS_ALERT_SENDER:-n8n@example.test}
|
||||||
MOBILITYOPS_CALLBACK_TOKEN: ${MOBILITYOPS_CALLBACK_TOKEN:-replace-me-n8n-callback-token}
|
MOBILITYOPS_CALLBACK_TOKEN: ${MOBILITYOPS_CALLBACK_TOKEN:-replace-me-n8n-callback-token}
|
||||||
ports:
|
ports:
|
||||||
- "5678:5678"
|
- "5678:5678"
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ ENV VITE_API_BASE_URL=$VITE_API_BASE_URL
|
|||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
FROM nginx:1.30.4-alpine@sha256:97d490c12ba55b4946b01546d1c3ed324e8d41ab1c9fcb2a616aa470620e5b46
|
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 VCS_REF=development
|
||||||
ARG BUILD_DATE=unknown
|
ARG BUILD_DATE=unknown
|
||||||
LABEL org.opencontainers.image.title="Fleet Ops Web" \
|
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.goto("/login");
|
||||||
await page.getByRole("button", { name: "Verken als Operationsmanager" }).click();
|
await page.getByRole("button", { name: "Verken als Operationsmanager" }).click();
|
||||||
await expect(page).toHaveURL(/\/dashboard$/);
|
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 [
|
for (const [path, heading] of [
|
||||||
["/vehicles", "Wagenpark"],
|
["/vehicles", "Wagenpark"],
|
||||||
|
|||||||
@@ -6,6 +6,10 @@ export default defineConfig({
|
|||||||
// it mutates demo data via a reset and is run explicitly, not as part of the suite.
|
// it mutates demo data via a reset and is run explicitly, not as part of the suite.
|
||||||
testIgnore: process.env.CAPTURE_EVIDENCE === "1" ? undefined : "**/_*.spec.ts",
|
testIgnore: process.env.CAPTURE_EVIDENCE === "1" ? undefined : "**/_*.spec.ts",
|
||||||
timeout: 30_000,
|
timeout: 30_000,
|
||||||
|
// CI exercises the browser while image scans and container services share the
|
||||||
|
// same runner. Keep assertions strict, but allow successful API-backed route
|
||||||
|
// transitions enough time to render under that bounded load.
|
||||||
|
expect: { timeout: 15_000 },
|
||||||
fullyParallel: false,
|
fullyParallel: false,
|
||||||
workers: 1,
|
workers: 1,
|
||||||
snapshotPathTemplate: "{testDir}/__screenshots__/{arg}{ext}",
|
snapshotPathTemplate: "{testDir}/__screenshots__/{arg}{ext}",
|
||||||
|
|||||||
@@ -121,4 +121,4 @@ this handler was not observed live.
|
|||||||
| Active status | Imported inactive by default; production deployment must publish it before enabling Alertmanager. |
|
| Active status | Imported inactive by default; production deployment must publish it before enabling Alertmanager. |
|
||||||
| Error Workflow | `Fleet Ops — Workflow Error Handler` (wired) |
|
| Error Workflow | `Fleet Ops — Workflow Error Handler` (wired) |
|
||||||
| Safety | Strict Alertmanager payload shape, bounded to 25 alerts and bounded text fields. |
|
| Safety | Strict Alertmanager payload shape, bounded to 25 alerts and bounded text fields. |
|
||||||
| Checksum (sha256) | `3672ad3d14b65c603c8c3f2067197cc50372e9d4c2fc314d1c9b6aaf3ecef444` |
|
| Checksum (sha256) | `4eb1ae41c4e675a9bb51a43722a507da8a6eae8a6ce8649b7e3a57417911a418` |
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
"id": "accept", "name": "Accept alert", "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1.4, "position": [740, 300]
|
"id": "accept", "name": "Accept alert", "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1.4, "position": [740, 300]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"parameters": {"toRecipients": "jens@itworx.tech", "subject": "={{ $('Validate and format').item.json.subject }}", "bodyContent": "={{ $('Validate and format').item.json.html }}", "additionalFields": {"from": "n8n@itworx.tech", "bodyContentType": "html"}},
|
"parameters": {"toRecipients": "={{ $env.MOBILITYOPS_ALERT_RECIPIENT || 'alerts@example.test' }}", "subject": "={{ $('Validate and format').item.json.subject }}", "bodyContent": "={{ $('Validate and format').item.json.html }}", "additionalFields": {"from": "={{ $env.MOBILITYOPS_ALERT_SENDER || 'n8n@example.test' }}", "bodyContentType": "html"}},
|
||||||
"id": "email", "name": "Send owner email", "type": "n8n-nodes-base.microsoftOutlook", "typeVersion": 2, "position": [980, 300],
|
"id": "email", "name": "Send owner email", "type": "n8n-nodes-base.microsoftOutlook", "typeVersion": 2, "position": [980, 300],
|
||||||
"credentials": {"microsoftOutlookOAuth2Api": {"id": "EDTj3sOsganaoDVL", "name": "M365 n8n Shared Mailbox"}},
|
"credentials": {"microsoftOutlookOAuth2Api": {"id": "EDTj3sOsganaoDVL", "name": "M365 n8n Shared Mailbox"}},
|
||||||
"retryOnFail": true, "maxTries": 3, "waitBetweenTries": 1000
|
"retryOnFail": true, "maxTries": 3, "waitBetweenTries": 1000
|
||||||
|
|||||||
@@ -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