Skip to content

Commit edcaf22

Browse files
committed
Fix script to handle SARIF file recategorization
adding GitPython lib cleaning the files for redundant made Codeql executable with bazel fixing bzel run issues adding a version removing timeout addresses several issues related to environment-specific paths and execution context removing the ref
1 parent ebd508f commit edcaf22

14 files changed

Lines changed: 567 additions & 230 deletions

File tree

.github/codeql/codeql-config.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,11 @@ paths-ignore:
1919
- "**/test/**"
2020
- "**/mock/**"
2121
- "**/codeql-coding-standards-repo/**"
22+
- "**/examples/**"
23+
- "**/docs/**"
24+
- "**/target/**"
25+
- "**/bazel-*/**"
26+
- "**/.git/**"
27+
- "**/node_modules/**"
28+
- "**/build/**"
29+
- "**/dist/**"

.github/workflows/codeql-multiple-repo-scan.yml

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ jobs:
3232
analyze-repos:
3333
name: Analyze Multiple Repositories
3434
runs-on: ubuntu-latest
35+
timeout-minutes: 120 # Prevent indefinite hanging
3536
permissions:
3637
security-events: write
3738
packages: read
@@ -40,25 +41,23 @@ jobs:
4041
steps:
4142
- name: Checkout central repository
4243
uses: actions/checkout@v4
43-
- name: Checkout CodeQL Coding Standards scripts
44-
uses: actions/checkout@v4
45-
with:
46-
repository: github/codeql-coding-standards
47-
path: codeql-coding-standards-repo # Klonen in diesen Ordner
48-
ref: main # Oder eine spezifische Release-Version, z.B. 'v2.53.0-dev'
49-
# Add coding standard packages and dependencies
50-
- name: Install Python dependencies for Coding Standards scripts
44+
- name: Install sarif-tools for HTML report generation
5145
run: |
5246
python3 -m pip install --upgrade pip
53-
pip3 install pyyaml jsonpath-ng jsonschema jsonpatch jsonpointer pytest sarif-tools
54-
- name: Parse known_good.json and create repos.json
55-
id: parse-repos
56-
run: |
57-
scripts/workflow/parse_repos.sh
47+
pip3 install sarif-tools
48+
- name: Cache repository checkouts
49+
uses: actions/cache@v4
50+
with:
51+
path: repos/
52+
key: repos-${{ hashFiles('known_good.json') }}
53+
restore-keys: |
54+
repos-
5855
- name: Checkout all pinned repositories
5956
id: checkout-repos
57+
env:
58+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
6059
run: |
61-
scripts/workflow/checkout_repos.sh
60+
bazel run //scripts/tooling:checkout_repos
6261
- name: Initialize CodeQL for all repositories
6362
uses: github/codeql-action/init@v4
6463
with:
@@ -69,16 +68,30 @@ jobs:
6968
- name: Perform CodeQL Analysis
7069
uses: github/codeql-action/analyze@v4
7170
with:
72-
upload-database: false # Don't upload databases for each repo
71+
upload-database: false
7372
output: sarif-results/
7473
category: "multi-repo-scan"
74+
- name: Cleanup repository checkouts
75+
if: always()
76+
run: |
77+
echo "Cleaning up checked out repositories to free disk space"
78+
rm -rf repos/
79+
- name: Checkout CodeQL Coding Standards scripts
80+
uses: actions/checkout@v4
81+
with:
82+
repository: github/codeql-coding-standards
83+
path: codeql-coding-standards-repo
7584
- name: Recategorize Guidelines
7685
if: always()
7786
run: |
78-
scripts/workflow/recategorize_guidelines.sh
87+
bazel run //scripts/tooling:recategorize_guidelines
7988
- name: Generate HTML Report from SARIF
8089
run: |
8190
SARIF_FILE="sarif-results/cpp.sarif"
91+
if [ ! -f "$SARIF_FILE" ]; then
92+
echo "Error: SARIF file not found at $SARIF_FILE"
93+
exit 1
94+
fi
8295
sarif html "$SARIF_FILE" --output codeql-report.html
8396
- name: Upload SARIF results as artifact
8497
uses: actions/upload-artifact@v4

