Repository navigation
Expand file tree
/
Copy pathmain.py
More file actions
132 lines (115 loc) · 5.26 KB
/
Copy pathmain.py
File metadata and controls
132 lines (115 loc) · 5.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import os
import requests
import json
import sys
token = sys.argv[1]
endpoint = sys.argv[2]
exclude = sys.argv[3] if len(sys.argv) > 3 else ""
build_mode_manual_override = sys.argv[4] if len(sys.argv) > 4 else ""
standard_language_names = sys.argv[5] if len(sys.argv) > 5 else ""
# Opt-in: use the standard combined CodeQL language names (e.g. "javascript-typescript")
# as used by github/codeql-action, instead of the legacy single names (e.g. "javascript").
# Defaults to False to preserve backward compatibility with existing workflows.
use_standard_language_names = standard_language_names.strip().lower() in ("true", "1", "yes")
codeql_languages = ["actions", "cpp", "c-cpp", "csharp", "go", "java", "java-kotlin", "javascript",
"javascript-typescript", "python", "ruby", "rust", "typescript", "kotlin", "swift"]
# Connect to the languages API and return languages
def get_languages():
headers = {'Authorization': 'Bearer ' + token, 'Accept': 'application/vnd.github.v3+json'}
response = requests.get(endpoint, headers=headers)
return response.json()
# Find the intersection of the languages returned by the API and the languages supported by CodeQL
def build_languages_list(languages):
original_languages = [language.lower() for language in languages.keys()]
mapped_languages = []
language_mapping = {} # Track mapped language -> list of original languages
for orig_lang in original_languages:
mapped_lang = orig_lang
if orig_lang == "c#":
mapped_lang = "csharp"
elif orig_lang in ("c++", "c"):
mapped_lang = "c-cpp" if use_standard_language_names else "cpp"
elif orig_lang == "typescript":
mapped_lang = "javascript-typescript" if use_standard_language_names else "javascript"
elif orig_lang == "javascript" and use_standard_language_names:
mapped_lang = "javascript-typescript"
elif orig_lang == "kotlin":
mapped_lang = "java-kotlin" if use_standard_language_names else "java"
elif orig_lang == "java" and use_standard_language_names:
mapped_lang = "java-kotlin"
elif orig_lang == "yaml":
mapped_lang = "actions"
mapped_languages.append(mapped_lang)
# Track all original languages that map to this CodeQL language
if mapped_lang not in language_mapping:
language_mapping[mapped_lang] = []
language_mapping[mapped_lang].append(orig_lang)
print("After mapping:", mapped_languages)
intersection = list(set(mapped_languages) & set(codeql_languages))
print("Intersection:", intersection)
return intersection, language_mapping
# return a list of objects from language list if they are not in the exclude list
def exclude_languages(language_list):
if not exclude:
return language_list
excluded = [x.strip() for x in exclude.split(',')]
output = list(set(language_list).difference(excluded))
print("languages={}".format(output))
return output
# Determine build mode for each language
def get_build_mode(language, original_languages=None):
# Languages that should use manual build mode by default
# Check original languages first if available
if original_languages:
# If any of the original languages require manual build mode, use manual
for orig_lang in original_languages:
if orig_lang in ["kotlin", "go", "swift"]:
manual_by_default = True
break
else:
manual_by_default = False
else:
# Fallback to mapped language check
manual_by_default = language in ["go", "swift"]
# Check if user overrode build mode to manual
if build_mode_manual_override:
override_languages = [x.strip() for x in build_mode_manual_override.split(',')]
if language in override_languages:
return "manual"
if original_languages:
for orig_lang in original_languages:
if orig_lang in override_languages:
return "manual"
# Use default logic
if manual_by_default:
return "manual"
else:
return "none"
# Build the matrix include format
def build_matrix(language_list, language_mapping):
include = []
for language in language_list:
original_languages = language_mapping.get(language, [language])
build_mode = get_build_mode(language, original_languages)
include.append({
"language": language,
"build-mode": build_mode
})
matrix = {"include": include}
print("Matrix:", matrix)
return matrix
# Set the output of the action
def set_action_output(output_name, value) :
if "GITHUB_OUTPUT" in os.environ :
with open(os.environ["GITHUB_OUTPUT"], "a") as f :
print("{0}={1}".format(output_name, value), file=f)
def main():
languages = get_languages()
language_list, language_mapping = build_languages_list(languages)
filtered_languages = exclude_languages(language_list)
matrix = build_matrix(filtered_languages, language_mapping)
set_action_output("matrix", json.dumps(matrix))
# Keep the old output for backward compatibility
set_action_output("languages", json.dumps(filtered_languages))
if __name__ == '__main__':
main()