efs-sbom 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.
- efs_sbom-1.0.0/.cdxgenrc.example +11 -0
- efs_sbom-1.0.0/.github/ISSUE_TEMPLATE/bug_report.yml +49 -0
- efs_sbom-1.0.0/.github/ISSUE_TEMPLATE/config.yml +8 -0
- efs_sbom-1.0.0/.github/ISSUE_TEMPLATE/feature_request.yml +36 -0
- efs_sbom-1.0.0/.github/PULL_REQUEST_TEMPLATE.md +15 -0
- efs_sbom-1.0.0/.github/dependabot.yml +18 -0
- efs_sbom-1.0.0/.github/workflows/ci.yml +94 -0
- efs_sbom-1.0.0/.github/workflows/release.yml +59 -0
- efs_sbom-1.0.0/.github/workflows/sbom.yml +41 -0
- efs_sbom-1.0.0/.gitignore +39 -0
- efs_sbom-1.0.0/.python-version +1 -0
- efs_sbom-1.0.0/CHANGELOG.md +132 -0
- efs_sbom-1.0.0/CODE_OF_CONDUCT.md +36 -0
- efs_sbom-1.0.0/CONTRIBUTING.md +75 -0
- efs_sbom-1.0.0/LICENSE +201 -0
- efs_sbom-1.0.0/NOTICE +18 -0
- efs_sbom-1.0.0/PKG-INFO +120 -0
- efs_sbom-1.0.0/README.md +79 -0
- efs_sbom-1.0.0/SECURITY.md +30 -0
- efs_sbom-1.0.0/docs/commands.md +271 -0
- efs_sbom-1.0.0/docs/config.md +208 -0
- efs_sbom-1.0.0/docs/fstec.md +243 -0
- efs_sbom-1.0.0/docs/index.md +39 -0
- efs_sbom-1.0.0/efs/__init__.py +18 -0
- efs_sbom-1.0.0/efs/additional_schemas/jsf-0.82.schema.json +240 -0
- efs_sbom-1.0.0/efs/additional_schemas/spdx.schema.json +737 -0
- efs_sbom-1.0.0/efs/checker.py +355 -0
- efs_sbom-1.0.0/efs/cli.py +562 -0
- efs_sbom-1.0.0/efs/config.py +565 -0
- efs_sbom-1.0.0/efs/init_wizard.py +330 -0
- efs_sbom-1.0.0/efs/odt_templates/template.odt +0 -0
- efs_sbom-1.0.0/efs/odt_templates/template_container.odt +0 -0
- efs_sbom-1.0.0/efs/postprocess.py +781 -0
- efs_sbom-1.0.0/efs/scanner.py +144 -0
- efs_sbom-1.0.0/efs/schemas/schema.json +5961 -0
- efs_sbom-1.0.0/efs/schemas/schema_container.json +5889 -0
- efs_sbom-1.0.0/efs/to_csv.py +79 -0
- efs_sbom-1.0.0/efs/to_odt.py +169 -0
- efs_sbom-1.0.0/efs/unifier.py +241 -0
- efs_sbom-1.0.0/efs/updater.py +680 -0
- efs_sbom-1.0.0/efs/utils.py +409 -0
- efs_sbom-1.0.0/examples/example-sbom.json +58 -0
- efs_sbom-1.0.0/pyproject.toml +96 -0
- efs_sbom-1.0.0/tests/__init__.py +0 -0
- efs_sbom-1.0.0/tests/conftest.py +152 -0
- efs_sbom-1.0.0/tests/test_checker.py +354 -0
- efs_sbom-1.0.0/tests/test_cli.py +480 -0
- efs_sbom-1.0.0/tests/test_config.py +393 -0
- efs_sbom-1.0.0/tests/test_init_wizard.py +257 -0
- efs_sbom-1.0.0/tests/test_postprocess.py +349 -0
- efs_sbom-1.0.0/tests/test_scanner.py +110 -0
- efs_sbom-1.0.0/tests/test_unifier.py +463 -0
- efs_sbom-1.0.0/tests/test_updater.py +289 -0
- efs_sbom-1.0.0/tests/test_utils.py +244 -0
- efs_sbom-1.0.0/uv.lock +705 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
name: Ошибка
|
|
2
|
+
description: Сообщить о некорректной работе efs
|
|
3
|
+
labels: ["bug"]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
id: what-happened
|
|
7
|
+
attributes:
|
|
8
|
+
label: Что произошло
|
|
9
|
+
description: Опишите проблему и чего вы ожидали вместо этого.
|
|
10
|
+
validations:
|
|
11
|
+
required: true
|
|
12
|
+
|
|
13
|
+
- type: textarea
|
|
14
|
+
id: reproduce
|
|
15
|
+
attributes:
|
|
16
|
+
label: Как воспроизвести
|
|
17
|
+
description: Команда efs целиком и, если возможно, минимальный SBOM-файл или конфиг.
|
|
18
|
+
render: shell
|
|
19
|
+
validations:
|
|
20
|
+
required: true
|
|
21
|
+
|
|
22
|
+
- type: textarea
|
|
23
|
+
id: output
|
|
24
|
+
attributes:
|
|
25
|
+
label: Вывод команды
|
|
26
|
+
description: Полный вывод, включая traceback. Запустите с флагом -v для подробностей.
|
|
27
|
+
render: shell
|
|
28
|
+
|
|
29
|
+
- type: input
|
|
30
|
+
id: version
|
|
31
|
+
attributes:
|
|
32
|
+
label: Версия efs
|
|
33
|
+
description: "Вывод команды: pip show efs-sbom"
|
|
34
|
+
validations:
|
|
35
|
+
required: true
|
|
36
|
+
|
|
37
|
+
- type: input
|
|
38
|
+
id: python
|
|
39
|
+
attributes:
|
|
40
|
+
label: Версия Python и ОС
|
|
41
|
+
placeholder: "3.12.7, Ubuntu 24.04"
|
|
42
|
+
validations:
|
|
43
|
+
required: true
|
|
44
|
+
|
|
45
|
+
- type: input
|
|
46
|
+
id: scanner
|
|
47
|
+
attributes:
|
|
48
|
+
label: Инструмент генерации SBOM
|
|
49
|
+
description: Если проблема связана со сканированием — cdxgen или trivy и его версия.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
blank_issues_enabled: false
|
|
2
|
+
contact_links:
|
|
3
|
+
- name: Вопрос по использованию
|
|
4
|
+
url: https://github.com/happykust/efs/discussions
|
|
5
|
+
about: Задайте вопрос в обсуждениях, если это не ошибка и не предложение
|
|
6
|
+
- name: Уязвимость безопасности
|
|
7
|
+
url: https://github.com/happykust/efs/security/advisories/new
|
|
8
|
+
about: Сообщайте об уязвимостях приватно, а не через issue
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: Предложение
|
|
2
|
+
description: Предложить новую возможность или улучшение
|
|
3
|
+
labels: ["enhancement"]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
id: problem
|
|
7
|
+
attributes:
|
|
8
|
+
label: Какую задачу это решает
|
|
9
|
+
description: Опишите ситуацию, в которой текущих возможностей не хватает.
|
|
10
|
+
validations:
|
|
11
|
+
required: true
|
|
12
|
+
|
|
13
|
+
- type: textarea
|
|
14
|
+
id: proposal
|
|
15
|
+
attributes:
|
|
16
|
+
label: Предлагаемое решение
|
|
17
|
+
description: Как это могло бы работать — команда, флаг, поле конфига.
|
|
18
|
+
validations:
|
|
19
|
+
required: true
|
|
20
|
+
|
|
21
|
+
- type: textarea
|
|
22
|
+
id: alternatives
|
|
23
|
+
attributes:
|
|
24
|
+
label: Альтернативы
|
|
25
|
+
description: Что вы пробовали или рассматривали вместо этого.
|
|
26
|
+
|
|
27
|
+
- type: checkboxes
|
|
28
|
+
id: scope
|
|
29
|
+
attributes:
|
|
30
|
+
label: Область
|
|
31
|
+
options:
|
|
32
|
+
- label: Требования ФСТЭК / ГОСТ Р 56939-2024
|
|
33
|
+
- label: Генерация SBOM (cdxgen, trivy)
|
|
34
|
+
- label: Валидация и схемы
|
|
35
|
+
- label: Экспорт (CSV, ODT)
|
|
36
|
+
- label: Конфигурация
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
## Что меняется
|
|
2
|
+
|
|
3
|
+
<!-- Коротко: что и зачем. Если есть связанный issue — укажите «Closes #N». -->
|
|
4
|
+
|
|
5
|
+
## Как проверено
|
|
6
|
+
|
|
7
|
+
<!-- Какие тесты добавлены или какие сценарии проверены вручную. -->
|
|
8
|
+
|
|
9
|
+
## Чеклист
|
|
10
|
+
|
|
11
|
+
- [ ] `uv run pytest` проходит
|
|
12
|
+
- [ ] `uv run ruff check .` и `uv run ruff format --check .` проходят
|
|
13
|
+
- [ ] Добавлены тесты на новое поведение или на исправленный баг
|
|
14
|
+
- [ ] Изменение, заметное пользователю, добавлено в `CHANGELOG.md`
|
|
15
|
+
- [ ] Документация обновлена (README, если менялся интерфейс команд)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: github-actions
|
|
4
|
+
directory: "/"
|
|
5
|
+
schedule:
|
|
6
|
+
interval: monthly
|
|
7
|
+
commit-message:
|
|
8
|
+
prefix: "ci"
|
|
9
|
+
|
|
10
|
+
- package-ecosystem: uv
|
|
11
|
+
directory: "/"
|
|
12
|
+
schedule:
|
|
13
|
+
interval: monthly
|
|
14
|
+
commit-message:
|
|
15
|
+
prefix: "build"
|
|
16
|
+
groups:
|
|
17
|
+
dev-dependencies:
|
|
18
|
+
patterns: ["pytest*", "ruff", "responses"]
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
concurrency:
|
|
10
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
11
|
+
cancel-in-progress: true
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
lint:
|
|
15
|
+
name: Линтер и форматирование
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v7
|
|
19
|
+
- uses: astral-sh/setup-uv@v7
|
|
20
|
+
with:
|
|
21
|
+
enable-cache: true
|
|
22
|
+
- run: uv sync --locked
|
|
23
|
+
- run: uv run ruff check --output-format=github .
|
|
24
|
+
- run: uv run ruff format --check .
|
|
25
|
+
|
|
26
|
+
test:
|
|
27
|
+
name: Тесты (Python ${{ matrix.python-version }})
|
|
28
|
+
runs-on: ubuntu-latest
|
|
29
|
+
strategy:
|
|
30
|
+
fail-fast: false
|
|
31
|
+
matrix:
|
|
32
|
+
python-version: ["3.12", "3.13", "3.14"]
|
|
33
|
+
steps:
|
|
34
|
+
- uses: actions/checkout@v7
|
|
35
|
+
- uses: astral-sh/setup-uv@v7
|
|
36
|
+
with:
|
|
37
|
+
enable-cache: true
|
|
38
|
+
python-version: ${{ matrix.python-version }}
|
|
39
|
+
- run: uv sync --locked
|
|
40
|
+
- run: uv run pytest -q --cov=efs --cov-report=term-missing
|
|
41
|
+
|
|
42
|
+
build:
|
|
43
|
+
name: Сборка пакета
|
|
44
|
+
runs-on: ubuntu-latest
|
|
45
|
+
steps:
|
|
46
|
+
- uses: actions/checkout@v7
|
|
47
|
+
- uses: astral-sh/setup-uv@v7
|
|
48
|
+
with:
|
|
49
|
+
enable-cache: true
|
|
50
|
+
- run: uv build
|
|
51
|
+
- name: Проверка метаданных дистрибутивов
|
|
52
|
+
run: uvx twine check dist/*
|
|
53
|
+
- name: Проверка данных пакета в wheel
|
|
54
|
+
run: |
|
|
55
|
+
python3 - <<'PY'
|
|
56
|
+
import glob, sys, zipfile
|
|
57
|
+
|
|
58
|
+
required = (
|
|
59
|
+
"efs/schemas/schema.json",
|
|
60
|
+
"efs/schemas/schema_container.json",
|
|
61
|
+
"efs/additional_schemas/spdx.schema.json",
|
|
62
|
+
"efs/additional_schemas/jsf-0.82.schema.json",
|
|
63
|
+
"efs/odt_templates/template.odt",
|
|
64
|
+
"efs/odt_templates/template_container.odt",
|
|
65
|
+
)
|
|
66
|
+
names = set(zipfile.ZipFile(glob.glob("dist/*.whl")[0]).namelist())
|
|
67
|
+
missing = [item for item in required if item not in names]
|
|
68
|
+
if missing:
|
|
69
|
+
sys.exit("в wheel отсутствуют файлы: " + ", ".join(missing))
|
|
70
|
+
print("данные пакета на месте")
|
|
71
|
+
PY
|
|
72
|
+
- uses: actions/upload-artifact@v7
|
|
73
|
+
with:
|
|
74
|
+
name: dist
|
|
75
|
+
path: dist/
|
|
76
|
+
|
|
77
|
+
smoke:
|
|
78
|
+
name: Проверка установленного пакета
|
|
79
|
+
needs: build
|
|
80
|
+
runs-on: ubuntu-latest
|
|
81
|
+
steps:
|
|
82
|
+
- uses: actions/checkout@v7
|
|
83
|
+
- uses: actions/download-artifact@v8
|
|
84
|
+
with:
|
|
85
|
+
name: dist
|
|
86
|
+
path: dist
|
|
87
|
+
- uses: astral-sh/setup-uv@v7
|
|
88
|
+
- name: Установка из wheel и запуск команд
|
|
89
|
+
run: |
|
|
90
|
+
uv venv
|
|
91
|
+
uv pip install dist/*.whl
|
|
92
|
+
uv run efs --help
|
|
93
|
+
uv run efs check examples/example-sbom.json
|
|
94
|
+
uv run efs export csv examples/example-sbom.json /tmp/components.csv
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ["v*"]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
build:
|
|
12
|
+
name: Сборка дистрибутивов
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v7
|
|
16
|
+
- uses: astral-sh/setup-uv@v7
|
|
17
|
+
with:
|
|
18
|
+
enable-cache: true
|
|
19
|
+
- run: uv sync --locked
|
|
20
|
+
- run: uv run ruff check .
|
|
21
|
+
- run: uv run pytest -q
|
|
22
|
+
- run: uv build
|
|
23
|
+
- run: uvx twine check dist/*
|
|
24
|
+
- uses: actions/upload-artifact@v7
|
|
25
|
+
with:
|
|
26
|
+
name: dist
|
|
27
|
+
path: dist/
|
|
28
|
+
|
|
29
|
+
publish:
|
|
30
|
+
name: Публикация в PyPI
|
|
31
|
+
needs: build
|
|
32
|
+
runs-on: ubuntu-latest
|
|
33
|
+
environment:
|
|
34
|
+
name: pypi
|
|
35
|
+
url: https://pypi.org/p/efs-sbom
|
|
36
|
+
permissions:
|
|
37
|
+
id-token: write
|
|
38
|
+
steps:
|
|
39
|
+
- uses: actions/download-artifact@v8
|
|
40
|
+
with:
|
|
41
|
+
name: dist
|
|
42
|
+
path: dist
|
|
43
|
+
- uses: pypa/gh-action-pypi-publish@v1.14.2
|
|
44
|
+
|
|
45
|
+
github-release:
|
|
46
|
+
name: Релиз на GitHub
|
|
47
|
+
needs: publish
|
|
48
|
+
runs-on: ubuntu-latest
|
|
49
|
+
permissions:
|
|
50
|
+
contents: write
|
|
51
|
+
steps:
|
|
52
|
+
- uses: actions/download-artifact@v8
|
|
53
|
+
with:
|
|
54
|
+
name: dist
|
|
55
|
+
path: dist
|
|
56
|
+
- uses: softprops/action-gh-release@v3
|
|
57
|
+
with:
|
|
58
|
+
files: dist/*
|
|
59
|
+
generate_release_notes: true
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
name: SBOM
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ["v*"]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
self-sbom:
|
|
13
|
+
name: SBOM самого efs
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v7
|
|
17
|
+
- uses: astral-sh/setup-uv@v7
|
|
18
|
+
with:
|
|
19
|
+
enable-cache: true
|
|
20
|
+
- uses: actions/setup-node@v7
|
|
21
|
+
with:
|
|
22
|
+
node-version: "22"
|
|
23
|
+
- run: npm install -g @cyclonedx/cdxgen
|
|
24
|
+
- run: uv sync --locked
|
|
25
|
+
- name: Генерация и постобработка SBOM
|
|
26
|
+
run: |
|
|
27
|
+
uv run efs scan --tool cdxgen --target . --output bom.raw.json
|
|
28
|
+
uv run efs postprocess bom.raw.json efs.sbom.json \
|
|
29
|
+
--app-name efs \
|
|
30
|
+
--app-version "${GITHUB_REF_NAME#v}" \
|
|
31
|
+
--manufacturer "Kirill Nikolaevskiy"
|
|
32
|
+
- name: Валидация результата
|
|
33
|
+
run: |
|
|
34
|
+
uv run efs check efs.sbom.json || status=$?
|
|
35
|
+
if [ "${status:-0}" = "1" ]; then
|
|
36
|
+
exit 1
|
|
37
|
+
fi
|
|
38
|
+
- uses: actions/upload-artifact@v7
|
|
39
|
+
with:
|
|
40
|
+
name: efs-sbom
|
|
41
|
+
path: efs.sbom.json
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
.eggs/
|
|
6
|
+
|
|
7
|
+
# Сборка и дистрибутивы
|
|
8
|
+
build/
|
|
9
|
+
dist/
|
|
10
|
+
|
|
11
|
+
# Виртуальные окружения
|
|
12
|
+
venv/
|
|
13
|
+
.venv/
|
|
14
|
+
env/
|
|
15
|
+
|
|
16
|
+
# Тесты и покрытие
|
|
17
|
+
.pytest_cache/
|
|
18
|
+
.coverage
|
|
19
|
+
coverage.xml
|
|
20
|
+
htmlcov/
|
|
21
|
+
.ruff_cache/
|
|
22
|
+
.mypy_cache/
|
|
23
|
+
|
|
24
|
+
# IDE
|
|
25
|
+
.idea/
|
|
26
|
+
.vscode/
|
|
27
|
+
|
|
28
|
+
# Локальные артефакты SBOM и конфиги
|
|
29
|
+
*.sbom.json
|
|
30
|
+
bom.json
|
|
31
|
+
.sbom-config.json
|
|
32
|
+
.purl_to_vcs.json
|
|
33
|
+
.purl_to_gost.json
|
|
34
|
+
.purl_exclude.json
|
|
35
|
+
.cdxgenrc
|
|
36
|
+
|
|
37
|
+
# Локальные инструкции для агентов и рабочие заметки
|
|
38
|
+
CLAUDE.md
|
|
39
|
+
docs/superpowers/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
Все значимые изменения проекта фиксируются в этом файле.
|
|
4
|
+
|
|
5
|
+
Формат основан на [Keep a Changelog](https://keepachangelog.com/ru/1.1.0/),
|
|
6
|
+
проект следует [семантическому версионированию](https://semver.org/lang/ru/).
|
|
7
|
+
|
|
8
|
+
## [1.0.0] — 2026-08-29
|
|
9
|
+
|
|
10
|
+
Первый выпуск под именем `efs-sbom`. Раздел «Изменено» описывает, чем релиз
|
|
11
|
+
отличается от предшественника — пакета `sbom-utils`, который не публиковался.
|
|
12
|
+
|
|
13
|
+
### Изменено (breaking)
|
|
14
|
+
|
|
15
|
+
- `efs check` возвращает осмысленный код: `0` — перечень готов, `1` — ошибки схемы
|
|
16
|
+
или недоступные ссылки, `3` — схема в порядке, но перечень не заполнен. Прежде
|
|
17
|
+
команда всегда завершалась с кодом `0`, из-за чего не годилась для CI. Код `2`
|
|
18
|
+
оставлен за ошибками вызова, как принято в click.
|
|
19
|
+
- Проект переименован в **efs** (Easy FSTEC SBOMs).
|
|
20
|
+
- Дистрибутив на PyPI: `efs-sbom` (имя `efs` там занято чужим пакетом).
|
|
21
|
+
- Python-пакет: `sbom_utils` → `efs`.
|
|
22
|
+
- CLI-команда: `sbom` → `efs`.
|
|
23
|
+
- Модуль `sbom_utils.sbom_utils` → `efs.utils`.
|
|
24
|
+
- Модуль `sbom_utils.cdxgen_postprocess` → `efs.postprocess` (обрабатывает вывод
|
|
25
|
+
и cdxgen, и trivy, прежнее имя вводило в заблуждение).
|
|
26
|
+
- Каталог кеша: `~/.cache/sbom-checker` → `~/.cache/efs`. Прежний кеш не
|
|
27
|
+
переносится — при первом запуске проверки выполняются заново.
|
|
28
|
+
- Имя файла конфигурации `.sbom-config.json` не изменилось.
|
|
29
|
+
- Удалён неиспользуемый слой argparse из модулей (`configure_parser()`, `main()`,
|
|
30
|
+
`if __name__ == '__main__'`). Прямой вызов модулей вида
|
|
31
|
+
`python -m sbom_utils.updater` больше не поддерживается — используйте `efs update`.
|
|
32
|
+
- Удалён `requirements.txt`: зависимости описаны в `pyproject.toml`, версии
|
|
33
|
+
зафиксированы в `uv.lock`.
|
|
34
|
+
|
|
35
|
+
### Добавлено
|
|
36
|
+
|
|
37
|
+
- Набор тестов на pytest и конфигурация ruff.
|
|
38
|
+
- CI на GitHub Actions: линтер, тесты на Python 3.12/3.13/3.14, сборка пакета
|
|
39
|
+
с проверкой состава wheel и запуск команд из установленного дистрибутива.
|
|
40
|
+
- Публикация в PyPI по тегу через trusted publishing, релиз на GitHub с дистрибутивами.
|
|
41
|
+
- Workflow генерации SBOM самого efs (cdxgen → postprocess → check) на релизных тегах.
|
|
42
|
+
- `CONTRIBUTING.md`, `SECURITY.md`, `CODE_OF_CONDUCT.md`, шаблоны issue и pull request,
|
|
43
|
+
конфигурация Dependabot.
|
|
44
|
+
- Пример заполненного перечня — `examples/example-sbom.json`.
|
|
45
|
+
- Документация в `docs/`: руководство по подготовке перечня под ФСТЭК, справочник
|
|
46
|
+
команд и описание конфига. README сокращён до точки входа.
|
|
47
|
+
- Поле `source_langs` в конфиге: языки задаются списком или строкой и попадают в
|
|
48
|
+
SBOM отдельным свойством `GOST:source_langs` на каждый язык, как требует ФСТЭК.
|
|
49
|
+
Для большинства экосистем (pypi, npm, maven, cargo, golang, gem, nuget и других)
|
|
50
|
+
язык определяется по типу purl автоматически; `deb` и `rpm` заполняются вручную.
|
|
51
|
+
`efs config init` подставляет язык в конфиг, `efs config status` показывает
|
|
52
|
+
компоненты без языка.
|
|
53
|
+
- Экспорт в CSV и ODT выводит все языки компонента, а не только первый.
|
|
54
|
+
- В графу источника отчётной формы попадает название сертифицированного СЗИ из
|
|
55
|
+
`GOST:provided_by`, если ссылки на исходный код нет. Прежде графа оставалась
|
|
56
|
+
пустой, хотя `efs check` считал такой компонент заполненным.
|
|
57
|
+
- `efs postprocess` сохраняет `description` у образов контейнеров: это графа
|
|
58
|
+
«Назначение» отчётной формы, и постобработка её стирала.
|
|
59
|
+
- `efs check --format container` сообщает об образах без назначения.
|
|
60
|
+
- `efs --version` (`-V`) печатает версию.
|
|
61
|
+
- `efs check --check-vcs` показывает, сколько ссылок проверяется, и отмечает
|
|
62
|
+
прогресс на длинных перечнях.
|
|
63
|
+
- Мастер `efs init` завершается проверкой готовности перечня, а результат
|
|
64
|
+
постобработки пишет в отдельный файл, не перезаписывая исходный SBOM.
|
|
65
|
+
- `efs merge` переносит языки в сводный перечень: компонент-сервис наследует языки
|
|
66
|
+
своих компонентов, включая вложенные. Прежде сводный перечень гарантированно не
|
|
67
|
+
проходил проверку готовности.
|
|
68
|
+
- `efs update --props`, `--gost` и `--fix-all` проставляют язык, следующий из purl.
|
|
69
|
+
- Значения `--format`, `--tool` и `--gost-default` проверяются и подсказываются
|
|
70
|
+
автодополнением; неверное значение отвергается с перечнем допустимых.
|
|
71
|
+
- Входные файлы проверяются на существование: вместо трассировки стека выводится
|
|
72
|
+
сообщение об ошибке, а команда завершается ненулевым кодом. Прежде `efs check`
|
|
73
|
+
на отсутствующем файле печатал traceback и возвращал `0`.
|
|
74
|
+
- `efs postprocess` проставляет `GOST:source_langs` и без конфига: язык следует из
|
|
75
|
+
purl и не зависит от того, описан ли компонент в `.efs-config.json`. Прежде
|
|
76
|
+
проверка требовала язык, а заполнить его без конфига было нечем.
|
|
77
|
+
- Компоненты, которые `efs postprocess` дописывает в конфиг, сразу получают язык,
|
|
78
|
+
выведенный из экосистемы, — как и при `efs config init`.
|
|
79
|
+
- `efs check` проверяет готовность перечня к сдаче: заглушки `TODO` в метаданных,
|
|
80
|
+
отсутствие ГОСТ-свойств и `GOST:source_langs`, компоненты без ссылки на
|
|
81
|
+
репозиторий и без `GOST:provided_by`. В конце печатается сводка по видам
|
|
82
|
+
замечаний. Отдельного флага нет — проверка выполняется всегда.
|
|
83
|
+
- `efs merge` объединяет сырые отчёты trivy: компоненты дедуплицируются по purl,
|
|
84
|
+
уязвимости — по CVE, зависимости пересопоставляются, компоненты-манифесты и
|
|
85
|
+
висячие ссылки отбрасываются. Смешивание trivy-отчётов с обычными SBOM
|
|
86
|
+
завершается ошибкой.
|
|
87
|
+
- `NOTICE` с атрибуцией ИСП РАН как автора исходного проекта sbom-checker.
|
|
88
|
+
- Поддержка значения `exclude: "direct"` в конфиге — исключение самого компонента
|
|
89
|
+
без каскадного удаления его транзитивных зависимостей.
|
|
90
|
+
- Резолверы VCS-ссылок для PyPI, npm, Maven, RPM и Deb в `efs update`.
|
|
91
|
+
- Параллельная обработка purl при поиске VCS-ссылок.
|
|
92
|
+
- Команда `efs config migrate` — была описана в README, но отсутствовала в CLI.
|
|
93
|
+
|
|
94
|
+
### Производительность
|
|
95
|
+
|
|
96
|
+
- Проверка уникальности элементов вынесена из JSON Schema в отдельный линейный
|
|
97
|
+
проход. jsonschema сравнивает элементы массивов попарно, из-за чего `efs check`
|
|
98
|
+
на перечне с тысячами зависимостей работал квадратично: полная проверка
|
|
99
|
+
реального SBOM (6933 компонента, 6892 зависимости) занимала 39 секунд, а
|
|
100
|
+
на 100 000 компонентов не завершалась за разумное время. Стало 11 и 47 секунд
|
|
101
|
+
соответственно, для валидного перечня на 1370 компонентов — около секунды.
|
|
102
|
+
|
|
103
|
+
### Исправлено
|
|
104
|
+
|
|
105
|
+
- Сопоставление purl в `exclude` учитывает версию: запись `pkg:npm/ajv@6.12.6`
|
|
106
|
+
больше не удаляет из SBOM все версии `ajv`.
|
|
107
|
+
- Каскадное `exclude: true` действительно удаляет транзитивные зависимости, как и
|
|
108
|
+
описано в документации. Прежде корни графа вычислялись уже после отбрасывания
|
|
109
|
+
рёбер исключённого компонента, из-за чего его зависимости сами становились
|
|
110
|
+
корнями и сохранялись — каскад не работал ни в одном практическом случае.
|
|
111
|
+
Защита от удаления «осиротевших» рантайм-зависимостей сохранена: корнями
|
|
112
|
+
считаются узлы без входящих рёбер в исходном графе.
|
|
113
|
+
- HTTP-фоллбэк при таймауте `git ls-remote` — крупные репозитории (например,
|
|
114
|
+
chromium) больше не помечаются как недоступные.
|
|
115
|
+
- Неинтерактивный режим для `svn ls` и `hg identify` — проверка VCS не зависает
|
|
116
|
+
в ожидании ввода учётных данных.
|
|
117
|
+
- Тайм-ауты для всех HTTP-запросов в `efs update`.
|
|
118
|
+
- `efs check --check-source-distribution` завершался исключением на каждой ссылке:
|
|
119
|
+
`is_archive_url` вызывался без HTTP-сессии. Ошибки внутри параллельных проверок
|
|
120
|
+
больше не игнорируются — файл не объявляется корректным.
|
|
121
|
+
- `rich` добавлен в явные зависимости: модули использовали его, полагаясь на
|
|
122
|
+
транзитивную установку через typer.
|
|
123
|
+
|
|
124
|
+
## Предыстория
|
|
125
|
+
|
|
126
|
+
Проект вырос из `sbom-checker` (ИСП РАН) и до переименования назывался
|
|
127
|
+
`sbom-utils`: единая CLI-точка входа, единый конфиг, команды `check`, `update`,
|
|
128
|
+
`merge`, `postprocess`, `scan`, `export`, `config`, `init`. Под именем `sbom-utils`
|
|
129
|
+
пакет не публиковался, поэтому первым выпуском считается 1.0.0 под именем
|
|
130
|
+
`efs-sbom`.
|
|
131
|
+
|
|
132
|
+
[1.0.0]: https://github.com/happykust/efs/releases/tag/v1.0.0
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Кодекс поведения участников
|
|
2
|
+
|
|
3
|
+
## Наше обязательство
|
|
4
|
+
|
|
5
|
+
Мы, участники и сопровождающие проекта, обязуемся сделать участие в сообществе свободным от притеснений для всех — независимо от возраста, телосложения, видимых или невидимых особенностей, пола, уровня опыта, образования, социального статуса, национальности, внешности, расы, религии, сексуальной ориентации и идентичности.
|
|
6
|
+
|
|
7
|
+
## Наши стандарты
|
|
8
|
+
|
|
9
|
+
Примеры поведения, которое создаёт здоровую атмосферу:
|
|
10
|
+
|
|
11
|
+
- уважение к чужому мнению и опыту;
|
|
12
|
+
- конструктивная критика и готовность её принимать;
|
|
13
|
+
- признание своих ошибок и извинения перед теми, кого они затронули;
|
|
14
|
+
- забота об интересах сообщества, а не только о собственных.
|
|
15
|
+
|
|
16
|
+
Примеры неприемлемого поведения:
|
|
17
|
+
|
|
18
|
+
- сексуализированные высказывания и внимание любого рода;
|
|
19
|
+
- троллинг, оскорбления, уничижительные комментарии, личные и политические нападки;
|
|
20
|
+
- публичное или приватное притеснение;
|
|
21
|
+
- публикация чужих личных данных без явного разрешения;
|
|
22
|
+
- иное поведение, неуместное в профессиональной среде.
|
|
23
|
+
|
|
24
|
+
## Применение
|
|
25
|
+
|
|
26
|
+
Сопровождающие проекта отвечают за разъяснение этих стандартов и принимают справедливые меры в ответ на неприемлемое поведение: от удаления комментариев и коммитов до временного или постоянного запрета на участие.
|
|
27
|
+
|
|
28
|
+
О случаях неприемлемого поведения сообщайте сопровождающему проекта: me@happykust.dev. Все жалобы рассматриваются оперативно и справедливо, приватность заявителя соблюдается.
|
|
29
|
+
|
|
30
|
+
## Область действия
|
|
31
|
+
|
|
32
|
+
Кодекс действует во всех пространствах проекта, а также когда участник официально представляет проект в публичном пространстве.
|
|
33
|
+
|
|
34
|
+
## Источник
|
|
35
|
+
|
|
36
|
+
Документ адаптирован из [Contributor Covenant](https://www.contributor-covenant.org/version/2/1/code_of_conduct/), версия 2.1.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Участие в разработке
|
|
2
|
+
|
|
3
|
+
Спасибо за интерес к efs. Здесь описано, как собрать проект, что проверяется в CI и как оформлять изменения.
|
|
4
|
+
|
|
5
|
+
## Быстрый старт
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
git clone https://github.com/happykust/efs.git
|
|
9
|
+
cd efs
|
|
10
|
+
uv sync
|
|
11
|
+
uv run efs --help
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
`uv sync` ставит и рантайм-зависимости, и dev-группу (pytest, ruff). Отдельного шага установки для разработки не нужно.
|
|
15
|
+
|
|
16
|
+
## Проверки перед отправкой изменений
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
uv run pytest # тесты
|
|
20
|
+
uv run ruff check . # линтер
|
|
21
|
+
uv run ruff format . # форматирование
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Ровно эти три команды выполняет CI на Python 3.12, 3.13 и 3.14. Если они проходят локально, сборка на GitHub тоже пройдёт.
|
|
25
|
+
|
|
26
|
+
## Тесты
|
|
27
|
+
|
|
28
|
+
Тесты лежат в `tests/`, фикстуры и конструкторы минимальных SBOM — в `tests/conftest.py`.
|
|
29
|
+
|
|
30
|
+
Правило без исключений: **тесты не ходят в сеть и не запускают внешние процессы**. HTTP мокается через `responses`, вызовы `subprocess` и функции проверки репозиториев — через `monkeypatch`. Тест, которому нужен реальный `git`, `cdxgen` или доступ к API, написан неправильно.
|
|
31
|
+
|
|
32
|
+
Для нового кода тест обязателен. Для исправления бага — сначала тест, воспроизводящий ошибку.
|
|
33
|
+
|
|
34
|
+
## Стиль кода
|
|
35
|
+
|
|
36
|
+
- Python 3.12+, длина строки 120, форматирование ruff.
|
|
37
|
+
- Документация, комментарии, сообщения об ошибках и вывод CLI — на русском языке.
|
|
38
|
+
- SPDX-заголовки обязательны в каждом файле:
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
# SPDX-FileCopyrightText: 2026 Ваше Имя
|
|
42
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Файлы, унаследованные от исходного проекта sbom-checker, сохраняют строку копирайта ИСП РАН — не удаляйте её, добавляйте свою следом.
|
|
46
|
+
|
|
47
|
+
- Комментарии объясняют «почему», а не «что». Комментарий, пересказывающий соседнюю строку кода, не нужен.
|
|
48
|
+
|
|
49
|
+
## Структура проекта
|
|
50
|
+
|
|
51
|
+
CLI построен на typer: `efs/cli.py` — единственная точка входа, она разбирает аргументы и передаёт их в `run(args)` соответствующего модуля. Логика команд живёт в модулях (`checker.py`, `updater.py`, `postprocess.py`, ...), в CLI её быть не должно.
|
|
52
|
+
|
|
53
|
+
Документация лежит в [`docs/`](docs/): [руководство по ФСТЭК](docs/fstec.md), [справочник команд](docs/commands.md), [описание конфига](docs/config.md). Меняете поведение команды — поправьте справочник в том же коммите.
|
|
54
|
+
|
|
55
|
+
## Коммиты и pull request'ы
|
|
56
|
+
|
|
57
|
+
- Заголовок коммита — одной строкой, на английском, в формате Conventional Commits: `feat:`, `fix:`, `docs:`, `test:`, `refactor:`, `chore:`, `ci:`, `build:`, `style:`.
|
|
58
|
+
- Ломающие изменения помечаются восклицательным знаком: `refactor!: ...`.
|
|
59
|
+
- Одно изменение — один коммит. Форматирование не смешивается с содержательными правками.
|
|
60
|
+
- Изменения, заметные пользователю, добавляются в `CHANGELOG.md` в раздел `Unreleased`.
|
|
61
|
+
|
|
62
|
+
## Релизы
|
|
63
|
+
|
|
64
|
+
Версия задаётся в `pyproject.toml`. Релиз выпускается тегом:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
git tag v1.1.0
|
|
68
|
+
git push origin v1.1.0
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Дальше всё делает workflow `release.yml`: собирает дистрибутивы, публикует их в PyPI через trusted publishing и создаёт релиз на GitHub. Токены PyPI в секретах репозитория не хранятся.
|
|
72
|
+
|
|
73
|
+
## Лицензия
|
|
74
|
+
|
|
75
|
+
Отправляя pull request, вы соглашаетесь на распространение своего вклада на условиях [Apache License 2.0](LICENSE).
|