feature_integration_tests/test_cases/BUILD

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ compile_pip_requirements(
2525
"requirements.txt",
2626
"@score_tooling//python_basics:requirements.txt",
2727
],
28+
extra_args = [
29+
"--no-annotate",
30+
],
2831
requirements_txt = "requirements.txt.lock",
2932
tags = [
3033
"manual",

feature_integration_tests/test_cases/requirements.txt.lock

Lines changed: 23 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,17 @@
22
# This file is autogenerated by pip-compile with Python 3.12
33
# by the following command:
44
#
5-
# bazel run //feature_integration_tests/python_test_cases:requirements.update
5+
# bazel run //feature_integration_tests/test_cases:requirements.update
66
#
7-
basedpyright==1.29.2 \
8-
--hash=sha256:12c49186003b9f69a028615da883ef97035ea2119a9e3f93a00091b3a27088a6 \
9-
--hash=sha256:f389e2997de33d038c5065fd85bff351fbdc62fa6d6371c7b947fc3bce8d437d
10-
# via -r /home/pko/.cache/bazel/_bazel_pko/2af2ff4db91047a487505aa8f91f8f54/external/score_tooling+/python_basics/requirements.txt
11-
iniconfig==2.1.0 \
12-
--hash=sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7 \
13-
--hash=sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760
14-
# via
15-
# -r /home/pko/.cache/bazel/_bazel_pko/2af2ff4db91047a487505aa8f91f8f54/external/score_tooling+/python_basics/requirements.txt
16-
# pytest
7+
basedpyright==1.35.0 \
8+
--hash=sha256:2a7e0bd476623d48499e2b18ff6ed19dc28c51909cf9e1152ad355b5809049ad \
9+
--hash=sha256:4f4f84023df5a0cd4ee154916ba698596682ac98bacfa22c941ed6aaf07bba4e
10+
iniconfig==2.3.0 \
11+
--hash=sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730 \
12+
--hash=sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12
1713
jinja2==3.1.6 \
1814
--hash=sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d \
1915
--hash=sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67
20-
# via pytest-html
2116
markupsafe==3.0.2 \
2217
--hash=sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4 \
2318
--hash=sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30 \
@@ -80,54 +75,37 @@ markupsafe==3.0.2 \
8075
--hash=sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79 \
8176
--hash=sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430 \
8277
--hash=sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50
83-
# via jinja2
84-
nodejs-wheel-binaries==22.16.0 \
85-
--hash=sha256:2728972d336d436d39ee45988978d8b5d963509e06f063e80fe41b203ee80b28 \
86-
--hash=sha256:2fffb4bf1066fb5f660da20819d754f1b424bca1b234ba0f4fa901c52e3975fb \
87-
--hash=sha256:447ad796850eb52ca20356ad39b2d296ed8fef3f214921f84a1ccdad49f2eba1 \
88-
--hash=sha256:4ae3cf22138891cb44c3ee952862a257ce082b098b29024d7175684a9a77b0c0 \
89-
--hash=sha256:71f2de4dc0b64ae43e146897ce811f80ac4f9acfbae6ccf814226282bf4ef174 \
90-
--hash=sha256:7f526ca6a132b0caf633566a2a78c6985fe92857e7bfdb37380f76205a10b808 \
91-
--hash=sha256:986b715a96ed703f8ce0c15712f76fc42895cf09067d72b6ef29e8b334eccf64 \
92-
--hash=sha256:d695832f026df3a0cf9a089d222225939de9d1b67f8f0a353b79f015aabbe7e2 \
93-
--hash=sha256:dbfccbcd558d2f142ccf66d8c3a098022bf4436db9525b5b8d32169ce185d99e
94-
# via
95-
# -r /home/pko/.cache/bazel/_bazel_pko/2af2ff4db91047a487505aa8f91f8f54/external/score_tooling+/python_basics/requirements.txt
96-
# basedpyright
78+
nodejs-wheel-binaries==24.11.1 \
79+
--hash=sha256:0e14874c3579def458245cdbc3239e37610702b0aa0975c1dc55e2cb80e42102 \
80+
--hash=sha256:10197b1c9c04d79403501766f76508b0dac101ab34371ef8a46fcf51773497d0 \
81+
--hash=sha256:376b9ea1c4bc1207878975dfeb604f7aa5668c260c6154dcd2af9d42f7734116 \
82+
--hash=sha256:413dfffeadfb91edb4d8256545dea797c237bba9b3faefea973cde92d96bb922 \
83+
--hash=sha256:5ef598101b0fb1c2bf643abb76dfbf6f76f1686198ed17ae46009049ee83c546 \
84+
--hash=sha256:78bc5bb889313b565df8969bb7423849a9c7fc218bf735ff0ce176b56b3e96f0 \
85+
--hash=sha256:c2741525c9874b69b3e5a6d6c9179a6fe484ea0c3d5e7b7c01121c8e5d78b7e2 \
86+
--hash=sha256:c79a7e43869ccecab1cae8183778249cceb14ca2de67b5650b223385682c6239 \
87+
--hash=sha256:cde41d5e4705266688a8d8071debf4f8a6fcea264c61292782672ee75a6905f9
9788
packaging==25.0 \
9889
--hash=sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484 \
9990
--hash=sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f
100-
# via
101-
# -r /home/pko/.cache/bazel/_bazel_pko/2af2ff4db91047a487505aa8f91f8f54/external/score_tooling+/python_basics/requirements.txt
102-
# pytest
10391
pluggy==1.6.0 \
10492
--hash=sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3 \
10593
--hash=sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746
106-
# via
107-
# -r /home/pko/.cache/bazel/_bazel_pko/2af2ff4db91047a487505aa8f91f8f54/external/score_tooling+/python_basics/requirements.txt
108-
# pytest
109-
pytest==8.3.5 \
110-
--hash=sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820 \
111-
--hash=sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845
112-
# via
113-
# -r /home/pko/.cache/bazel/_bazel_pko/2af2ff4db91047a487505aa8f91f8f54/external/score_tooling+/python_basics/requirements.txt
114-
# pytest-html
115-
# pytest-metadata
116-
# pytest-repeat
117-
# testing-utils
94+
pygments==2.19.2 \
95+
--hash=sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887 \
96+
--hash=sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b
97+
pytest==9.0.1 \
98+
--hash=sha256:3e9c069ea73583e255c3b21cf46b8d3c56f6e3a1a8f6da94ccb0fcf57b9d73c8 \
99+
--hash=sha256:67be0030d194df2dfa7b556f2e56fb3c3315bd5c8822c6951162b92b32ce7dad
118100
pytest-html==4.1.1 \
119101
--hash=sha256:70a01e8ae5800f4a074b56a4cb1025c8f4f9b038bba5fe31e3c98eb996686f07 \
120102
--hash=sha256:c8152cea03bd4e9bee6d525573b67bbc6622967b72b9628dda0ea3e2a0b5dd71
121-
# via testing-utils
122103
pytest-metadata==3.1.1 \
123104
--hash=sha256:c8e0844db684ee1c798cfa38908d20d67d0463ecb6137c72e91f418558dd5f4b \
124105
--hash=sha256:d2a29b0355fbc03f168aa96d41ff88b1a3b44a3b02acbe491801c98a048017c8
125-
# via pytest-html
126106
pytest-repeat==0.9.4 \
127107
--hash=sha256:c1738b4e412a6f3b3b9e0b8b29fcd7a423e50f87381ad9307ef6f5a8601139f3 \
128108
--hash=sha256:d92ac14dfaa6ffcfe6917e5d16f0c9bc82380c135b03c2a5f412d2637f224485
129-
# via testing-utils
130109
# WARNING: pip install will require the following package to be hashed.
131110
# Consider using a hashable URL like https://github.com/jazzband/pip-tools/archive/SOMECOMMIT.zip
132111
testing-utils @ git+https://github.com/eclipse-score/testing_tools.git@v0.3.0
133-
# via -r feature_integration_tests/python_test_cases/requirements.txt

scripts/tooling/BUILD

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,21 @@ load("@rules_python//python:defs.bzl", "py_binary", "py_library")
1515
load("@rules_python//python:pip.bzl", "compile_pip_requirements")
1616
load("@score_tooling//python_basics:defs.bzl", "score_py_pytest")
1717

18-
# In order to update the requirements, change the `requirements.in` file and run:
19-
# `bazel run //src:requirements.update`.
20-
# This will update the `requirements.txt` file.
21-
# To upgrade all dependencies to their latest versions, run:
22-
# `bazel run //src:requirements.update -- --upgrade`.
18+
# In order to update the requirements, change the `requirements.in` file and run
19+
# `bazel run //scripts/tooling:requirements.update`
20+
# This will update the `requirements.txt` file
21+
# To upgrade all dependencies to their latest versions, run
22+
# `bazel run //scripts/tooling:requirements.update -- --upgrade`
23+
2324
compile_pip_requirements(
2425
name = "requirements",
2526
srcs = [
2627
"requirements.in",
2728
"@score_tooling//python_basics:requirements.txt",
2829
],
30+
extra_args = [
31+
"--no-annotate",
32+
],
2933
requirements_txt = "requirements.txt",
3034
tags = [
3135
"manual",
@@ -58,6 +62,25 @@ py_binary(
5862
deps = [":cli"],
5963
)
6064

65+
# Workflow scripts as executables
66+
py_binary(
67+
name = "checkout_repos",
68+
srcs = ["cli/workflow/checkout_repos.py"],
69+
main = "cli/workflow/checkout_repos.py",
70+
visibility = ["//visibility:public"],
71+
deps = [
72+
":cli",
73+
":lib",
74+
] + all_requirements,
75+
)
76+
77+
py_binary(
78+
name = "recategorize_guidelines",
79+
srcs = ["cli/workflow/recategorize_guidelines.py"],
80+
main = "cli/workflow/recategorize_guidelines.py",
81+
visibility = ["//visibility:public"],
82+
)
83+
6184
# Tests target
6285
score_py_pytest(
6386
name = "tooling_tests",
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# *******************************************************************************
2+
# Copyright (c) 2026 Contributors to the Eclipse Foundation
3+
#
4+
# See the NOTICE file(s) distributed with this work for additional
5+
# information regarding copyright ownership.
6+
#
7+
# This program and the accompanying materials are made available under the
8+
# terms of the Apache License Version 2.0 which is available at
9+
# https://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# SPDX-License-Identifier: Apache-2.0
12+
# *******************************************************************************
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# *******************************************************************************
2+
# Copyright (c) 2026 Contributors to the Eclipse Foundation
3+
#
4+
# See the NOTICE file(s) distributed with this work for additional
5+
# information regarding copyright ownership.
6+
#
7+
# This program and the accompanying materials are made available under the
8+
# terms of the Apache License Version 2.0 which is available at
9+
# https://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# SPDX-License-Identifier: Apache-2.0
12+
# *******************************************************************************
13+
14+
"""
15+
Checkout all pinned repositories for CodeQL analysis.
16+
17+
Clones repositories directly from known_good.json using GitPython library
18+
with GitHub token authentication to avoid rate limits.
19+
"""
20+
21+
import logging
22+
import os
23+
import sys
24+
from pathlib import Path
25+
26+
from scripts.tooling.lib.git_operations import shallow_clone_repository
27+
from scripts.tooling.lib.known_good import load_known_good
28+
29+
_LOG = logging.getLogger(__name__)
30+
logging.basicConfig(level=logging.INFO, format="%(message)s")
31+
32+
33+
def checkout_repo(name: str, url: str, ref: str, path: Path) -> None:
34+
"""
35+
Checkout a single repository using git_operations library.
36+
37+
Args:
38+
name: Repository name
39+
url: Repository URL
40+
ref: Git reference (branch, tag, or commit hash)
41+
path: Local path to checkout into
42+
43+
Raises:
44+
Exception: If checkout fails
45+
"""
46+
_LOG.info(f"Checking out {name} ({ref}) to {path}")
47+
48+
shallow_clone_repository(url=url, path=path, ref=ref)
49+
50+
51+
def main() -> int:
52+
"""Main entry point for standalone execution."""
53+
# When running with bazel, use BUILD_WORKING_DIRECTORY to find workspace root
54+
workspace_root = Path(os.environ.get("BUILD_WORKING_DIRECTORY", "."))
55+
known_good_path = workspace_root / "known_good.json"
56+
57+
if not known_good_path.exists():
58+
_LOG.error(f"known_good.json not found at {known_good_path}")
59+
return 1
60+
61+
try:
62+
known_good = load_known_good(known_good_path)
63+
except Exception as e:
64+
_LOG.error(f"Failed to parse known_good.json: {e}")
65+
return 1
66+
67+
# Extract target_sw modules
68+
modules = known_good.modules.get("target_sw", {})
69+
repo_count = len(modules)
70+
71+
_LOG.info(f"Checking out {repo_count} repositories from known_good.json...")
72+
73+
# Track successfully checked out repositories
74+
repo_paths = []
75+
76+
# Checkout each repository
77+
for name, module in modules.items():
78+
url = module.repo
79+
ref = module.version or module.branch or module.hash
80+
# Use workspace-relative path
81+
path = workspace_root / "repos" / name
82+
83+
try:
84+
checkout_repo(name, url, ref, path)
85+
repo_paths.append(str(path))
86+
except Exception as e:
87+
_LOG.error(f"Failed to checkout {name}: {e}")
88+
return 1
89+
90+
# Output all paths (comma-separated for GitHub Actions compatibility)
91+
repo_paths_output = ",".join(repo_paths)
92+
93+
# Write to GITHUB_OUTPUT if available
94+
github_output = os.environ.get("GITHUB_OUTPUT")
95+
if github_output:
96+
try:
97+
with open(github_output, "a") as f:
98+
f.write(f"repo_paths={repo_paths_output}\n")
99+
except IOError as e:
100+
_LOG.warning(f"Failed to write GITHUB_OUTPUT: {e}")
101+
102+
# Log summary
103+
_LOG.info(f"Successfully checked out {len(repo_paths)} of {repo_count} repositories")
104+
105+
return 0
106+
107+
108+
if __name__ == "__main__":
109+
sys.exit(main())

0 commit comments

Comments
 (0)