Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
23 changes: 15 additions & 8 deletions .github/scripts/detect-build-matrix.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
#!/usr/bin/env python3
# file: .github/scripts/detect-build-matrix.py
# version: 1.1.0
# version: 1.1.1
# guid: a1b2c3d4-e5f6-7890-1234-56789abcdef0
# last-edited: 2026-10-05

"""Detect build matrix requirements for the repository.

This script analyzes the repository to determine what technologies are used
and generates appropriate build matrices for GitHub Actions.
"""
Expand Down Expand Up @@ -74,7 +76,8 @@ def detect_build_requirements():

# Check for Python projects
if any(
os.path.exists(f) for f in ["pyproject.toml", "requirements.txt", "setup.py"]
os.path.exists(f)
for f in ["pyproject.toml", "requirements.txt", "setup.py"]
) or check_file_exists("*.py"):
print("Python project detected")
flags["has_python"] = True
Expand Down Expand Up @@ -103,9 +106,7 @@ def detect_build_requirements():
# Read package.json to determine if this is actually a frontend project
try:
with open("package.json") as f:
import json as json_lib

pkg_data = json_lib.load(f)
pkg_data = json.load(f)

# Check for frontend indicators
frontend_indicators = [
Expand Down Expand Up @@ -154,7 +155,9 @@ def detect_build_requirements():
**pkg_data.get("devDependencies", {}),
}

has_frontend_deps = any(indicator in all_deps for indicator in frontend_indicators)
has_frontend_deps = any(
indicator in all_deps for indicator in frontend_indicators
)
has_build_scripts = any(
script in build_scripts
for script in script_indicators
Expand Down Expand Up @@ -197,7 +200,9 @@ def detect_build_requirements():
print("Docker project detected")
flags["has_docker"] = True
# Use docker-detect.py script for detailed Docker configuration
success, output = run_command("python3 .github/scripts/docker-detect.py")
success, _output = run_command(
"python3 .github/scripts/docker-detect.py"
)
if success:
print("Docker detection script completed successfully")
# The docker-detect.py script will set its own outputs
Expand All @@ -215,7 +220,9 @@ def detect_build_requirements():
}

# Check for protobuf
if any(os.path.exists(f) for f in ["buf.yaml", "buf.gen.yaml"]) or check_file_exists("*.proto"):
if any(
os.path.exists(f) for f in ["buf.yaml", "buf.gen.yaml"]
) or check_file_exists("*.proto"):
print("Protobuf project detected")
flags["protobuf_needed"] = True

Expand Down
32 changes: 23 additions & 9 deletions .github/scripts/detect_languages.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#!/usr/bin/env python3
# file: .github/scripts/detect_languages.py
# version: 1.2.0
# version: 1.2.1
# guid: 4f6c9d88-2d4b-4a1e-9c61-3e0b2b9a7f11
# last-edited: 2026-10-05
"""Detect project languages and emit key=value lines for GitHub Actions outputs.

Enhanced to respect `.github/workflow-config.yaml` for language versions,
Expand Down Expand Up @@ -51,7 +52,11 @@ def load_build_config() -> dict[str, Any]:
continue

# Detect leaving build section (new top-level key)
if in_build and not line.startswith(" ") and not stripped.startswith("build:"):
if (
in_build
and not line.startswith(" ")
and not stripped.startswith("build:")
):
# Reached a new top-level key; stop parsing build
break

Expand All @@ -77,7 +82,9 @@ def load_build_config() -> dict[str, Any]:
key, remainder = key_match.groups()

if remainder == "": # list start or empty value
current_list_key = key if key.endswith("s") else None # heuristic
current_list_key = (
key if key.endswith("s") else None
) # heuristic
if current_list_key:
build.setdefault(current_list_key, [])
continue
Expand All @@ -98,6 +105,7 @@ def load_build_config() -> dict[str, Any]:


def exists_any(*paths: str) -> bool:
"""Return True if any of the given paths exists."""
return any(os.path.exists(p) for p in paths)


Expand All @@ -109,7 +117,9 @@ def exists_any(*paths: str) -> bool:
else False
)
has_frontend = exists_any("package.json", "yarn.lock", "pnpm-lock.yaml")
has_docker = exists_any("Dockerfile", "docker-compose.yml", "docker-compose.yaml")
has_docker = exists_any(
"Dockerfile", "docker-compose.yml", "docker-compose.yaml"
)
has_rust = exists_any("Cargo.toml")
protobuf_needed = (
(build_cfg.get("enable_protobuf") is True)
Expand All @@ -130,8 +140,9 @@ def exists_any(*paths: str) -> bool:


def build_matrix(
kind: str, versions: list[str], os_list: list[str], version_key: str
versions: list[str], os_list: list[str], version_key: str
) -> dict[str, Any]:
"""Build a versions x OS include-matrix; the first entry is primary."""
include: list[dict[str, Any]] = []
if not versions or not os_list:
return {"include": include}
Expand Down Expand Up @@ -163,15 +174,17 @@ def build_matrix(
platforms = build_cfg.get("platforms") or ["linux/amd64", "linux/arm64"]

go_matrix = (
build_matrix("go", go_versions, operating_systems, "go-version") if has_go else {"include": []}
build_matrix(go_versions, operating_systems, "go-version")
if has_go
else {"include": []}
)
python_matrix = (
build_matrix("python", python_versions, operating_systems, "python-version")
build_matrix(python_versions, operating_systems, "python-version")
if has_python
else {"include": []}
)
frontend_matrix = (
build_matrix("frontend", node_versions, operating_systems, "node-version")
build_matrix(node_versions, operating_systems, "node-version")
if has_frontend
else {"include": []}
)
Expand All @@ -188,7 +201,8 @@ def build_matrix(
)


def emit(key: str, value):
def emit(key: str, value: object) -> None:
"""Print a key=value line for GITHUB_OUTPUT."""
print(f"{key}={value}")


Expand Down
21 changes: 15 additions & 6 deletions .github/scripts/determine-security-languages.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#!/usr/bin/env python3
# file: .github/scripts/determine-security-languages.py
# version: 1.1.0
# version: 1.1.1
# guid: a1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d
# last-edited: 2026-10-05

"""Determine which languages need security scanning based on file changes.

