Skip to content

Commit 29cdd3a

Browse files
committed
chore: address PR review comments
Signed-off-by: sophie-bates <[email protected]>
1 parent aa64fa6 commit 29cdd3a

File tree

3 files changed

+41
-95
lines changed

3 files changed

+41
-95
lines changed

src/macaron/slsa_analyzer/build_tool/poetry.py

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import logging
1111
import os
1212
import tomllib
13-
from collections.abc import Iterable
1413
from pathlib import Path
1514

1615
from macaron.config.defaults import defaults
@@ -124,36 +123,3 @@ def get_dep_analyzer(self, repo_path: str) -> DependencyAnalyzer:
124123
"""
125124
# TODO: Implement this method.
126125
return NoneDependencyAnalyzer()
127-
128-
def get_build_dirs(self, repo_path: str) -> Iterable[Path]:
129-
"""Find directories in the repository that have their own build scripts.
130-
131-
This is especially important for applications that consist of multiple services.
132-
133-
Parameters
134-
----------
135-
repo_path: str
136-
The path to the target repo.
137-
138-
Yields
139-
------
140-
Path
141-
The relative paths from the repo path that contain build scripts.
142-
"""
143-
config_paths: set[str] = set()
144-
config_files = self.build_configs + self.package_lock
145-
for build_cfg in config_files:
146-
config_paths.update(glob.glob(os.path.join(repo_path, "**", build_cfg), recursive=True))
147-
148-
list_iter = iter(sorted(config_paths, key=lambda x: (str(Path(x).parent), len(Path(x).parts))))
149-
try:
150-
cfg_path = next(list_iter)
151-
yield Path(cfg_path).parent.relative_to(repo_path)
152-
while next_item := next(list_iter):
153-
if str(Path(cfg_path).parent) in next_item:
154-
continue
155-
cfg_path = next_item
156-
yield Path(next_item).parent.relative_to(repo_path)
157-
158-
except StopIteration:
159-
pass

tests/conftest.py

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
from macaron.slsa_analyzer.build_tool.maven import Maven
1313
from macaron.slsa_analyzer.build_tool.pip import Pip
1414
from macaron.slsa_analyzer.build_tool.poetry import Poetry
15-
from macaron.slsa_analyzer.checks.check_result import CheckResult
1615
from macaron.slsa_analyzer.ci_service.circleci import CircleCI
1716
from macaron.slsa_analyzer.ci_service.github_actions import GitHubActions
1817
from macaron.slsa_analyzer.ci_service.gitlab_ci import GitLabCI
@@ -71,23 +70,6 @@ def setup_test(test_dir: Path, macaron_path: Path) -> NoReturn: # type: ignore
7170
defaults.clear()
7271

7372

74-
@pytest.fixture()
75-
def check_result() -> CheckResult: # pylint: disable=unused-argument
76-
"""Create a CheckResult instance.
77-
78-
Parameters
79-
----------
80-
setup_test
81-
Depends on setup_test fixture.
82-
83-
Returns
84-
-------
85-
CheckResult
86-
The CheckResult instance.
87-
"""
88-
return CheckResult(justification=[]) # type: ignore
89-
90-
9173
@pytest.fixture(autouse=True)
9274
def maven_tool(setup_test) -> Maven: # type: ignore # pylint: disable=unused-argument
9375
"""Create a Maven tool instance.

tests/slsa_analyzer/checks/test_build_as_code_check.py

Lines changed: 41 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
from pathlib import Path
88
from unittest.mock import MagicMock
99

10-
import pytest
11-
1210
import macaron
1311
from macaron.code_analyzer.call_graph import BaseNode, CallGraph
1412
from macaron.parsers.actionparser import parse as parse_action
@@ -28,26 +26,7 @@
2826
from macaron.slsa_analyzer.specs.ci_spec import CIInfo
2927

3028

