Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 31 additions & 9 deletions .github/scripts/commit_prefix_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,18 +62,28 @@ def infer_prefix_from_paths(paths):
component_prefixes.add(f"{parts[1]}:")

# ----- src/ → flb_xxx.* → xxx: OR src/<dir>/ → <dir>: -----
# ----- src/fluent-bit.c → bin: -----
# ----- src/ handling -----
if p.startswith("src/"):
parts = p.split("/")
filename = os.path.basename(p)
if filename.startswith("flb_"):

# src/fluent-bit.c → bin:
if filename == "fluent-bit.c":
component_prefixes.add("bin:")
continue

# src/flb_xxx.c → xxx:
if len(parts) == 2 and filename.startswith("flb_"):
core = filename[4:].split(".")[0]
component_prefixes.add(f"{core}:")
elif filename == "fluent-bit.c":
component_prefixes.add("bin:")
else:
parts = p.split("/")
if len(parts) > 1:
component_prefixes.add(f"{parts[1]}:")
continue

# src/<dir>/... → <dir>:
if len(parts) > 2:
src_dir = parts[1]
component_prefixes.add(f"{src_dir}:")
continue


# prefixes = component prefixes + build: if needed
prefixes |= component_prefixes
Expand Down Expand Up @@ -170,6 +180,18 @@ def validate_commit(commit):
expected_lower = {p.lower() for p in expected}
subj_lower = subject_prefix.lower()

# ------------------------------------------------
# config_format strict rule:
# If config_format: exists, it MUST be used as subject
# ------------------------------------------------
if "config_format:" in expected_lower and subj_lower != "config_format:":
expected_list = sorted(expected)
expected_str = ", ".join(expected_list)
return False, (
f"Subject prefix '{subject_prefix}' does not match files changed.\n"
f"Expected one of: config_format:"
)

# ------------------------------------------------
# Multiple-component detection
# ------------------------------------------------
Expand All @@ -183,7 +205,7 @@ def validate_commit(commit):
}

# Prefixes that are allowed to cover multiple subcomponents
umbrella_prefixes = {"lib:"}
umbrella_prefixes = {"lib:", "config_format:"}

# If more than one non-build prefix is inferred AND the subject is not an umbrella
# prefix, require split commits.
Expand Down
69 changes: 69 additions & 0 deletions .github/scripts/tests/test_commit_lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,75 @@ def test_valid_config_file_changes():
ok, _ = validate_commit(commit)
assert ok is True

# -----------------------------------------------------------
# config_format strict rules
# -----------------------------------------------------------

def test_valid_config_format_commit():
"""
When files under src/config_format are modified, the subject MUST use
the umbrella prefix 'config_format:'.

This ensures config_format is treated as a logical subsystem rather than
exposing internal implementation names (cf_yaml, cf_fluentbit, etc.)
in commit subjects.
"""
commit = make_commit(
"config_format: cf_yaml: fix include resolution\n\nSigned-off-by: User",
["src/config_format/flb_cf_yaml.c"]
)
ok, _ = validate_commit(commit)
assert ok is True


def test_error_cf_yaml_prefix_not_allowed():
"""
Internal implementation prefixes like 'cf_yaml:' must NOT be allowed
as commit subjects when modifying src/config_format.

The umbrella prefix 'config_format:' must be used instead.
"""
commit = make_commit(
"cf_yaml: fix include resolution\n\nSigned-off-by: User",
["src/config_format/flb_cf_yaml.c"]
)
ok, msg = validate_commit(commit)
assert ok is False
assert "config_format:" in msg


def test_error_yaml_prefix_not_allowed():
"""
Generic implementation prefixes like 'yaml:' must NOT be allowed
for src/config_format changes.

This prevents leaking format-specific implementation details into
commit history.
"""
commit = make_commit(
"yaml: fix include resolution\n\nSigned-off-by: User",
["src/config_format/flb_cf_yaml.c"]
)
ok, msg = validate_commit(commit)
assert ok is False
assert "config_format:" in msg


def test_valid_config_format_multiple_files():
"""
Modifying multiple files under src/config_format should still require
the 'config_format:' umbrella prefix.
"""
commit = make_commit(
"config_format: refactor include handling\n\nSigned-off-by: User",
[
"src/config_format/flb_cf_yaml.c",
"src/config_format/flb_cf_fluentbit.c",
]
)
ok, _ = validate_commit(commit)
assert ok is True


# -----------------------------------------------------------
# Additional Tests: validate_commit Complex Scenarios
Expand Down