Expand All @@ -16,8 +17,10 @@


def get_env_bool(key: str, default: bool = False) -> bool:
"""Safely get a boolean environment variable."""
value = os.environ.get(key, "").lower()
"""Safely get a boolean environment variable; unset or empty -> default."""
value = os.environ.get(key, "").strip().lower()
if not value:
return default
return value in ("true", "1", "yes", "on")


Expand Down Expand Up @@ -53,7 +56,9 @@ def determine_security_languages() -> dict[str, any]:
else:
matrix = {"language": languages_with_changes}
has_languages = True
print(f"Languages for security scanning: {', '.join(languages_with_changes)}")
print(
f"Languages for security scanning: {', '.join(languages_with_changes)}"
)

result = {
"matrix": matrix,
Expand Down Expand Up @@ -92,9 +97,13 @@ def main() -> None:

# Write outputs for GitHub Actions
write_github_output("matrix", json.dumps(result["matrix"]))
write_github_output("has-languages", str(result["has_languages"]).lower())
write_github_output(
"has-languages", str(result["has_languages"]).lower()
)
write_github_output("language-count", str(result["language_count"]))
write_github_output("languages", json.dumps(result["languages"])) # Output as JSON array
write_github_output(
"languages", json.dumps(result["languages"])
) # Output as JSON array

print("✅ Security language determination completed successfully")

Expand Down
14 changes: 6 additions & 8 deletions .github/scripts/docker-detect.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
#!/usr/bin/env python3
# file: .github/scripts/docker-detect.py
# version: 1.0.1
# version: 1.0.2
# guid: d1e2f3g4-h5i6-j7k8-l9m0-n1o2p3q4r5s6
# last-edited: 2026-10-05

"""Docker configuration detection script for matrix build system.

Detects Docker files, configurations, and determines build strategy.
"""

Expand Down Expand Up @@ -63,10 +65,8 @@ def check_docker_compose():
def should_build_docker(event_name, ref):
"""Determine if Docker image should be built and pushed."""
return (
(event_name == "push" and ref == "refs/heads/main")
or event_name == "release"
or event_name == "workflow_dispatch"
)
event_name == "push" and ref == "refs/heads/main"
) or event_name in {"release", "workflow_dispatch"}


def generate_docker_matrix():
Expand All @@ -76,7 +76,7 @@ def generate_docker_matrix():
return {"include": []}

# Basic multi-platform matrix
matrix = {
return {
"include": [
{
"platform": "linux/amd64",
Expand All @@ -93,8 +93,6 @@ def generate_docker_matrix():
]
}

return matrix


def set_github_output(key, value):
"""Set GitHub Actions output."""
Expand Down
Loading
Loading