gitlab-compliance 2.6.0__tar.gz → 2.7.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.
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/PKG-INFO +7 -7
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/pyproject.toml +12 -12
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/behave_support/environment.py +7 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/behave_support/steps/given_steps.py +19 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/include_fetch.py +6 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/include_resolution.py +4 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/model.py +39 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/runner.py +6 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/gitlab_compliance.py +142 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/modules/pipeline_data.py +539 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/LICENSE +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/docs/index.md +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/__init__.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/__init__.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/api_config.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/api_enrichment.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/behave_support/steps/__init__.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/behave_support/steps/script_steps.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/behave_support/steps/then_steps.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/behave_support/steps/when_steps.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/builtin_policies/__init__.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/builtin_policies/baseline-jobs.feature +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/builtin_policies/component-inputs.feature +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/builtin_policies/include-pinning.feature +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/builtin_policies/shell/shell-ci-conventions.feature +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/builtin_policies/shell/shell-command-substitution.feature +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/builtin_policies/shell/shell-conditionals.feature +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/builtin_policies/shell/shell-error-handling.feature +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/builtin_policies/shell/shell-file-operations.feature +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/builtin_policies/shell/shell-pinning.feature +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/builtin_policies/shell/shell-pipelines.feature +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/builtin_policies/shell/shell-portability.feature +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/builtin_policies/shell/shell-quoting.feature +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/builtin_policies/shell/shell-references.feature +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/builtin_policies/shell/shell-security.feature +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/builtin_policies/supply-chain/image-pinning.feature +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/builtin_policies/supply-chain/include-versions.feature +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/builtin_policies/supply-chain/service-pinning.feature +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/builtin_policies/variable-allowlist.feature +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/console.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/container_fix.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/gitlab_api.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/image_versions.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/include_fix.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/include_versions.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/merge_requests.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/metadata.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/models.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/oci_registry.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/policy_doc.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/policy_fix.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/release_cache.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/render.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/script_analysis.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/secret_redact.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/shell_lex.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/shell_render.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/stash.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/supply_chain_fix.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/gitlab_docs.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/modules/__init__.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/modules/command_reference.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/modules/common.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/modules/constants.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/modules/doc_controller.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/modules/gitlab_reference.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/modules/gitstrings.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/modules/job_composition.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/modules/logging.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/modules/output_filters.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/modules/release.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/modules/swagger_html.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/modules/swagger_markdown.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/modules/yaml_lines.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/modules/yaml_md_table.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/properties/__init__.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/properties/extract_job_attribute.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/properties/includes.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/properties/inputs.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/properties/jobs.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/properties/table_render.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/properties/variables.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/properties/workflows.py +0 -0
- {gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/properties/yaml_paths.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gitlab-compliance
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.7.0
|
|
4
4
|
Summary: BDD compliance testing for GitLab CI/CD pipelines and project settings — by MaturityBuilder
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
License-File: LICENSE
|
|
@@ -19,21 +19,21 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
19
19
|
Classifier: Topic :: Software Development :: Quality Assurance
|
|
20
20
|
Classifier: Topic :: Software Development :: Testing
|
|
21
21
|
Requires-Dist: behave (>=1.2.6,<2.0.0)
|
|
22
|
-
Requires-Dist: click (>=8.
|
|
23
|
-
Requires-Dist: idna (==3.
|
|
22
|
+
Requires-Dist: click (>=8.5.0,<9.0.0)
|
|
23
|
+
Requires-Dist: idna (==3.20)
|
|
24
24
|
Requires-Dist: jq (==1.12.0)
|
|
25
25
|
Requires-Dist: loguru (==0.7.2)
|
|
26
26
|
Requires-Dist: markdown-analysis (==0.1.5)
|
|
27
|
-
Requires-Dist: oras (==0.2.
|
|
27
|
+
Requires-Dist: oras (==0.2.43)
|
|
28
28
|
Requires-Dist: oyaml
|
|
29
29
|
Requires-Dist: prettytable
|
|
30
30
|
Requires-Dist: pytablewriter (==1.2.1)
|
|
31
|
-
Requires-Dist: python-gitlab (==8.
|
|
31
|
+
Requires-Dist: python-gitlab (==8.6.0)
|
|
32
32
|
Requires-Dist: pyyaml (==6.0.3)
|
|
33
33
|
Requires-Dist: requests (==2.34.2)
|
|
34
34
|
Requires-Dist: rich (==15.0.0)
|
|
35
|
-
Requires-Dist: semver (==3.0
|
|
36
|
-
Requires-Dist: typer (==0.27.
|
|
35
|
+
Requires-Dist: semver (==3.1.0)
|
|
36
|
+
Requires-Dist: typer (==0.27.2)
|
|
37
37
|
Requires-Dist: urllib3 (==2.8.0)
|
|
38
38
|
Project-URL: Documentation, https://maturitybuilder.github.io/gitlab-compliance/
|
|
39
39
|
Project-URL: Home Page, https://maturitybuilder.github.io/gitlab-compliance/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "gitlab-compliance"
|
|
3
|
-
version = "2.
|
|
3
|
+
version = "2.7.0"
|
|
4
4
|
dynamic = [ "readme" ]
|
|
5
5
|
license = "Apache-2.0"
|
|
6
6
|
requires-python = ">=3.12"
|
|
@@ -40,18 +40,18 @@ python = ">=3.12"
|
|
|
40
40
|
prettytable = "*"
|
|
41
41
|
pytablewriter = "1.2.1"
|
|
42
42
|
oyaml = "*"
|
|
43
|
-
typer = "0.27.
|
|
43
|
+
typer = "0.27.2"
|
|
44
44
|
markdown-analysis = "0.1.5"
|
|
45
45
|
urllib3 = "2.8.0"
|
|
46
46
|
jq = "1.12.0"
|
|
47
|
-
click = "^8.
|
|
48
|
-
semver = "3.0
|
|
47
|
+
click = "^8.5.0"
|
|
48
|
+
semver = "3.1.0"
|
|
49
49
|
pyyaml = "6.0.3"
|
|
50
50
|
loguru = "0.7.2"
|
|
51
|
-
python-gitlab = "8.
|
|
51
|
+
python-gitlab = "8.6.0"
|
|
52
52
|
rich = "15.0.0"
|
|
53
|
-
oras = "0.2.
|
|
54
|
-
idna = "3.
|
|
53
|
+
oras = "0.2.43"
|
|
54
|
+
idna = "3.20"
|
|
55
55
|
requests = "2.34.2"
|
|
56
56
|
behave = "^1.2.6"
|
|
57
57
|
|
|
@@ -60,13 +60,13 @@ gitlab-docs = 'src.gitlab_compliance:gitlab_compliance'
|
|
|
60
60
|
gitlab-compliance = 'src.gitlab_compliance:gitlab_compliance'
|
|
61
61
|
|
|
62
62
|
[tool.poetry.group.dev.dependencies]
|
|
63
|
-
setuptools = "
|
|
63
|
+
setuptools = "84.1.0"
|
|
64
64
|
pytest = "^9.0.3"
|
|
65
65
|
pytest-xdist = "^3.8.0"
|
|
66
|
-
pytest-cov = "^
|
|
67
|
-
pre-commit = "^4.6.
|
|
66
|
+
pytest-cov = "^7.1.0"
|
|
67
|
+
pre-commit = "^4.6.2"
|
|
68
68
|
pyyaml = "^6.0.3"
|
|
69
|
-
coverage = "^7.
|
|
69
|
+
coverage = "^7.16.2"
|
|
70
70
|
|
|
71
71
|
[tool.black]
|
|
72
72
|
line-length = 88
|
|
@@ -79,7 +79,7 @@ max-line-length = 88
|
|
|
79
79
|
extend-ignore = ["E203", "W503"]
|
|
80
80
|
|
|
81
81
|
[tool.poetry.group.docs.dependencies]
|
|
82
|
-
zensical = "^0.0.
|
|
82
|
+
zensical = "^0.0.67"
|
|
83
83
|
[build-system]
|
|
84
84
|
requires = ["poetry-core","setuptools","poetry-bumpversion","id"]
|
|
85
85
|
build-backend = "poetry.core.masonry.api"
|
{gitlab_compliance-2.6.0 → gitlab_compliance-2.7.0}/src/compliance/behave_support/environment.py
RENAMED
|
@@ -37,6 +37,10 @@ def before_scenario(context, scenario):
|
|
|
37
37
|
if not context.compliance_entities:
|
|
38
38
|
depth_raw = context.config.userdata.get("max_include_depth", "")
|
|
39
39
|
max_include_depth = int(depth_raw) if str(depth_raw).strip() else None
|
|
40
|
+
generated_raw = context.config.userdata.get("generated_configs", "") or ""
|
|
41
|
+
generated_configs = tuple(
|
|
42
|
+
part.strip() for part in str(generated_raw).split(",") if part.strip()
|
|
43
|
+
)
|
|
40
44
|
context.compliance_entities = load_pipeline_entities(
|
|
41
45
|
pipeline_file=pipeline,
|
|
42
46
|
include_nested=context.config.userdata.get("include_nested", "true")
|
|
@@ -54,6 +58,9 @@ def before_scenario(context, scenario):
|
|
|
54
58
|
resolve_external_includes=_resolve_external_flag(
|
|
55
59
|
context.config.userdata.get("resolve_external_includes", "auto")
|
|
56
60
|
),
|
|
61
|
+
resolve_generated=context.config.userdata.get("resolve_generated", "true")
|
|
62
|
+
== "true",
|
|
63
|
+
generated_configs=generated_configs or None,
|
|
57
64
|
cache=getattr(context, "release_cache", None),
|
|
58
65
|
)
|
|
59
66
|
|
|
@@ -107,6 +107,25 @@ def given_any_container_image_with_release_metadata(context):
|
|
|
107
107
|
)
|
|
108
108
|
|
|
109
109
|
|
|
110
|
+
@given("I have any dynamic child pipeline defined")
|
|
111
|
+
def given_any_dynamic_child_pipeline(context):
|
|
112
|
+
_set_stash(context, context.compliance_entities.get("dynamic_child_pipelines", []))
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
@given('I have dynamic child pipeline "{name}" defined')
|
|
116
|
+
def given_named_dynamic_child_pipeline(context, name):
|
|
117
|
+
pipelines = [
|
|
118
|
+
item
|
|
119
|
+
for item in context.compliance_entities.get("dynamic_child_pipelines", [])
|
|
120
|
+
if item.get("name") == name or item.get("trigger_job") == name
|
|
121
|
+
]
|
|
122
|
+
_set_stash_or_skip(
|
|
123
|
+
context,
|
|
124
|
+
pipelines,
|
|
125
|
+
skip_reason=f'No dynamic child pipeline named "{name}" found in pipeline',
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
|
|
110
129
|
@given("I have any variable defined")
|
|
111
130
|
def given_any_variable(context):
|
|
112
131
|
_set_stash(context, context.compliance_entities.get("variables", []))
|
|
@@ -322,6 +322,12 @@ def include_reference_label(parsed: dict[str, Any]) -> str:
|
|
|
322
322
|
return f"{parsed.get('project', '')}@{parsed.get('version', '')}"
|
|
323
323
|
if include_type == "template":
|
|
324
324
|
return str(parsed.get("project", ""))
|
|
325
|
+
if include_type == "artifact":
|
|
326
|
+
artifact = parsed.get("artifact") or parsed.get("project", "")
|
|
327
|
+
generator = parsed.get("generator_job") or ""
|
|
328
|
+
if generator:
|
|
329
|
+
return f"{artifact} (from job {generator})"
|
|
330
|
+
return str(artifact)
|
|
325
331
|
return str(parsed.get("project", ""))
|
|
326
332
|
|
|
327
333
|
|
|
@@ -16,6 +16,10 @@ REASON_MESSAGES = {
|
|
|
16
16
|
"external_resolution_disabled": "external include resolution disabled",
|
|
17
17
|
"path_rejected": "local include path rejected",
|
|
18
18
|
"not_found": "include file not found",
|
|
19
|
+
"generated_at_runtime": (
|
|
20
|
+
"generated CI YAML not on disk yet "
|
|
21
|
+
"(run compliance after the generator job writes the artifact)"
|
|
22
|
+
),
|
|
19
23
|
}
|
|
20
24
|
|
|
21
25
|
|
|
@@ -106,11 +106,32 @@ def _workflow_rule_entity(
|
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
|
|
109
|
+
def _dynamic_child_pipeline_entity(index: int, record: dict) -> dict:
|
|
110
|
+
trigger_job = str(record.get("trigger_job") or "")
|
|
111
|
+
artifact = str(record.get("artifact") or "")
|
|
112
|
+
name = trigger_job or artifact or f"dynamic-child-{index}"
|
|
113
|
+
return {
|
|
114
|
+
"address": f"dynamic_child_pipeline.{index}",
|
|
115
|
+
"type": "dynamic_child_pipeline",
|
|
116
|
+
"name": name,
|
|
117
|
+
"trigger_job": trigger_job,
|
|
118
|
+
"generator_job": str(record.get("generator_job") or ""),
|
|
119
|
+
"artifact": artifact,
|
|
120
|
+
"resolved": bool(record.get("resolved")),
|
|
121
|
+
"include_type": str(record.get("include_type") or "artifact"),
|
|
122
|
+
"values": dict(record),
|
|
123
|
+
"source_file": str(record.get("source_file") or ""),
|
|
124
|
+
"line": int(record.get("line") or 0),
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
|
|
109
128
|
def load_yaml_entities(
|
|
110
129
|
pipeline_file: str,
|
|
111
130
|
include_nested: bool = True,
|
|
112
131
|
max_include_depth: int | None = None,
|
|
113
132
|
resolve_external_includes: bool | None = None,
|
|
133
|
+
resolve_generated: bool = True,
|
|
134
|
+
generated_configs: tuple[str, ...] | list[str] | None = None,
|
|
114
135
|
gitlab_url: str | None = None,
|
|
115
136
|
token: str | None = None,
|
|
116
137
|
) -> tuple[dict[str, list[dict]], list[dict]]:
|
|
@@ -125,6 +146,8 @@ def load_yaml_entities(
|
|
|
125
146
|
include_scripts=True,
|
|
126
147
|
resolve_job_composition=True,
|
|
127
148
|
resolve_external_includes=resolve_external_includes,
|
|
149
|
+
resolve_generated=resolve_generated,
|
|
150
|
+
generated_configs=generated_configs,
|
|
128
151
|
gitlab_url=gitlab_url,
|
|
129
152
|
token=token,
|
|
130
153
|
)
|
|
@@ -168,6 +191,12 @@ def load_yaml_entities(
|
|
|
168
191
|
)
|
|
169
192
|
for index, rule in enumerate(pipeline_data["workflow_rules"], 1)
|
|
170
193
|
],
|
|
194
|
+
"dynamic_child_pipelines": [
|
|
195
|
+
_dynamic_child_pipeline_entity(index, record)
|
|
196
|
+
for index, record in enumerate(
|
|
197
|
+
pipeline_data.get("dynamic_child_pipelines") or [], 1
|
|
198
|
+
)
|
|
199
|
+
],
|
|
171
200
|
"project_settings": [],
|
|
172
201
|
"project_ci_variables": [],
|
|
173
202
|
"group_settings": [],
|
|
@@ -201,6 +230,8 @@ def _job_values(job: dict) -> dict:
|
|
|
201
230
|
"extends_chain",
|
|
202
231
|
"unresolved_script_references",
|
|
203
232
|
"script_provenance",
|
|
233
|
+
"dynamic_parent_job",
|
|
234
|
+
"generated_artifact",
|
|
204
235
|
):
|
|
205
236
|
if key in job:
|
|
206
237
|
values[key] = job[key]
|
|
@@ -212,6 +243,8 @@ def load_merged_job_scripts(
|
|
|
212
243
|
include_nested: bool = True,
|
|
213
244
|
max_include_depth: int | None = None,
|
|
214
245
|
resolve_external_includes: bool | None = None,
|
|
246
|
+
resolve_generated: bool = True,
|
|
247
|
+
generated_configs: tuple[str, ...] | list[str] | None = None,
|
|
215
248
|
gitlab_url: str | None = None,
|
|
216
249
|
token: str | None = None,
|
|
217
250
|
) -> list[dict]:
|
|
@@ -224,6 +257,8 @@ def load_merged_job_scripts(
|
|
|
224
257
|
include_scripts=True,
|
|
225
258
|
resolve_job_composition=True,
|
|
226
259
|
resolve_external_includes=resolve_external_includes,
|
|
260
|
+
resolve_generated=resolve_generated,
|
|
261
|
+
generated_configs=generated_configs,
|
|
227
262
|
gitlab_url=gitlab_url,
|
|
228
263
|
token=token,
|
|
229
264
|
)
|
|
@@ -242,6 +277,8 @@ def load_pipeline_entities(
|
|
|
242
277
|
enrich_images: bool = True,
|
|
243
278
|
load_api_entities: bool = True,
|
|
244
279
|
resolve_external_includes: bool | None = None,
|
|
280
|
+
resolve_generated: bool = True,
|
|
281
|
+
generated_configs: tuple[str, ...] | list[str] | None = None,
|
|
245
282
|
cache: "ReleaseMetadataCache | None" = None,
|
|
246
283
|
) -> dict[str, list[dict]]:
|
|
247
284
|
from src.compliance.api_config import resolve_group, resolve_project, resolve_token
|
|
@@ -252,6 +289,8 @@ def load_pipeline_entities(
|
|
|
252
289
|
include_nested=include_nested,
|
|
253
290
|
max_include_depth=max_include_depth,
|
|
254
291
|
resolve_external_includes=resolve_external_includes,
|
|
292
|
+
resolve_generated=resolve_generated,
|
|
293
|
+
generated_configs=generated_configs,
|
|
255
294
|
gitlab_url=gitlab_url,
|
|
256
295
|
token=token,
|
|
257
296
|
)
|
|
@@ -427,6 +427,8 @@ def run_compliance(
|
|
|
427
427
|
group: str | None = None,
|
|
428
428
|
strict: bool = False,
|
|
429
429
|
resolve_external_includes: bool | None = None,
|
|
430
|
+
resolve_generated: bool = True,
|
|
431
|
+
generated_configs: tuple[str, ...] | list[str] | None = None,
|
|
430
432
|
dry_run: bool = False,
|
|
431
433
|
output_format: str = "console",
|
|
432
434
|
policies_source: str | None = None,
|
|
@@ -513,6 +515,8 @@ def run_compliance(
|
|
|
513
515
|
include_nested=include_nested,
|
|
514
516
|
max_include_depth=max_include_depth,
|
|
515
517
|
resolve_external_includes=resolve_external_includes,
|
|
518
|
+
resolve_generated=resolve_generated,
|
|
519
|
+
generated_configs=generated_configs,
|
|
516
520
|
gitlab_url=gitlab_url,
|
|
517
521
|
token=resolved_token or token,
|
|
518
522
|
)
|
|
@@ -615,6 +619,8 @@ def run_compliance(
|
|
|
615
619
|
if resolve_external_includes is True
|
|
616
620
|
else "false" if resolve_external_includes is False else "auto"
|
|
617
621
|
),
|
|
622
|
+
"resolve_generated": "true" if resolve_generated else "false",
|
|
623
|
+
"generated_configs": ",".join(generated_configs or ()),
|
|
618
624
|
"release_cache": release_cache,
|
|
619
625
|
"shell_check_verbose": "true" if verbose else "false",
|
|
620
626
|
}
|
|
@@ -11,6 +11,7 @@ from datetime import datetime
|
|
|
11
11
|
import click
|
|
12
12
|
|
|
13
13
|
import src.gitlab_docs as _gitlab_docs
|
|
14
|
+
import src.modules.common as common
|
|
14
15
|
import src.modules.doc_controller as md_writer
|
|
15
16
|
import src.properties.includes as includes
|
|
16
17
|
import src.properties.inputs as inputs
|
|
@@ -93,6 +94,37 @@ def _parse_generate_filters(exclude, group_by):
|
|
|
93
94
|
return exclude_sections, exclude_attributes, group_by
|
|
94
95
|
|
|
95
96
|
|
|
97
|
+
def _render_dynamic_child_pipelines(OUTPUT_FILE, pipeline_data: dict) -> None:
|
|
98
|
+
records = pipeline_data.get("dynamic_child_pipelines") or []
|
|
99
|
+
if not records:
|
|
100
|
+
return
|
|
101
|
+
add_between_markers(
|
|
102
|
+
file_path=OUTPUT_FILE, content="\n\n## Dynamic child pipelines\n\n"
|
|
103
|
+
)
|
|
104
|
+
table = common.table_design(
|
|
105
|
+
headers=[
|
|
106
|
+
"**Trigger job**",
|
|
107
|
+
"**Generator job**",
|
|
108
|
+
"**Artifact**",
|
|
109
|
+
"**Resolved**",
|
|
110
|
+
]
|
|
111
|
+
)
|
|
112
|
+
for record in records:
|
|
113
|
+
table.add_row(
|
|
114
|
+
[
|
|
115
|
+
record.get("trigger_job") or "—",
|
|
116
|
+
record.get("generator_job") or "—",
|
|
117
|
+
record.get("artifact") or "—",
|
|
118
|
+
"yes" if record.get("resolved") else "no",
|
|
119
|
+
]
|
|
120
|
+
)
|
|
121
|
+
add_between_markers(
|
|
122
|
+
file_path=OUTPUT_FILE,
|
|
123
|
+
content=common.markdown_table_from_prettytable(table),
|
|
124
|
+
)
|
|
125
|
+
add_between_markers(file_path=OUTPUT_FILE, content="\n")
|
|
126
|
+
|
|
127
|
+
|
|
96
128
|
def _generate_markdown(
|
|
97
129
|
OUTPUT_FILE,
|
|
98
130
|
GLDOCS_CONFIG_FILE,
|
|
@@ -101,6 +133,8 @@ def _generate_markdown(
|
|
|
101
133
|
exclude_attributes=None,
|
|
102
134
|
group_by=None,
|
|
103
135
|
max_include_depth=None,
|
|
136
|
+
resolve_generated=True,
|
|
137
|
+
generated_configs=None,
|
|
104
138
|
):
|
|
105
139
|
ENABLE_WORKFLOW_DOCUMENTATION = detailed
|
|
106
140
|
exclude_sections = exclude_sections or set()
|
|
@@ -133,6 +167,7 @@ def _generate_markdown(
|
|
|
133
167
|
DISABLE_TITLE=True,
|
|
134
168
|
OUTPUT_FILE=OUTPUT_FILE,
|
|
135
169
|
)
|
|
170
|
+
pipeline_data = None
|
|
136
171
|
if "jobs" not in exclude_sections:
|
|
137
172
|
pipeline_data = collect_pipeline_data(
|
|
138
173
|
config_file=GLDOCS_CONFIG_FILE,
|
|
@@ -141,12 +176,26 @@ def _generate_markdown(
|
|
|
141
176
|
exclude_sections=exclude_sections,
|
|
142
177
|
exclude_attributes=exclude_attributes,
|
|
143
178
|
group_by=group_by,
|
|
179
|
+
resolve_generated=resolve_generated,
|
|
180
|
+
generated_configs=generated_configs,
|
|
144
181
|
)
|
|
145
182
|
jobs.render_jobs_from_pipeline(
|
|
146
183
|
OUTPUT_FILE=OUTPUT_FILE,
|
|
147
184
|
pipeline_data=pipeline_data,
|
|
148
185
|
detailed=detailed,
|
|
149
186
|
)
|
|
187
|
+
if pipeline_data is None:
|
|
188
|
+
pipeline_data = collect_pipeline_data(
|
|
189
|
+
config_file=GLDOCS_CONFIG_FILE,
|
|
190
|
+
detailed=detailed,
|
|
191
|
+
max_include_depth=max_include_depth,
|
|
192
|
+
exclude_sections=exclude_sections,
|
|
193
|
+
exclude_attributes=exclude_attributes,
|
|
194
|
+
group_by=group_by,
|
|
195
|
+
resolve_generated=resolve_generated,
|
|
196
|
+
generated_configs=generated_configs,
|
|
197
|
+
)
|
|
198
|
+
_render_dynamic_child_pipelines(OUTPUT_FILE, pipeline_data)
|
|
150
199
|
|
|
151
200
|
|
|
152
201
|
def _generate_html(
|
|
@@ -157,6 +206,8 @@ def _generate_html(
|
|
|
157
206
|
exclude_attributes=None,
|
|
158
207
|
group_by=None,
|
|
159
208
|
max_include_depth=None,
|
|
209
|
+
resolve_generated=True,
|
|
210
|
+
generated_configs=None,
|
|
160
211
|
):
|
|
161
212
|
pipeline_data = collect_pipeline_data(
|
|
162
213
|
config_file=GLDOCS_CONFIG_FILE,
|
|
@@ -165,6 +216,8 @@ def _generate_html(
|
|
|
165
216
|
exclude_sections=exclude_sections,
|
|
166
217
|
exclude_attributes=exclude_attributes,
|
|
167
218
|
group_by=group_by,
|
|
219
|
+
resolve_generated=resolve_generated,
|
|
220
|
+
generated_configs=generated_configs,
|
|
168
221
|
)
|
|
169
222
|
html_output = render_swagger_html(pipeline_data)
|
|
170
223
|
with open(OUTPUT_FILE, "w", encoding="utf-8") as output_file:
|
|
@@ -179,6 +232,8 @@ def _generate_swagger_markdown(
|
|
|
179
232
|
exclude_attributes=None,
|
|
180
233
|
group_by=None,
|
|
181
234
|
max_include_depth=None,
|
|
235
|
+
resolve_generated=True,
|
|
236
|
+
generated_configs=None,
|
|
182
237
|
):
|
|
183
238
|
pipeline_data = collect_pipeline_data(
|
|
184
239
|
config_file=GLDOCS_CONFIG_FILE,
|
|
@@ -187,6 +242,8 @@ def _generate_swagger_markdown(
|
|
|
187
242
|
exclude_sections=exclude_sections,
|
|
188
243
|
exclude_attributes=exclude_attributes,
|
|
189
244
|
group_by=group_by,
|
|
245
|
+
resolve_generated=resolve_generated,
|
|
246
|
+
generated_configs=generated_configs,
|
|
190
247
|
)
|
|
191
248
|
markdown_output = render_swagger_markdown(pipeline_data)
|
|
192
249
|
with open(OUTPUT_FILE, "w", encoding="utf-8") as output_file:
|
|
@@ -365,6 +422,21 @@ def get_attributes(OUTPUT_FILE, GLDOCS_CONFIG_FILE, attributes, json_format):
|
|
|
365
422
|
default=None,
|
|
366
423
|
help="Max local include nesting depth from the root file (omit for unlimited).",
|
|
367
424
|
)
|
|
425
|
+
@click.option(
|
|
426
|
+
"--resolve-generated/--no-resolve-generated",
|
|
427
|
+
"resolve_generated",
|
|
428
|
+
default=True,
|
|
429
|
+
help=(
|
|
430
|
+
"Load dynamically generated child pipeline YAML from trigger.include "
|
|
431
|
+
"artifact paths when the file exists on disk (default: on)."
|
|
432
|
+
),
|
|
433
|
+
)
|
|
434
|
+
@click.option(
|
|
435
|
+
"--generated-config",
|
|
436
|
+
"generated_configs",
|
|
437
|
+
multiple=True,
|
|
438
|
+
help=("Extra generated CI YAML path to merge into documentation (repeatable)."),
|
|
439
|
+
)
|
|
368
440
|
def generate(
|
|
369
441
|
detailed,
|
|
370
442
|
output_format,
|
|
@@ -374,6 +446,8 @@ def generate(
|
|
|
374
446
|
exclude,
|
|
375
447
|
group_by,
|
|
376
448
|
max_include_depth,
|
|
449
|
+
resolve_generated,
|
|
450
|
+
generated_configs,
|
|
377
451
|
):
|
|
378
452
|
"""
|
|
379
453
|
Will scan through your gitlab-ci yml and build documentation from the yml.
|
|
@@ -403,6 +477,8 @@ def generate(
|
|
|
403
477
|
exclude_attributes=exclude_attributes,
|
|
404
478
|
group_by=group_by,
|
|
405
479
|
max_include_depth=max_include_depth,
|
|
480
|
+
resolve_generated=resolve_generated,
|
|
481
|
+
generated_configs=generated_configs,
|
|
406
482
|
)
|
|
407
483
|
|
|
408
484
|
if output_format == "html":
|
|
@@ -554,6 +630,24 @@ def _resolve_policies_dir(
|
|
|
554
630
|
"project when a token is available)."
|
|
555
631
|
),
|
|
556
632
|
)
|
|
633
|
+
@click.option(
|
|
634
|
+
"--resolve-generated/--no-resolve-generated",
|
|
635
|
+
"resolve_generated",
|
|
636
|
+
default=True,
|
|
637
|
+
help=(
|
|
638
|
+
"Load dynamically generated child pipeline YAML from trigger.include "
|
|
639
|
+
"artifact paths when the file exists on disk (default: on)."
|
|
640
|
+
),
|
|
641
|
+
)
|
|
642
|
+
@click.option(
|
|
643
|
+
"--generated-config",
|
|
644
|
+
"generated_configs",
|
|
645
|
+
multiple=True,
|
|
646
|
+
help=(
|
|
647
|
+
"Extra generated CI YAML path to merge (repeatable). Use when the artifact "
|
|
648
|
+
"is written somewhere other than the declared trigger.include path."
|
|
649
|
+
),
|
|
650
|
+
)
|
|
557
651
|
@click.option(
|
|
558
652
|
"--gitlab-url",
|
|
559
653
|
default=None,
|
|
@@ -690,6 +784,8 @@ def check(
|
|
|
690
784
|
include_nested,
|
|
691
785
|
max_include_depth,
|
|
692
786
|
resolve_external_includes,
|
|
787
|
+
resolve_generated,
|
|
788
|
+
generated_configs,
|
|
693
789
|
gitlab_url,
|
|
694
790
|
token,
|
|
695
791
|
project,
|
|
@@ -739,6 +835,8 @@ def check(
|
|
|
739
835
|
include_nested=include_nested,
|
|
740
836
|
max_include_depth=max_include_depth,
|
|
741
837
|
resolve_external_includes=resolve_external_includes,
|
|
838
|
+
resolve_generated=resolve_generated,
|
|
839
|
+
generated_configs=generated_configs,
|
|
742
840
|
gitlab_url=gitlab_url,
|
|
743
841
|
token=token,
|
|
744
842
|
project=project,
|
|
@@ -849,6 +947,24 @@ def check(
|
|
|
849
947
|
"project when a token is available)."
|
|
850
948
|
),
|
|
851
949
|
)
|
|
950
|
+
@click.option(
|
|
951
|
+
"--resolve-generated/--no-resolve-generated",
|
|
952
|
+
"resolve_generated",
|
|
953
|
+
default=True,
|
|
954
|
+
help=(
|
|
955
|
+
"Load dynamically generated child pipeline YAML from trigger.include "
|
|
956
|
+
"artifact paths when the file exists on disk (default: on)."
|
|
957
|
+
),
|
|
958
|
+
)
|
|
959
|
+
@click.option(
|
|
960
|
+
"--generated-config",
|
|
961
|
+
"generated_configs",
|
|
962
|
+
multiple=True,
|
|
963
|
+
help=(
|
|
964
|
+
"Extra generated CI YAML path to merge (repeatable). Use when the artifact "
|
|
965
|
+
"is written somewhere other than the declared trigger.include path."
|
|
966
|
+
),
|
|
967
|
+
)
|
|
852
968
|
@click.option(
|
|
853
969
|
"--features",
|
|
854
970
|
"-f",
|
|
@@ -924,6 +1040,8 @@ def supply_chain(
|
|
|
924
1040
|
include_nested,
|
|
925
1041
|
max_include_depth,
|
|
926
1042
|
resolve_external_includes,
|
|
1043
|
+
resolve_generated,
|
|
1044
|
+
generated_configs,
|
|
927
1045
|
features_dir,
|
|
928
1046
|
gitlab_url,
|
|
929
1047
|
token,
|
|
@@ -955,6 +1073,8 @@ def supply_chain(
|
|
|
955
1073
|
include_nested=include_nested,
|
|
956
1074
|
max_include_depth=max_include_depth,
|
|
957
1075
|
resolve_external_includes=resolve_external_includes,
|
|
1076
|
+
resolve_generated=resolve_generated,
|
|
1077
|
+
generated_configs=generated_configs,
|
|
958
1078
|
gitlab_url=gitlab_url,
|
|
959
1079
|
token=token,
|
|
960
1080
|
project=project,
|
|
@@ -1050,6 +1170,24 @@ def supply_chain(
|
|
|
1050
1170
|
"project when a token is available)."
|
|
1051
1171
|
),
|
|
1052
1172
|
)
|
|
1173
|
+
@click.option(
|
|
1174
|
+
"--resolve-generated/--no-resolve-generated",
|
|
1175
|
+
"resolve_generated",
|
|
1176
|
+
default=True,
|
|
1177
|
+
help=(
|
|
1178
|
+
"Load dynamically generated child pipeline YAML from trigger.include "
|
|
1179
|
+
"artifact paths when the file exists on disk (default: on)."
|
|
1180
|
+
),
|
|
1181
|
+
)
|
|
1182
|
+
@click.option(
|
|
1183
|
+
"--generated-config",
|
|
1184
|
+
"generated_configs",
|
|
1185
|
+
multiple=True,
|
|
1186
|
+
help=(
|
|
1187
|
+
"Extra generated CI YAML path to merge (repeatable). Use when the artifact "
|
|
1188
|
+
"is written somewhere other than the declared trigger.include path."
|
|
1189
|
+
),
|
|
1190
|
+
)
|
|
1053
1191
|
@click.option(
|
|
1054
1192
|
"--gitlab-url",
|
|
1055
1193
|
default=None,
|
|
@@ -1118,6 +1256,8 @@ def shell_check(
|
|
|
1118
1256
|
include_nested,
|
|
1119
1257
|
max_include_depth,
|
|
1120
1258
|
resolve_external_includes,
|
|
1259
|
+
resolve_generated,
|
|
1260
|
+
generated_configs,
|
|
1121
1261
|
gitlab_url,
|
|
1122
1262
|
token,
|
|
1123
1263
|
project,
|
|
@@ -1147,6 +1287,8 @@ def shell_check(
|
|
|
1147
1287
|
include_nested=include_nested,
|
|
1148
1288
|
max_include_depth=max_include_depth,
|
|
1149
1289
|
resolve_external_includes=resolve_external_includes,
|
|
1290
|
+
resolve_generated=resolve_generated,
|
|
1291
|
+
generated_configs=generated_configs,
|
|
1150
1292
|
gitlab_url=gitlab_url,
|
|
1151
1293
|
token=token,
|
|
1152
1294
|
project=project,
|