cdk-diff-summary 1.1.1__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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 cdk-diff-summary contributors
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 all
13
+ 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 THE
21
+ SOFTWARE.
@@ -0,0 +1,170 @@
1
+ Metadata-Version: 2.4
2
+ Name: cdk-diff-summary
3
+ Version: 1.1.1
4
+ Summary: Summarize AWS CDK diff JSON as compact Markdown.
5
+ Author: cdk-diff-summary contributors
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/jalcock501/cdk-diff-summary-pypi
8
+ Project-URL: Repository, https://github.com/jalcock501/cdk-diff-summary-pypi
9
+ Project-URL: Documentation, https://github.com/jalcock501/cdk-diff-summary-pypi#readme
10
+ Project-URL: Issues, https://github.com/jalcock501/cdk-diff-summary-pypi/issues
11
+ Keywords: aws,cdk,cloudformation,github-actions,diff
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Software Development :: Build Tools
20
+ Classifier: Topic :: System :: Systems Administration
21
+ Classifier: Typing :: Typed
22
+ Requires-Python: >=3.11
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Provides-Extra: dev
26
+ Requires-Dist: build<2.0,>=1.2; extra == "dev"
27
+ Requires-Dist: pytest<10.0,>=8.3; extra == "dev"
28
+ Requires-Dist: ruff<0.16,>=0.8; extra == "dev"
29
+ Requires-Dist: twine<7.0,>=5.0; extra == "dev"
30
+ Dynamic: license-file
31
+
32
+ # cdk-diff-summary
33
+
34
+ `cdk-diff-summary` reads AWS CDK diff JSON and renders a compact Markdown summary.
35
+
36
+ It is useful locally, in CI systems, and in GitHub Actions workflows where raw CDK or CloudFormation diffs are too noisy. It groups adds, modifies, removes, replacements, security group rule changes, and other changes while reducing common churn from IAM policy documents and CDK asset hashes.
37
+
38
+ The tool deliberately shows changed field paths only, not before/after values, to avoid exposing sensitive infrastructure values in summaries.
39
+
40
+ ## Install
41
+
42
+ ```bash
43
+ pipx install cdk-diff-summary
44
+ ```
45
+
46
+ or:
47
+
48
+ ```bash
49
+ python -m pip install cdk-diff-summary
50
+ ```
51
+
52
+ ## Usage
53
+
54
+ Generate CDK diff JSON:
55
+
56
+ ```bash
57
+ npx cdk diff --json > cdk-diff.json
58
+ ```
59
+
60
+ Render Markdown to stdout:
61
+
62
+ ```bash
63
+ cdk-diff-summary cdk-diff.json
64
+ ```
65
+
66
+ Append Markdown to a file:
67
+
68
+ ```bash
69
+ cdk-diff-summary cdk-diff.json --output cdk-diff-summary.md
70
+ ```
71
+
72
+ Use a custom title and field limit:
73
+
74
+ ```bash
75
+ cdk-diff-summary cdk-diff.json \
76
+ --title "Production CDK diff" \
77
+ --max-changed-fields 5
78
+ ```
79
+
80
+ Fail when visible removals or replacements exist:
81
+
82
+ ```bash
83
+ cdk-diff-summary cdk-diff.json --fail-on-remove --fail-on-replace
84
+ ```
85
+
86
+ ## CLI Options
87
+
88
+ | Option | Description |
89
+ | --- | --- |
90
+ | `diff-json-path` | Path to JSON produced by `cdk diff --json`. May also be set with `DIFF_JSON_PATH`. |
91
+ | `--title` | Markdown heading for the summary. Defaults to `CDK diff summary`. |
92
+ | `--max-changed-fields` | Maximum changed field paths shown per resource. Defaults to `8`. |
93
+ | `--collapse-iam-policies` / `--no-collapse-iam-policies` | Collapse large IAM policy document diffs to compact paths. Enabled by default. |
94
+ | `--collapse-assets` / `--no-collapse-assets` | Collapse common CDK asset/hash churn. Enabled by default. |
95
+ | `--fail-on-remove` | Write the summary, then exit non-zero if visible resource removes exist. |
96
+ | `--fail-on-replace` | Write the summary, then exit non-zero if visible resource replacements exist. |
97
+ | `--output` | Optional path to append the generated Markdown summary. |
98
+ | `--github-step-summary` | Optional path to append GitHub Step Summary Markdown. Defaults to `$GITHUB_STEP_SUMMARY`. |
99
+
100
+ Environment variables compatible with the GitHub Action wrapper are also supported:
101
+
102
+ - `DIFF_JSON_PATH`
103
+ - `SUMMARY_TITLE`
104
+ - `MAX_CHANGED_FIELDS`
105
+ - `COLLAPSE_IAM_POLICIES`
106
+ - `COLLAPSE_ASSETS`
107
+ - `FAIL_ON_REMOVE`
108
+ - `FAIL_ON_REPLACE`
109
+ - `SUMMARY_OUTPUT_PATH`
110
+ - `GITHUB_STEP_SUMMARY`
111
+
112
+ CLI arguments take precedence over environment variables.
113
+
114
+ ## Example Output
115
+
116
+ ```markdown
117
+ ## CDK diff summary
118
+
119
+ | Metric | Count |
120
+ | --- | ---: |
121
+ | Stack changes | 1 |
122
+ | Resource changes | 3 |
123
+ | Adds | 1 |
124
+ | Modifies | 1 |
125
+ | Removes | 0 |
126
+ | Replacements | 1 |
127
+ | Security group changes | 1 |
128
+ | Changes shown below | 4 |
129
+
130
+ ### Replacements
131
+
132
+ | Stack | Logical ID | Action | Resource type | Changed fields |
133
+ | --- | --- | --- | --- | --- |
134
+ | PaymentsStack | Worker | replace | AWS::Lambda::Function | `Architectures[]`, `Layers[]` |
135
+
136
+ ### Security group changes
137
+
138
+ | Stack | Security group | Direction | Protocol | Port | Action |
139
+ | --- | --- | --- | --- | --- | --- |
140
+ | PaymentsStack | AppSecurityGroup | ingress | tcp | 443 | add |
141
+ ```
142
+
143
+ ## Local Development
144
+
145
+ ```bash
146
+ python -m pip install -e ".[dev]"
147
+ python -m pytest
148
+ ruff check .
149
+ python -m build
150
+ twine check dist/*
151
+ ```
152
+
153
+ Run from source:
154
+
155
+ ```bash
156
+ cdk-diff-summary example_cdk_diff_json/cdk-diff-json-tiny.json
157
+ ```
158
+
159
+ ## Publishing
160
+
161
+ This package is ready for PyPI trusted publishing. Create a PyPI project named `cdk-diff-summary`, configure a trusted publisher for this repository and the `publish.yml` workflow, then create a GitHub release.
162
+
163
+ For a manual dry run:
164
+
165
+ ```bash
166
+ python -m build
167
+ twine check dist/*
168
+ ```
169
+
170
+ CDK diff JSON shape can vary by CDK version. If parsing fails, please open an issue with a sanitized example of the JSON shape that failed.
@@ -0,0 +1,139 @@
1
+ # cdk-diff-summary
2
+
3
+ `cdk-diff-summary` reads AWS CDK diff JSON and renders a compact Markdown summary.
4
+
5
+ It is useful locally, in CI systems, and in GitHub Actions workflows where raw CDK or CloudFormation diffs are too noisy. It groups adds, modifies, removes, replacements, security group rule changes, and other changes while reducing common churn from IAM policy documents and CDK asset hashes.
6
+
7
+ The tool deliberately shows changed field paths only, not before/after values, to avoid exposing sensitive infrastructure values in summaries.
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ pipx install cdk-diff-summary
13
+ ```
14
+
15
+ or:
16
+
17
+ ```bash
18
+ python -m pip install cdk-diff-summary
19
+ ```
20
+
21
+ ## Usage
22
+
23
+ Generate CDK diff JSON:
24
+
25
+ ```bash
26
+ npx cdk diff --json > cdk-diff.json
27
+ ```
28
+
29
+ Render Markdown to stdout:
30
+
31
+ ```bash
32
+ cdk-diff-summary cdk-diff.json
33
+ ```
34
+
35
+ Append Markdown to a file:
36
+
37
+ ```bash
38
+ cdk-diff-summary cdk-diff.json --output cdk-diff-summary.md
39
+ ```
40
+
41
+ Use a custom title and field limit:
42
+
43
+ ```bash
44
+ cdk-diff-summary cdk-diff.json \
45
+ --title "Production CDK diff" \
46
+ --max-changed-fields 5
47
+ ```
48
+
49
+ Fail when visible removals or replacements exist:
50
+
51
+ ```bash
52
+ cdk-diff-summary cdk-diff.json --fail-on-remove --fail-on-replace
53
+ ```
54
+
55
+ ## CLI Options
56
+
57
+ | Option | Description |
58
+ | --- | --- |
59
+ | `diff-json-path` | Path to JSON produced by `cdk diff --json`. May also be set with `DIFF_JSON_PATH`. |
60
+ | `--title` | Markdown heading for the summary. Defaults to `CDK diff summary`. |
61
+ | `--max-changed-fields` | Maximum changed field paths shown per resource. Defaults to `8`. |
62
+ | `--collapse-iam-policies` / `--no-collapse-iam-policies` | Collapse large IAM policy document diffs to compact paths. Enabled by default. |
63
+ | `--collapse-assets` / `--no-collapse-assets` | Collapse common CDK asset/hash churn. Enabled by default. |
64
+ | `--fail-on-remove` | Write the summary, then exit non-zero if visible resource removes exist. |
65
+ | `--fail-on-replace` | Write the summary, then exit non-zero if visible resource replacements exist. |
66
+ | `--output` | Optional path to append the generated Markdown summary. |
67
+ | `--github-step-summary` | Optional path to append GitHub Step Summary Markdown. Defaults to `$GITHUB_STEP_SUMMARY`. |
68
+
69
+ Environment variables compatible with the GitHub Action wrapper are also supported:
70
+
71
+ - `DIFF_JSON_PATH`
72
+ - `SUMMARY_TITLE`
73
+ - `MAX_CHANGED_FIELDS`
74
+ - `COLLAPSE_IAM_POLICIES`
75
+ - `COLLAPSE_ASSETS`
76
+ - `FAIL_ON_REMOVE`
77
+ - `FAIL_ON_REPLACE`
78
+ - `SUMMARY_OUTPUT_PATH`
79
+ - `GITHUB_STEP_SUMMARY`
80
+
81
+ CLI arguments take precedence over environment variables.
82
+
83
+ ## Example Output
84
+
85
+ ```markdown
86
+ ## CDK diff summary
87
+
88
+ | Metric | Count |
89
+ | --- | ---: |
90
+ | Stack changes | 1 |
91
+ | Resource changes | 3 |
92
+ | Adds | 1 |
93
+ | Modifies | 1 |
94
+ | Removes | 0 |
95
+ | Replacements | 1 |
96
+ | Security group changes | 1 |
97
+ | Changes shown below | 4 |
98
+
99
+ ### Replacements
100
+
101
+ | Stack | Logical ID | Action | Resource type | Changed fields |
102
+ | --- | --- | --- | --- | --- |
103
+ | PaymentsStack | Worker | replace | AWS::Lambda::Function | `Architectures[]`, `Layers[]` |
104
+
105
+ ### Security group changes
106
+
107
+ | Stack | Security group | Direction | Protocol | Port | Action |
108
+ | --- | --- | --- | --- | --- | --- |
109
+ | PaymentsStack | AppSecurityGroup | ingress | tcp | 443 | add |
110
+ ```
111
+
112
+ ## Local Development
113
+
114
+ ```bash
115
+ python -m pip install -e ".[dev]"
116
+ python -m pytest
117
+ ruff check .
118
+ python -m build
119
+ twine check dist/*
120
+ ```
121
+
122
+ Run from source:
123
+
124
+ ```bash
125
+ cdk-diff-summary example_cdk_diff_json/cdk-diff-json-tiny.json
126
+ ```
127
+
128
+ ## Publishing
129
+
130
+ This package is ready for PyPI trusted publishing. Create a PyPI project named `cdk-diff-summary`, configure a trusted publisher for this repository and the `publish.yml` workflow, then create a GitHub release.
131
+
132
+ For a manual dry run:
133
+
134
+ ```bash
135
+ python -m build
136
+ twine check dist/*
137
+ ```
138
+
139
+ CDK diff JSON shape can vary by CDK version. If parsing fails, please open an issue with a sanitized example of the JSON shape that failed.
@@ -0,0 +1,64 @@
1
+ [build-system]
2
+ requires = ["setuptools>=69", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "cdk-diff-summary"
7
+ version = "1.1.1"
8
+ description = "Summarize AWS CDK diff JSON as compact Markdown."
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [{ name = "cdk-diff-summary contributors" }]
14
+ keywords = ["aws", "cdk", "cloudformation", "github-actions", "diff"]
15
+ classifiers = [
16
+ "Development Status :: 4 - Beta",
17
+ "Environment :: Console",
18
+ "Intended Audience :: Developers",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.11",
21
+ "Programming Language :: Python :: 3.12",
22
+ "Programming Language :: Python :: 3.13",
23
+ "Topic :: Software Development :: Build Tools",
24
+ "Topic :: System :: Systems Administration",
25
+ "Typing :: Typed",
26
+ ]
27
+ dependencies = []
28
+
29
+ [project.optional-dependencies]
30
+ dev = [
31
+ "build>=1.2,<2.0",
32
+ "pytest>=8.3,<10.0",
33
+ "ruff>=0.8,<0.16",
34
+ "twine>=5.0,<7.0",
35
+ ]
36
+
37
+ [project.scripts]
38
+ cdk-diff-summary = "cdk_diff_summary.cli:main"
39
+
40
+ [project.urls]
41
+ Homepage = "https://github.com/jalcock501/cdk-diff-summary-pypi"
42
+ Repository = "https://github.com/jalcock501/cdk-diff-summary-pypi"
43
+ Documentation = "https://github.com/jalcock501/cdk-diff-summary-pypi#readme"
44
+ Issues = "https://github.com/jalcock501/cdk-diff-summary-pypi/issues"
45
+
46
+ [tool.setuptools]
47
+ package-dir = { "" = "src" }
48
+
49
+ [tool.setuptools.packages.find]
50
+ where = ["src"]
51
+
52
+ [tool.setuptools.package-data]
53
+ cdk_diff_summary = ["py.typed"]
54
+
55
+ [tool.pytest.ini_options]
56
+ pythonpath = ["src"]
57
+ testpaths = ["tests"]
58
+
59
+ [tool.ruff]
60
+ line-length = 100
61
+ target-version = "py311"
62
+
63
+ [tool.ruff.lint]
64
+ select = ["E", "F", "I", "UP", "B", "SIM"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,3 @@
1
+ """Summarize AWS CDK diff JSON as compact Markdown."""
2
+
3
+ __version__ = "1.1.1"
@@ -0,0 +1,167 @@
1
+ """Command-line interface for cdk-diff-summary."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ import json
7
+ import sys
8
+ from dataclasses import dataclass
9
+ from os import environ
10
+ from pathlib import Path
11
+ from typing import TextIO
12
+
13
+ from cdk_diff_summary.config import DEFAULT_TITLE, parse_bool, parse_max_changed_fields
14
+ from cdk_diff_summary.diff import DiffSummary, parse_diff
15
+ from cdk_diff_summary.render import render_summary
16
+
17
+
18
+ @dataclass(frozen=True)
19
+ class CliConfig:
20
+ diff_json_path: str
21
+ title: str
22
+ max_changed_fields: int
23
+ collapse_iam_policies: bool
24
+ collapse_assets: bool
25
+ fail_on_remove: bool
26
+ fail_on_replace: bool
27
+ output_path: str
28
+ github_step_summary: str
29
+
30
+
31
+ def main(argv: list[str] | None = None) -> int:
32
+ try:
33
+ config = parse_args(argv)
34
+ diff_summary = parse_diff_from_file(config)
35
+ markdown = render_summary(
36
+ diff_summary,
37
+ title=config.title,
38
+ max_changed_fields=config.max_changed_fields,
39
+ )
40
+ append_outputs(config, markdown)
41
+ return fail_status(config, diff_summary)
42
+ except (OSError, ValueError, json.JSONDecodeError) as exc:
43
+ print(f"cdk-diff-summary: {exc}", file=sys.stderr)
44
+ return 1
45
+
46
+
47
+ def parse_args(argv: list[str] | None = None) -> CliConfig:
48
+ parser = argparse.ArgumentParser(
49
+ description="Render a compact Markdown summary from AWS CDK diff JSON.",
50
+ )
51
+ parser.add_argument(
52
+ "diff_json_path",
53
+ nargs="?",
54
+ help="Path to JSON produced by cdk diff --json. Defaults to DIFF_JSON_PATH.",
55
+ )
56
+ parser.add_argument(
57
+ "--title",
58
+ default=environ.get("SUMMARY_TITLE", DEFAULT_TITLE) or DEFAULT_TITLE,
59
+ help="Markdown heading for the summary.",
60
+ )
61
+ parser.add_argument(
62
+ "--max-changed-fields",
63
+ default=environ.get("MAX_CHANGED_FIELDS", "8"),
64
+ help="Maximum changed field paths to show for each resource.",
65
+ )
66
+ parser.add_argument(
67
+ "--collapse-iam-policies",
68
+ action=argparse.BooleanOptionalAction,
69
+ default=parse_bool(environ.get("COLLAPSE_IAM_POLICIES"), default=True),
70
+ help="Collapse IAM policy document changes. Enabled by default.",
71
+ )
72
+ parser.add_argument(
73
+ "--collapse-assets",
74
+ action=argparse.BooleanOptionalAction,
75
+ default=parse_bool(environ.get("COLLAPSE_ASSETS"), default=True),
76
+ help="Collapse common CDK asset/hash churn. Enabled by default.",
77
+ )
78
+ parser.add_argument(
79
+ "--fail-on-remove",
80
+ action="store_true",
81
+ default=parse_bool(environ.get("FAIL_ON_REMOVE"), default=False),
82
+ help="Exit non-zero after writing the summary if visible removes exist.",
83
+ )
84
+ parser.add_argument(
85
+ "--fail-on-replace",
86
+ action="store_true",
87
+ default=parse_bool(environ.get("FAIL_ON_REPLACE"), default=False),
88
+ help="Exit non-zero after writing the summary if visible replacements exist.",
89
+ )
90
+ parser.add_argument(
91
+ "--output",
92
+ default=environ.get("SUMMARY_OUTPUT_PATH", "").strip(),
93
+ help="Optional path to append the generated Markdown summary.",
94
+ )
95
+ parser.add_argument(
96
+ "--github-step-summary",
97
+ default=environ.get("GITHUB_STEP_SUMMARY", "").strip(),
98
+ help="Optional path to append GitHub Step Summary Markdown.",
99
+ )
100
+
101
+ args = parser.parse_args(argv)
102
+ diff_json_path = args.diff_json_path or environ.get("DIFF_JSON_PATH", "").strip()
103
+ if not diff_json_path:
104
+ raise ValueError("diff-json-path argument or DIFF_JSON_PATH is required")
105
+
106
+ return CliConfig(
107
+ diff_json_path=diff_json_path,
108
+ title=args.title,
109
+ max_changed_fields=parse_max_changed_fields(str(args.max_changed_fields)),
110
+ collapse_iam_policies=args.collapse_iam_policies,
111
+ collapse_assets=args.collapse_assets,
112
+ fail_on_remove=args.fail_on_remove,
113
+ fail_on_replace=args.fail_on_replace,
114
+ output_path=args.output,
115
+ github_step_summary=args.github_step_summary,
116
+ )
117
+
118
+
119
+ def parse_diff_from_file(config: CliConfig) -> DiffSummary:
120
+ with Path(config.diff_json_path).open(encoding="utf-8") as handle:
121
+ document = json.load(handle)
122
+ return parse_diff(
123
+ document,
124
+ collapse_iam_policies=config.collapse_iam_policies,
125
+ collapse_assets=config.collapse_assets,
126
+ )
127
+
128
+
129
+ def append_outputs(config: CliConfig, markdown: str) -> None:
130
+ if config.github_step_summary:
131
+ append_file(Path(config.github_step_summary), markdown)
132
+ if config.output_path:
133
+ append_file(Path(config.output_path), markdown)
134
+ if not config.github_step_summary and not config.output_path:
135
+ sys.stdout.write(markdown)
136
+
137
+
138
+ def append_file(path: Path, markdown: str) -> None:
139
+ path.parent.mkdir(parents=True, exist_ok=True)
140
+ with path.open("a", encoding="utf-8") as handle:
141
+ append_markdown(handle, markdown)
142
+
143
+
144
+ def append_markdown(handle: TextIO, markdown: str) -> None:
145
+ handle.write(markdown)
146
+ if not markdown.endswith("\n"):
147
+ handle.write("\n")
148
+
149
+
150
+ def fail_status(config: CliConfig, diff_summary: DiffSummary) -> int:
151
+ if config.fail_on_remove and diff_summary.removes > 0:
152
+ print(
153
+ "cdk-diff-summary: visible removes found and --fail-on-remove is set",
154
+ file=sys.stderr,
155
+ )
156
+ return 2
157
+ if config.fail_on_replace and diff_summary.replacements > 0:
158
+ print(
159
+ "cdk-diff-summary: visible replacements found and --fail-on-replace is set",
160
+ file=sys.stderr,
161
+ )
162
+ return 3
163
+ return 0
164
+
165
+
166
+ if __name__ == "__main__":
167
+ raise SystemExit(main())
@@ -0,0 +1,64 @@
1
+ """Runtime configuration for the cdk-diff-summary action."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+ from os import environ
7
+
8
+ DEFAULT_TITLE = "CDK diff summary"
9
+ TRUE_VALUES = {"1", "true", "yes", "y", "on"}
10
+ FALSE_VALUES = {"0", "false", "no", "n", "off", ""}
11
+
12
+
13
+ @dataclass(frozen=True)
14
+ class Config:
15
+ diff_json_path: str
16
+ summary_title: str
17
+ max_changed_fields: int
18
+ collapse_iam_policies: bool
19
+ collapse_assets: bool
20
+ fail_on_remove: bool
21
+ fail_on_replace: bool
22
+ summary_output_path: str
23
+ github_step_summary: str
24
+
25
+
26
+ def parse_bool(value: str | None, *, default: bool = False) -> bool:
27
+ if value is None:
28
+ return default
29
+ normalized = value.strip().lower()
30
+ if normalized in TRUE_VALUES:
31
+ return True
32
+ if normalized in FALSE_VALUES:
33
+ return False
34
+ raise ValueError(f"expected a boolean value, got {value!r}")
35
+
36
+
37
+ def parse_max_changed_fields(value: str | None) -> int:
38
+ raw_value = "8" if value is None or value.strip() == "" else value.strip()
39
+ try:
40
+ parsed = int(raw_value)
41
+ except ValueError as exc:
42
+ message = "MAX_CHANGED_FIELDS must be an integer greater than or equal to 1"
43
+ raise ValueError(message) from exc
44
+ if parsed < 1:
45
+ raise ValueError("MAX_CHANGED_FIELDS must be greater than or equal to 1")
46
+ return parsed
47
+
48
+
49
+ def load_config() -> Config:
50
+ diff_json_path = environ.get("DIFF_JSON_PATH", "").strip()
51
+ if not diff_json_path:
52
+ raise ValueError("DIFF_JSON_PATH is required")
53
+
54
+ return Config(
55
+ diff_json_path=diff_json_path,
56
+ summary_title=environ.get("SUMMARY_TITLE", DEFAULT_TITLE) or DEFAULT_TITLE,
57
+ max_changed_fields=parse_max_changed_fields(environ.get("MAX_CHANGED_FIELDS")),
58
+ collapse_iam_policies=parse_bool(environ.get("COLLAPSE_IAM_POLICIES"), default=True),
59
+ collapse_assets=parse_bool(environ.get("COLLAPSE_ASSETS"), default=True),
60
+ fail_on_remove=parse_bool(environ.get("FAIL_ON_REMOVE"), default=False),
61
+ fail_on_replace=parse_bool(environ.get("FAIL_ON_REPLACE"), default=False),
62
+ summary_output_path=environ.get("SUMMARY_OUTPUT_PATH", "").strip(),
63
+ github_step_summary=environ.get("GITHUB_STEP_SUMMARY", "").strip(),
64
+ )