bompage 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bompage-1.0.0/.gitignore +30 -0
- bompage-1.0.0/.gitlab-ci.yml +335 -0
- bompage-1.0.0/.gitleaks.toml +4 -0
- bompage-1.0.0/.markdownlint.yaml +9 -0
- bompage-1.0.0/.node-version +1 -0
- bompage-1.0.0/.pre-commit-config.yaml +27 -0
- bompage-1.0.0/.python-version +1 -0
- bompage-1.0.0/.releaserc +17 -0
- bompage-1.0.0/.yamllint +17 -0
- bompage-1.0.0/LICENSE +21 -0
- bompage-1.0.0/PKG-INFO +241 -0
- bompage-1.0.0/README.md +223 -0
- bompage-1.0.0/Taskfile.project.yml +161 -0
- bompage-1.0.0/Taskfile.yml +195 -0
- bompage-1.0.0/biome.json +30 -0
- bompage-1.0.0/deploy/.gitlab-ci.yml +78 -0
- bompage-1.0.0/deploy/README.md +90 -0
- bompage-1.0.0/deploy/reports/example-component/.gitkeep +0 -0
- bompage-1.0.0/deploy/web/.gitkeep +0 -0
- bompage-1.0.0/docs/analysis/drift.md +2 -0
- bompage-1.0.0/docs/analysis/freshness.md +2 -0
- bompage-1.0.0/docs/analysis/inventory.md +2 -0
- bompage-1.0.0/docs/analysis/timeline.md +2 -0
- bompage-1.0.0/docs/bompage.md +2 -0
- bompage-1.0.0/docs/build.md +2 -0
- bompage-1.0.0/docs/cli.md +20 -0
- bompage-1.0.0/docs/discovery.md +2 -0
- bompage-1.0.0/docs/index.md +8 -0
- bompage-1.0.0/docs/models.md +2 -0
- bompage-1.0.0/docs/parsers/base.md +2 -0
- bompage-1.0.0/docs/parsers/cyclonedx.md +2 -0
- bompage-1.0.0/docs/parsers/spdx.md +2 -0
- bompage-1.0.0/docs/prune.md +2 -0
- bompage-1.0.0/docs/push.md +2 -0
- bompage-1.0.0/docs/render/api.md +2 -0
- bompage-1.0.0/docs/render/data.md +2 -0
- bompage-1.0.0/docs/render/web.md +2 -0
- bompage-1.0.0/lychee.toml +4 -0
- bompage-1.0.0/mkdocs.yml +40 -0
- bompage-1.0.0/package.json +35 -0
- bompage-1.0.0/pnpm-lock.yaml +1284 -0
- bompage-1.0.0/pnpm-workspace.yaml +6 -0
- bompage-1.0.0/pyproject.toml +126 -0
- bompage-1.0.0/renovate.json +53 -0
- bompage-1.0.0/scripts/gen-demo-data.py +742 -0
- bompage-1.0.0/scripts/subset-icons.mjs +60 -0
- bompage-1.0.0/src/bompage/__init__.py +0 -0
- bompage-1.0.0/src/bompage/_git.py +72 -0
- bompage-1.0.0/src/bompage/_time.py +20 -0
- bompage-1.0.0/src/bompage/analysis/__init__.py +0 -0
- bompage-1.0.0/src/bompage/analysis/drift.py +71 -0
- bompage-1.0.0/src/bompage/analysis/freshness.py +30 -0
- bompage-1.0.0/src/bompage/analysis/inventory.py +85 -0
- bompage-1.0.0/src/bompage/analysis/timeline.py +120 -0
- bompage-1.0.0/src/bompage/bompage.py +276 -0
- bompage-1.0.0/src/bompage/build.py +254 -0
- bompage-1.0.0/src/bompage/discovery.py +48 -0
- bompage-1.0.0/src/bompage/metadata.py +64 -0
- bompage-1.0.0/src/bompage/models.py +122 -0
- bompage-1.0.0/src/bompage/parsers/__init__.py +0 -0
- bompage-1.0.0/src/bompage/parsers/base.py +66 -0
- bompage-1.0.0/src/bompage/parsers/cyclonedx.py +88 -0
- bompage-1.0.0/src/bompage/parsers/spdx.py +64 -0
- bompage-1.0.0/src/bompage/prune.py +137 -0
- bompage-1.0.0/src/bompage/push.py +224 -0
- bompage-1.0.0/src/bompage/py.typed +0 -0
- bompage-1.0.0/src/bompage/render/__init__.py +0 -0
- bompage-1.0.0/src/bompage/render/api.py +8 -0
- bompage-1.0.0/src/bompage/render/data.py +98 -0
- bompage-1.0.0/src/bompage/render/web.py +47 -0
- bompage-1.0.0/templates/push-report.yml +118 -0
- bompage-1.0.0/tests/__init__.py +0 -0
- bompage-1.0.0/tests/analysis/__init__.py +0 -0
- bompage-1.0.0/tests/analysis/test_drift.py +102 -0
- bompage-1.0.0/tests/analysis/test_freshness.py +35 -0
- bompage-1.0.0/tests/analysis/test_inventory.py +97 -0
- bompage-1.0.0/tests/analysis/test_timeline.py +93 -0
- bompage-1.0.0/tests/conftest.py +22 -0
- bompage-1.0.0/tests/files/cyclonedx/simple.cdx.json +52 -0
- bompage-1.0.0/tests/files/reports/app-api/sbom-20260115.json +71 -0
- bompage-1.0.0/tests/files/spdx/simple.spdx.json +71 -0
- bompage-1.0.0/tests/files/spdx/web-frontend.spdx.json +52 -0
- bompage-1.0.0/tests/parsers/__init__.py +0 -0
- bompage-1.0.0/tests/parsers/test_base.py +87 -0
- bompage-1.0.0/tests/parsers/test_cyclonedx.py +155 -0
- bompage-1.0.0/tests/parsers/test_spdx.py +113 -0
- bompage-1.0.0/tests/render/__init__.py +0 -0
- bompage-1.0.0/tests/render/test_data.py +187 -0
- bompage-1.0.0/tests/render/test_web.py +80 -0
- bompage-1.0.0/tests/test_bompage.py +133 -0
- bompage-1.0.0/tests/test_build.py +308 -0
- bompage-1.0.0/tests/test_dashboard_e2e.py +303 -0
- bompage-1.0.0/tests/test_discovery.py +55 -0
- bompage-1.0.0/tests/test_metadata.py +79 -0
- bompage-1.0.0/tests/test_models.py +24 -0
- bompage-1.0.0/tests/test_prune.py +83 -0
- bompage-1.0.0/tests/test_prune_report.py +317 -0
- bompage-1.0.0/tests/test_push_report.py +658 -0
- bompage-1.0.0/tests/test_time.py +24 -0
- bompage-1.0.0/tsconfig.json +16 -0
- bompage-1.0.0/uv.lock +1230 -0
- bompage-1.0.0/vite.config.ts +23 -0
- bompage-1.0.0/vitest.config.ts +13 -0
- bompage-1.0.0/web-src/app.test.ts +24 -0
- bompage-1.0.0/web-src/app.ts +578 -0
- bompage-1.0.0/web-src/bompage.png +0 -0
- bompage-1.0.0/web-src/index.html +35 -0
- bompage-1.0.0/web-src/lib.test.ts +247 -0
- bompage-1.0.0/web-src/lib.ts +192 -0
- bompage-1.0.0/web-src/public/android-chrome-192x192.png +0 -0
- bompage-1.0.0/web-src/public/android-chrome-512x512.png +0 -0
- bompage-1.0.0/web-src/public/apple-touch-icon.png +0 -0
- bompage-1.0.0/web-src/public/favicon-16x16.png +0 -0
- bompage-1.0.0/web-src/public/favicon-32x32.png +0 -0
- bompage-1.0.0/web-src/public/favicon.ico +0 -0
- bompage-1.0.0/web-src/public/site.webmanifest +11 -0
- bompage-1.0.0/web-src/theme.css +420 -0
bompage-1.0.0/.gitignore
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# python generated files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[oc]
|
|
4
|
+
.coverage
|
|
5
|
+
build/
|
|
6
|
+
dist/
|
|
7
|
+
wheels/
|
|
8
|
+
*.egg-info
|
|
9
|
+
|
|
10
|
+
# build output & coverage reports (anchored so deploy/reports/ stays tracked)
|
|
11
|
+
/public/
|
|
12
|
+
/reports/
|
|
13
|
+
/demo-reports/
|
|
14
|
+
|
|
15
|
+
# JS toolchain: web-src/ is the source, src/bompage/web/ is the Vite build output
|
|
16
|
+
/node_modules/
|
|
17
|
+
/.pnpm-store/
|
|
18
|
+
/src/bompage/web/
|
|
19
|
+
|
|
20
|
+
# venv
|
|
21
|
+
.venv
|
|
22
|
+
|
|
23
|
+
.DS_Store
|
|
24
|
+
/.*cache/
|
|
25
|
+
/.claude/
|
|
26
|
+
/docs/memory/
|
|
27
|
+
/docs/superpowers/
|
|
28
|
+
/styles/
|
|
29
|
+
/Taskfile.d/
|
|
30
|
+
CLAUDE.md
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
---
|
|
2
|
+
workflow:
|
|
3
|
+
rules:
|
|
4
|
+
- if: $CI_PIPELINE_SOURCE == "schedule"
|
|
5
|
+
- if: $CI_PIPELINE_SOURCE == "web"
|
|
6
|
+
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
|
7
|
+
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
|
|
8
|
+
when: never
|
|
9
|
+
- if: $CI_COMMIT_TAG
|
|
10
|
+
- if: $CI_COMMIT_BRANCH
|
|
11
|
+
# Superseded pipelines abandon their still-running interruptible jobs when a
|
|
12
|
+
# newer commit lands on the same ref.
|
|
13
|
+
auto_cancel:
|
|
14
|
+
on_new_commit: interruptible
|
|
15
|
+
|
|
16
|
+
# Interruptible by default so redundant pipelines free their runners. Jobs that
|
|
17
|
+
# mutate something external (tag, PyPI upload, Pages deploy) opt out below.
|
|
18
|
+
# Retries are limited to causes that are never the code itself: infra hiccups.
|
|
19
|
+
default:
|
|
20
|
+
interruptible: true
|
|
21
|
+
retry:
|
|
22
|
+
max: 2
|
|
23
|
+
when:
|
|
24
|
+
- runner_system_failure
|
|
25
|
+
- stuck_or_timeout_failure
|
|
26
|
+
- scheduler_failure
|
|
27
|
+
|
|
28
|
+
variables:
|
|
29
|
+
# Single source of truth for the Python minor version (see the note on
|
|
30
|
+
# `include:` below for why the component inputs still hard-code it).
|
|
31
|
+
PYTHON_VERSION: "3.14"
|
|
32
|
+
# Pinned go-task release fetched by `.install-task` (floating "latest" would
|
|
33
|
+
# make release jobs non-reproducible). Bump deliberately.
|
|
34
|
+
TASK_VERSION: "v3.53.1"
|
|
35
|
+
IMAGE_UV: ghcr.io/astral-sh/uv:python${PYTHON_VERSION}-trixie-slim
|
|
36
|
+
IMAGE_NODE: node:24-trixie-slim
|
|
37
|
+
# Trivy generates bompage's own release SBOM in the `push-sbom` job. Pinned so
|
|
38
|
+
# re-running an old tag is reproducible; Renovate bumps it (custom manager in
|
|
39
|
+
# renovate.json).
|
|
40
|
+
TRIVY_VERSION: "0.74.0"
|
|
41
|
+
|
|
42
|
+
# `include:` is evaluated before the global `variables:` block, so the component
|
|
43
|
+
# `inputs:` below cannot reference ${PYTHON_VERSION}. The four
|
|
44
|
+
# `*_python_version: "3.14"` values are therefore kept as literals and must be
|
|
45
|
+
# bumped together with PYTHON_VERSION above (and deploy/.gitlab-ci.yml).
|
|
46
|
+
include:
|
|
47
|
+
- component: gitlab.com/op_so/components/core/lint@v2.0.2
|
|
48
|
+
inputs:
|
|
49
|
+
lint_vale: true
|
|
50
|
+
lint_markdown_glob: '"**/*.md" "#docs"'
|
|
51
|
+
- component: gitlab.com/op_so/components/python-uv/prepare-uv@v1.4.0
|
|
52
|
+
inputs:
|
|
53
|
+
prepare_uv_python_version: "3.14"
|
|
54
|
+
- component: gitlab.com/op_so/components/python-uv/lint-uv@v1.4.0
|
|
55
|
+
inputs:
|
|
56
|
+
lint_uv_python_version: "3.14"
|
|
57
|
+
lint_uv_isort: true
|
|
58
|
+
lint_uv_mypy: true
|
|
59
|
+
lint_uv_mypy_args: "--strict src/ tests/"
|
|
60
|
+
lint_uv_pyrefly: true
|
|
61
|
+
# Coverage is on by default and reads `[tool.coverage.run] source` from
|
|
62
|
+
# pyproject.toml, since the component passes `--cov` without an argument.
|
|
63
|
+
- component: gitlab.com/op_so/components/python-uv/test-uv@v1.4.0
|
|
64
|
+
inputs:
|
|
65
|
+
test_uv_python_version: "3.14"
|
|
66
|
+
- component: gitlab.com/op_so/components/core/semantic-release@v2.0.2
|
|
67
|
+
# Only runs on a scheduled pipeline setting RENOVATE=true, and needs a
|
|
68
|
+
# RENOVATE_TOKEN CI/CD variable.
|
|
69
|
+
- component: gitlab.com/op_so/components/core/renovate@v2.0.2
|
|
70
|
+
- component: gitlab.com/op_so/components/python-uv/publish-pypi-uv@v1.4.0
|
|
71
|
+
inputs:
|
|
72
|
+
publish_pypi_uv_python_version: "3.14"
|
|
73
|
+
publish_pypi_uv_stage: pypi-release
|
|
74
|
+
|
|
75
|
+
stages:
|
|
76
|
+
- prepare-uv
|
|
77
|
+
- lint
|
|
78
|
+
- build-web
|
|
79
|
+
- tests
|
|
80
|
+
- release
|
|
81
|
+
- pypi-release
|
|
82
|
+
- pages-release
|
|
83
|
+
- sbom-release
|
|
84
|
+
- renovate
|
|
85
|
+
|
|
86
|
+
# Shared pnpm setup for the dashboard sources (web-src/). corepack reads the
|
|
87
|
+
# pnpm version from package.json `packageManager`, so it stays pinned in one
|
|
88
|
+
# place instead of being repeated here.
|
|
89
|
+
.pnpm:
|
|
90
|
+
image: $IMAGE_NODE
|
|
91
|
+
needs: []
|
|
92
|
+
interruptible: true
|
|
93
|
+
variables:
|
|
94
|
+
PNPM_HOME: "$CI_PROJECT_DIR/.pnpm-store"
|
|
95
|
+
# `corepack prepare` would otherwise block on an interactive confirmation
|
|
96
|
+
# before downloading the pnpm release pinned in package.json.
|
|
97
|
+
COREPACK_ENABLE_DOWNLOAD_PROMPT: "0"
|
|
98
|
+
cache:
|
|
99
|
+
key:
|
|
100
|
+
files:
|
|
101
|
+
- pnpm-lock.yaml
|
|
102
|
+
prefix: pnpm-${CI_DEFAULT_BRANCH}
|
|
103
|
+
paths:
|
|
104
|
+
- .pnpm-store
|
|
105
|
+
before_script:
|
|
106
|
+
- corepack enable
|
|
107
|
+
- corepack prepare --activate
|
|
108
|
+
- pnpm config set store-dir "$PNPM_HOME"
|
|
109
|
+
- pnpm install --frozen-lockfile
|
|
110
|
+
|
|
111
|
+
# Dashboard sources (web-src/) validation: one job per step, like the Python
|
|
112
|
+
# side, so a failure points at the right thing. All reuse .pnpm, start
|
|
113
|
+
# immediately (needs: []) and only read the pnpm cache (build-web populates it).
|
|
114
|
+
# Biome covers TS *and* CSS.
|
|
115
|
+
format-web: # biome format check (TS + CSS)
|
|
116
|
+
extends: .pnpm
|
|
117
|
+
stage: lint
|
|
118
|
+
cache:
|
|
119
|
+
policy: pull
|
|
120
|
+
script:
|
|
121
|
+
- pnpm run format:web
|
|
122
|
+
|
|
123
|
+
lint-web: # biome check, no formatter: lint rules + import sort (TS + CSS)
|
|
124
|
+
extends: .pnpm
|
|
125
|
+
stage: lint
|
|
126
|
+
cache:
|
|
127
|
+
policy: pull
|
|
128
|
+
script:
|
|
129
|
+
- pnpm run lint:web
|
|
130
|
+
|
|
131
|
+
typecheck-web: # tsc --noEmit
|
|
132
|
+
extends: .pnpm
|
|
133
|
+
stage: lint
|
|
134
|
+
cache:
|
|
135
|
+
policy: pull
|
|
136
|
+
script:
|
|
137
|
+
- pnpm run typecheck:web
|
|
138
|
+
|
|
139
|
+
test-web: # vitest run: web-src/*.test.ts (happy-dom)
|
|
140
|
+
extends: .pnpm
|
|
141
|
+
stage: tests
|
|
142
|
+
cache:
|
|
143
|
+
policy: pull
|
|
144
|
+
script:
|
|
145
|
+
- pnpm run test:web
|
|
146
|
+
|
|
147
|
+
# Builds the constant Material Web (M3) dashboard into src/bompage/web/ (Vite +
|
|
148
|
+
# icon subset). That directory is git-ignored, so any job that packages the
|
|
149
|
+
# wheel or runs the dashboard tests must consume this artifact.
|
|
150
|
+
build-web:
|
|
151
|
+
extends: .pnpm
|
|
152
|
+
stage: build-web
|
|
153
|
+
script:
|
|
154
|
+
- pnpm run build:web
|
|
155
|
+
artifacts:
|
|
156
|
+
paths:
|
|
157
|
+
- src/bompage/web/
|
|
158
|
+
expire_in: 1 week
|
|
159
|
+
|
|
160
|
+
# Optional browser smoke of the built dashboard. Manual until a runner with the
|
|
161
|
+
# Playwright dependencies is confirmed. Keep the image tag aligned with the
|
|
162
|
+
# `playwright` version pinned in uv.lock (currently 1.62.0).
|
|
163
|
+
test-e2e:
|
|
164
|
+
stage: tests
|
|
165
|
+
image: mcr.microsoft.com/playwright/python:v1.62.0
|
|
166
|
+
needs: ["build-web"]
|
|
167
|
+
dependencies: ["build-web"]
|
|
168
|
+
when: manual
|
|
169
|
+
allow_failure: true
|
|
170
|
+
interruptible: true
|
|
171
|
+
script:
|
|
172
|
+
- curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
173
|
+
- export PATH="$HOME/.local/bin:$PATH"
|
|
174
|
+
- uv run --group dev playwright install chromium
|
|
175
|
+
- uv run --group dev pytest -m e2e
|
|
176
|
+
|
|
177
|
+
.install-task: &install-task
|
|
178
|
+
- apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends curl ca-certificates
|
|
179
|
+
- sh -c "$(curl --fail --silent --show-error --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin "${TASK_VERSION}"
|
|
180
|
+
|
|
181
|
+
# The cache block must stay identical to the one used by the python-uv
|
|
182
|
+
# components: they share a single key and any divergence silently splits it.
|
|
183
|
+
.abstract-uv:
|
|
184
|
+
image: $IMAGE_UV
|
|
185
|
+
needs: ["prepare-uv:sync"]
|
|
186
|
+
variables:
|
|
187
|
+
UV_CACHE_DIR: .uv-cache
|
|
188
|
+
cache:
|
|
189
|
+
key:
|
|
190
|
+
files:
|
|
191
|
+
- uv.lock
|
|
192
|
+
prefix: prepare-uv-${CI_DEFAULT_BRANCH}
|
|
193
|
+
paths:
|
|
194
|
+
- .uv-cache
|
|
195
|
+
- .venv
|
|
196
|
+
policy: pull
|
|
197
|
+
interruptible: true
|
|
198
|
+
|
|
199
|
+
# The python-uv/test-uv@v1.3.0 component defines its job as `test-uv:pytest`
|
|
200
|
+
# with `needs: ["prepare-uv:sync"]`. On its own it only sees the checkout, where
|
|
201
|
+
# src/bompage/web/ is git-ignored, so every test guarded by the `built_web`
|
|
202
|
+
# fixture (tests/conftest.py -> tests/test_build.py, tests/test_bompage.py,
|
|
203
|
+
# tests/render/test_web.py) does `pytest.skip`. Re-declaring `needs` with
|
|
204
|
+
# `build-web` (keeping prepare-uv:sync) pulls the artifact so CI exercises the
|
|
205
|
+
# same set as a local `task 00:220-run-tests`. `artifacts: true` downloads it,
|
|
206
|
+
# so no separate `dependencies:` is needed.
|
|
207
|
+
test-uv:pytest:
|
|
208
|
+
needs:
|
|
209
|
+
- job: "prepare-uv:sync"
|
|
210
|
+
artifacts: true
|
|
211
|
+
- job: build-web
|
|
212
|
+
artifacts: true
|
|
213
|
+
|
|
214
|
+
semantic-release:
|
|
215
|
+
# Creates the release tag: not interruptible.
|
|
216
|
+
interruptible: false
|
|
217
|
+
before_script:
|
|
218
|
+
- npx semantic-release --dry-run --no-ci
|
|
219
|
+
- if [ -s .VERSION ]; then task 00:800-project-set-version VERSION=$(cat .VERSION); fi
|
|
220
|
+
|
|
221
|
+
# The component runs `uv sync --frozen && uv build && uv publish` without
|
|
222
|
+
# substituting the version: without this before_script it would publish 0.0.0.
|
|
223
|
+
# It also needs the `build-web` artifact so the wheel embeds src/bompage/web/
|
|
224
|
+
# (see `[tool.hatch.build.targets.wheel] artifacts` in pyproject.toml). The
|
|
225
|
+
# component ships `needs: ["prepare-uv:sync"]`; we re-declare it with build-web
|
|
226
|
+
# added (a bare `dependencies: [build-web]` would be rejected as not part of
|
|
227
|
+
# `needs`).
|
|
228
|
+
publish-pypi-uv:
|
|
229
|
+
# Uploads to PyPI: not interruptible.
|
|
230
|
+
interruptible: false
|
|
231
|
+
needs:
|
|
232
|
+
- job: "prepare-uv:sync"
|
|
233
|
+
artifacts: true
|
|
234
|
+
- job: build-web
|
|
235
|
+
artifacts: true
|
|
236
|
+
before_script:
|
|
237
|
+
- *install-task
|
|
238
|
+
- test -f src/bompage/web/index.html # fail loudly if the artifact is missing
|
|
239
|
+
- task 00:800-project-set-version VERSION="${CI_COMMIT_TAG#v}"
|
|
240
|
+
|
|
241
|
+
# Publishes the source-code documentation site (mkdocs). The BOMpage dashboard
|
|
242
|
+
# itself is built by the central deployment repo (see deploy/), not here.
|
|
243
|
+
pages:
|
|
244
|
+
extends: .abstract-uv
|
|
245
|
+
stage: pages-release
|
|
246
|
+
# Deploys GitLab Pages: not interruptible. `needs` is made explicit here (it is
|
|
247
|
+
# also inherited from .abstract-uv): the docs build only needs the uv venv, not
|
|
248
|
+
# the build-web artifact.
|
|
249
|
+
interruptible: false
|
|
250
|
+
needs:
|
|
251
|
+
- job: "prepare-uv:sync"
|
|
252
|
+
artifacts: true
|
|
253
|
+
before_script:
|
|
254
|
+
- *install-task
|
|
255
|
+
- uv sync --frozen
|
|
256
|
+
- task 00:800-project-set-version VERSION="${CI_COMMIT_TAG#v}"
|
|
257
|
+
script:
|
|
258
|
+
- uv run mkdocs build --site-dir public
|
|
259
|
+
artifacts:
|
|
260
|
+
paths:
|
|
261
|
+
- public
|
|
262
|
+
rules:
|
|
263
|
+
- if: $DISABLE_JOBS == "true"
|
|
264
|
+
when: never
|
|
265
|
+
- if: $CI_COMMIT_TAG
|
|
266
|
+
|
|
267
|
+
# Dogfooding: on a release tag, generate bompage's own SBOM with Trivy and
|
|
268
|
+
# publish it into the central SBOM repository via `bompage push` (spec sections 5
|
|
269
|
+
# and 9). The released version is carried two ways: `uv lock` restamps it into
|
|
270
|
+
# uv.lock so Trivy records it as the SBOM's root component version, and
|
|
271
|
+
# `--sbom-version` puts it in the snapshot name
|
|
272
|
+
# (reports/bompage/sbom-YYYYMMDD-<version>.json) and the commit message.
|
|
273
|
+
# `push_report`'s anti-noise filter skips the commit when the dependency set is
|
|
274
|
+
# byte-identical to the previous snapshot.
|
|
275
|
+
#
|
|
276
|
+
# Requires a masked CI/CD variable BOMPAGE_TOKEN: a project/group access token
|
|
277
|
+
# scoped to write_repository on gitlab.com/op_so/pages/sbom-bompage only (spec
|
|
278
|
+
# section 5.3). `bompage push` reads it from that variable.
|
|
279
|
+
push-sbom:
|
|
280
|
+
extends: .abstract-uv
|
|
281
|
+
stage: sbom-release
|
|
282
|
+
# Pushes to an external repository: not interruptible.
|
|
283
|
+
interruptible: false
|
|
284
|
+
needs:
|
|
285
|
+
- job: "prepare-uv:sync"
|
|
286
|
+
artifacts: true
|
|
287
|
+
# Only publish the SBOM once the release itself has shipped to PyPI.
|
|
288
|
+
# `optional` keeps non-tag pipelines (where neither job runs) valid.
|
|
289
|
+
- job: publish-pypi-uv
|
|
290
|
+
artifacts: false
|
|
291
|
+
optional: true
|
|
292
|
+
variables:
|
|
293
|
+
# Central repository that hosts bompage's SBOM history.
|
|
294
|
+
BOMPAGE_REPO: "https://gitlab.com/op_so/pages/sbom-bompage.git"
|
|
295
|
+
before_script:
|
|
296
|
+
- *install-task # curl + ca-certificates + task
|
|
297
|
+
- DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends git
|
|
298
|
+
# Pinned Trivy release tarball (no `curl | sh`): reproducible, fails loudly.
|
|
299
|
+
# Asset suffix is Linux-64bit (amd64) or Linux-ARM64 depending on the runner.
|
|
300
|
+
- |
|
|
301
|
+
set -e
|
|
302
|
+
case "$(uname -m)" in
|
|
303
|
+
x86_64) TARCH=64bit ;;
|
|
304
|
+
aarch64 | arm64) TARCH=ARM64 ;;
|
|
305
|
+
*) echo "unsupported runner arch: $(uname -m)" >&2; exit 1 ;;
|
|
306
|
+
esac
|
|
307
|
+
curl --fail --silent --show-error --location --output /tmp/trivy.tgz \
|
|
308
|
+
"https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_Linux-${TARCH}.tar.gz"
|
|
309
|
+
tar -xzf /tmp/trivy.tgz -C /usr/local/bin trivy
|
|
310
|
+
- 'test -n "$BOMPAGE_TOKEN" || { echo "ERROR: CI/CD variable BOMPAGE_TOKEN is unset or empty" >&2; exit 1; }'
|
|
311
|
+
# `.venv` (bompage installed editable) matches the committed 0.0.0 lock here;
|
|
312
|
+
# stamp the real version afterwards and relock so uv.lock carries it before
|
|
313
|
+
# Trivy reads it as the SBOM's root component version.
|
|
314
|
+
- uv sync --frozen
|
|
315
|
+
- task 00:800-project-set-version VERSION="${CI_COMMIT_TAG#v}"
|
|
316
|
+
- uv lock
|
|
317
|
+
script:
|
|
318
|
+
# CycloneDX SBOM of the project. `--scanners license` limits Trivy to package
|
|
319
|
+
# + license data: no vulnerability DB download, and no volatile
|
|
320
|
+
# `vulnerabilities` section that would defeat push_report's anti-noise
|
|
321
|
+
# byte-compare. `--skip-files` drops the dashboard's build-time JS deps (only
|
|
322
|
+
# the built assets ship in the wheel).
|
|
323
|
+
- trivy fs --quiet --format cyclonedx --scanners license --offline-scan --skip-files "**/pnpm-lock.yaml" --output sbom.cdx.json .
|
|
324
|
+
- >
|
|
325
|
+
uv run --no-sync bompage push
|
|
326
|
+
--component bompage
|
|
327
|
+
--sbom sbom.cdx.json
|
|
328
|
+
--repo "$BOMPAGE_REPO"
|
|
329
|
+
--branch main
|
|
330
|
+
--sbom-version "${CI_COMMIT_TAG#v}"
|
|
331
|
+
--sbom-format cyclonedx
|
|
332
|
+
rules:
|
|
333
|
+
- if: $DISABLE_JOBS == "true"
|
|
334
|
+
when: never
|
|
335
|
+
- if: $CI_COMMIT_TAG
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
24
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
repos:
|
|
3
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
4
|
+
rev: v6.0.0
|
|
5
|
+
hooks:
|
|
6
|
+
- id: trailing-whitespace
|
|
7
|
+
args: [--markdown-linebreak-ext=md]
|
|
8
|
+
- id: end-of-file-fixer
|
|
9
|
+
- id: check-yaml
|
|
10
|
+
args: [--unsafe]
|
|
11
|
+
- id: check-added-large-files
|
|
12
|
+
# Hooks added from sample-config
|
|
13
|
+
- id: check-executables-have-shebangs
|
|
14
|
+
- id: check-json
|
|
15
|
+
- id: check-merge-conflict
|
|
16
|
+
- id: check-shebang-scripts-are-executable
|
|
17
|
+
- id: check-symlinks
|
|
18
|
+
- id: check-toml
|
|
19
|
+
- id: check-xml
|
|
20
|
+
- id: detect-private-key
|
|
21
|
+
- id: fix-byte-order-marker
|
|
22
|
+
- id: mixed-line-ending
|
|
23
|
+
|
|
24
|
+
- repo: https://github.com/gitleaks/gitleaks
|
|
25
|
+
rev: v8.30.1
|
|
26
|
+
hooks:
|
|
27
|
+
- id: gitleaks
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.14
|
bompage-1.0.0/.releaserc
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"branches": [
|
|
3
|
+
"main",
|
|
4
|
+
"master"
|
|
5
|
+
],
|
|
6
|
+
"plugins": [
|
|
7
|
+
"@semantic-release/commit-analyzer",
|
|
8
|
+
"@semantic-release/release-notes-generator",
|
|
9
|
+
[
|
|
10
|
+
"@semantic-release/exec",
|
|
11
|
+
{
|
|
12
|
+
"verifyReleaseCmd": "echo ${nextRelease.version} > .VERSION"
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"@semantic-release/gitlab"
|
|
16
|
+
]
|
|
17
|
+
}
|
bompage-1.0.0/.yamllint
ADDED
bompage-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright © 2026 FX Soubirou soubirou@yahoo.fr
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|