31-
@pytest.fixture()
32-
def build_as_code_check(setup_test) -> BuildAsCodeCheck: # type: ignore # pylint: disable=unused-argument
33-
"""Create a BuildAsCodeCheck instance.
34-
35-
Parameters
36-
----------
37-
setup_test
38-
Depends on setup_test fixture.
39-
40-
Returns
41-
-------
42-
BuildAsCodeCheck
43-
The BuildAsCodeCheck instance.
44-
"""
45-
return BuildAsCodeCheck()
46-
47-
4829
def test_build_as_code_check(
49-
build_as_code_check: BuildAsCodeCheck, # pylint: disable=redefined-outer-name
50-
check_result: CheckResult,
5130
maven_tool: Maven,
5231
gradle_tool: Gradle,
5332
poetry_tool: Poetry,
@@ -59,6 +38,8 @@ def test_build_as_code_check(
5938
gitlab_ci_service: GitLabCI,
6039
) -> None:
6140
"""Test the Build As Code Check."""
41+
check = BuildAsCodeCheck()
42+
check_result = CheckResult(justification=[]) # type: ignore
6243
bash_commands = BashCommands(caller_path="source_file", CI_path="ci_file", CI_type="github_actions", commands=[[]])
6344
ci_info = CIInfo(
6445
service=github_actions_service,
@@ -72,131 +53,131 @@ def test_build_as_code_check(
7253
# The target repo uses Maven build tool but does not deploy artifacts.
7354
use_build_tool = AnalyzeContext("use_build_tool", os.path.abspath("./"), MagicMock())
7455
use_build_tool.dynamic_data["build_spec"]["tool"] = maven_tool
75-
assert build_as_code_check.run_check(use_build_tool, check_result) == CheckResultType.FAILED
56+
assert check.run_check(use_build_tool, check_result) == CheckResultType.FAILED
7657

7758
# The target repo uses Gradle build tool but does not deploy artifacts.
7859
use_build_tool = AnalyzeContext("use_build_tool", os.path.abspath("./"), MagicMock())
7960
use_build_tool.dynamic_data["build_spec"]["tool"] = gradle_tool
80-
assert build_as_code_check.run_check(use_build_tool, check_result) == CheckResultType.FAILED
61+
assert check.run_check(use_build_tool, check_result) == CheckResultType.FAILED
8162

8263
# The target repo uses Poetry build tool but does not deploy artifacts.
8364
use_build_tool = AnalyzeContext("use_build_tool", os.path.abspath("./"), MagicMock())
8465
use_build_tool.dynamic_data["build_spec"]["tool"] = poetry_tool
85-
assert build_as_code_check.run_check(use_build_tool, check_result) == CheckResultType.FAILED
66+
assert check.run_check(use_build_tool, check_result) == CheckResultType.FAILED
8667

8768
# The target repo uses Pip build tool but does not deploy artifacts.
8869
use_build_tool = AnalyzeContext("use_build_tool", os.path.abspath("./"), MagicMock())
8970
use_build_tool.dynamic_data["build_spec"]["tool"] = pip_tool
90-
assert build_as_code_check.run_check(use_build_tool, check_result) == CheckResultType.FAILED
71+
assert check.run_check(use_build_tool, check_result) == CheckResultType.FAILED
9172

9273
# The target repo does not use a build tool.
9374
no_build_tool = AnalyzeContext("no_build_tool", os.path.abspath("./"), MagicMock())
94-
assert build_as_code_check.run_check(no_build_tool, check_result) == CheckResultType.FAILED
75+
assert check.run_check(no_build_tool, check_result) == CheckResultType.FAILED
9576

9677
# Use mvn deploy to deploy the artifact.
9778
maven_deploy = AnalyzeContext("use_build_tool", os.path.abspath("./"), MagicMock())
9879
maven_deploy.dynamic_data["build_spec"]["tool"] = maven_tool
9980
bash_commands["commands"] = [["mvn", "deploy"]]
10081
maven_deploy.dynamic_data["ci_services"] = [ci_info]
101-
assert build_as_code_check.run_check(maven_deploy, check_result) == CheckResultType.PASSED
82+
assert check.run_check(maven_deploy, check_result) == CheckResultType.PASSED
10283

10384
# Use the mvn in the local directory to deploy the artifact.
10485
bash_commands["commands"] = [["./mvn", "deploy"]]
10586
maven_deploy.dynamic_data["ci_services"] = [ci_info]
106-
assert build_as_code_check.run_check(maven_deploy, check_result) == CheckResultType.PASSED
87+
assert check.run_check(maven_deploy, check_result) == CheckResultType.PASSED
10788

10889
# Use an invalid build command that has mvn.
10990
bash_commands["commands"] = [["mvnblah", "deploy"]]
11091
maven_deploy.dynamic_data["ci_services"] = [ci_info]
111-
assert build_as_code_check.run_check(maven_deploy, check_result) == CheckResultType.FAILED
92+
assert check.run_check(maven_deploy, check_result) == CheckResultType.FAILED
11293

11394
# Use mvn but do not deploy artifacts.
11495
no_maven_deploy = AnalyzeContext("use_build_tool", os.path.abspath("./"), MagicMock())
11596
no_maven_deploy.dynamic_data["build_spec"]["tool"] = maven_tool
11697
bash_commands["commands"] = [["mvn", "verify"]]
11798
no_maven_deploy.dynamic_data["ci_services"] = [ci_info]
118-
assert build_as_code_check.run_check(no_maven_deploy, check_result) == CheckResultType.FAILED
99+
assert check.run_check(no_maven_deploy, check_result) == CheckResultType.FAILED
119100

120101
# Use an invalid goal that has deploy keyword.
121102
bash_commands["commands"] = [["mvnb", "deployblah"]]
122103
no_maven_deploy.dynamic_data["ci_services"] = [ci_info]
123-
assert build_as_code_check.run_check(no_maven_deploy, check_result) == CheckResultType.FAILED
104+
assert check.run_check(no_maven_deploy, check_result) == CheckResultType.FAILED
124105

125106
# Use gradle to deploy the artifact.
126107
gradle_deploy = AnalyzeContext("use_build_tool", os.path.abspath("./"), MagicMock())
127108
gradle_deploy.dynamic_data["build_spec"]["tool"] = gradle_tool
128109
bash_commands["commands"] = [["./gradlew", "publishToSonatype"]]
129110
gradle_deploy.dynamic_data["ci_services"] = [ci_info]
130-
assert build_as_code_check.run_check(gradle_deploy, check_result) == CheckResultType.PASSED
111+
assert check.run_check(gradle_deploy, check_result) == CheckResultType.PASSED
131112

132113
# Use poetry publish to publish the artifact.
133114
poetry_publish = AnalyzeContext("use_build_tool", os.path.abspath("./"), MagicMock())
134115
poetry_publish.dynamic_data["build_spec"]["tool"] = poetry_tool
135116
bash_commands["commands"] = [["poetry", "publish"]]
136117
poetry_publish.dynamic_data["ci_services"] = [ci_info]
137-
assert build_as_code_check.run_check(poetry_publish, check_result) == CheckResultType.PASSED
118+
assert check.run_check(poetry_publish, check_result) == CheckResultType.PASSED
138119

139120
# Use Poetry but do not deploy artifacts.
140121
no_poetry_deploy = AnalyzeContext("use_build_tool", os.path.abspath("./"), MagicMock())
141122
no_poetry_deploy.dynamic_data["build_spec"]["tool"] = poetry_tool
142123
bash_commands["commands"] = [["poetry", "upload"]]
143124
no_poetry_deploy.dynamic_data["ci_services"] = [ci_info]
144-
assert build_as_code_check.run_check(no_maven_deploy, check_result) == CheckResultType.FAILED
125+
assert check.run_check(no_maven_deploy, check_result) == CheckResultType.FAILED
145126

146127
# Use twine upload to deploy the artifact.
147128
twine_upload = AnalyzeContext("use_build_tool", os.path.abspath("./"), MagicMock())
148129
twine_upload.dynamic_data["build_spec"]["tool"] = pip_tool
149130
bash_commands["commands"] = [["twine", "upload", "dist/*"]]
150131
twine_upload.dynamic_data["ci_services"] = [ci_info]
151-
assert build_as_code_check.run_check(twine_upload, check_result) == CheckResultType.PASSED
132+
assert check.run_check(twine_upload, check_result) == CheckResultType.PASSED
152133

153134
# Use flit publish to deploy the artifact.
154135
flit_publish = AnalyzeContext("use_build_tool", os.path.abspath("./"), MagicMock())
155136
flit_publish.dynamic_data["build_spec"]["tool"] = pip_tool
156137
bash_commands["commands"] = [["flit", "publish"]]
157138
flit_publish.dynamic_data["ci_services"] = [ci_info]
158-
assert build_as_code_check.run_check(flit_publish, check_result) == CheckResultType.PASSED
139+
assert check.run_check(flit_publish, check_result) == CheckResultType.PASSED
159140

160141
# Test Jenkins.
161142
maven_deploy = AnalyzeContext("use_build_tool", os.path.abspath("./"), MagicMock())
162143
maven_deploy.dynamic_data["build_spec"]["tool"] = maven_tool
163144
ci_info["service"] = jenkins_service
164145
bash_commands["commands"] = []
165146
maven_deploy.dynamic_data["ci_services"] = [ci_info]
166-
assert build_as_code_check.run_check(maven_deploy, check_result) == CheckResultType.FAILED
147+
assert check.run_check(maven_deploy, check_result) == CheckResultType.FAILED
167148

168149
# Test Travis.
169150
maven_deploy = AnalyzeContext("use_build_tool", os.path.abspath("./"), MagicMock())
170151
maven_deploy.dynamic_data["build_spec"]["tool"] = maven_tool
171152
ci_info["service"] = travis_service
172153
bash_commands["commands"] = []
173154
maven_deploy.dynamic_data["ci_services"] = [ci_info]
174-
assert build_as_code_check.run_check(maven_deploy, check_result) == CheckResultType.FAILED
155+
assert check.run_check(maven_deploy, check_result) == CheckResultType.FAILED
175156

176157
# Test Circle CI.
177158
maven_deploy = AnalyzeContext("use_build_tool", os.path.abspath("./"), MagicMock())
178159
maven_deploy.dynamic_data["build_spec"]["tool"] = maven_tool
179160
ci_info["service"] = circle_ci_service
180161
bash_commands["commands"] = []
181162
maven_deploy.dynamic_data["ci_services"] = [ci_info]
182-
assert build_as_code_check.run_check(maven_deploy, check_result) == CheckResultType.FAILED
163+
assert check.run_check(maven_deploy, check_result) == CheckResultType.FAILED
183164

184165
# Test GitLab CI.
185166
maven_deploy = AnalyzeContext("use_build_tool", os.path.abspath("./"), MagicMock())
186167
maven_deploy.dynamic_data["build_spec"]["tool"] = maven_tool
187168
ci_info["service"] = gitlab_ci_service
188169
bash_commands["commands"] = []
189170
maven_deploy.dynamic_data["ci_services"] = [ci_info]
190-
assert build_as_code_check.run_check(maven_deploy, check_result) == CheckResultType.FAILED
171+
assert check.run_check(maven_deploy, check_result) == CheckResultType.FAILED
191172

192173

193174
def test_gha_workflow_deployment(
194-
build_as_code_check: BuildAsCodeCheck, # pylint: disable=redefined-outer-name
195-
check_result: CheckResult,
196175
pip_tool: Pip,
197176
github_actions_service: GitHubActions,
198177
) -> None:
199178
"""Test the use of verified GitHub Actions to deploy."""
179+
check = BuildAsCodeCheck()
180+
check_result = CheckResult(justification=[]) # type: ignore
200181
ci_info = CIInfo(
201182
service=github_actions_service,
202183
bash_commands=[],
@@ -227,4 +208,21 @@ def test_gha_workflow_deployment(
227208
root.add_callee(callee)
228209
github_actions_service.build_call_graph_from_node(callee)
229210
ci_info["callgraph"] = gh_cg
230-
assert build_as_code_check.run_check(gha_deploy, check_result) == CheckResultType.PASSED
211+
assert check.run_check(gha_deploy, check_result) == CheckResultType.PASSED
212+
213+
# This Github Actions workflow is not using a trusted action to publish the artifact.
214+
root = GitHubNode(name="root", node_type=GHWorkflowType.NONE, source_path="", parsed_obj={}, caller_path="")
215+
gh_cg = CallGraph(root, "")
216+
workflow_path = os.path.join(workflows_dir, "pypi_publish_blah.yaml")
217+
parsed_obj = parse_action(workflow_path, macaron_path=str(Path(macaron.MACARON_PATH)))
218+
callee = GitHubNode(
219+
name=os.path.basename(workflow_path),
220+
node_type=GHWorkflowType.INTERNAL,
221+
source_path=workflow_path,
222+
parsed_obj=parsed_obj,
223+
caller_path="",
224+
)
225+
root.add_callee(callee)
226+
github_actions_service.build_call_graph_from_node(callee)
227+
ci_info["callgraph"] = gh_cg
228+
assert check.run_check(gha_deploy, check_result) == CheckResultType.FAILED

0 commit comments

Comments
 (0)