Skip to content

Commit 6749705

Browse files
committed
Reapply "feat!: Update output path writing"
This reverts commit f36faa9.
1 parent bea20e5 commit 6749705

File tree

1 file changed

+56
-6
lines changed

1 file changed

+56
-6
lines changed

buildbot_nix/__init__.py

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -784,16 +784,57 @@ def __init__(self, project: GitProject, path: Path, **kwargs: Any) -> None:
784784
self.project = project
785785
self.path = path
786786

787+
def join_traversalsafe(self, root: Path, joined: Path) -> Path:
788+
root = root.resolve()
789+
790+
for part in joined.parts:
791+
new_root = (root / part).resolve()
792+
793+
if not new_root.is_relative_to(root):
794+
msg = f"Joined path attempted to traverse upwards when processing {root} against {part} (gave {new_root})"
795+
raise ValueError(msg)
796+
797+
root = new_root
798+
799+
return root
800+
801+
def join_all_traversalsafe(self, root: Path, *paths: Path) -> Path:
802+
for path in paths:
803+
root = self.join_traversalsafe(root, path)
804+
805+
return root
806+
807+
@defer.inlineCallbacks
787808
def run(self) -> Generator[Any, object, Any]:
788809
props = self.build.getProperties()
789-
if props.getProperty("branch") != self.project.default_branch:
810+
811+
pr = props.getProperty("pr_number")
812+
813+
if not pr and props.getProperty("branch") != self.project.default_branch:
790814
return util.SKIPPED
791815

792-
attr = Path(props.getProperty("attr")).name
793816
out_path = props.getProperty("out_path")
794-
# XXX don't hardcode this
795-
self.path.mkdir(parents=True, exist_ok=True)
796-
(self.path / attr).write_text(out_path)
817+
818+
if not out_path: # if, e.g., the build fails and doesn't produce an output
819+
return util.SKIPPED
820+
821+
project_name = Path(props.getProperty("projectname"))
822+
823+
target = Path(f"pulls/{pr}") if pr else Path(props.getProperty("branch"))
824+
825+
attr = Path(props.getProperty("attr"))
826+
827+
try:
828+
file = self.join_all_traversalsafe(self.path, project_name, target, attr)
829+
except ValueError as e:
830+
error_log: StreamLog = yield self.addLog("path_error")
831+
error_log.addStderr(f"Path traversal prevented ... skipping update: {e}")
832+
return util.FAILURE
833+
834+
file.parent.mkdir(parents=True, exist_ok=True)
835+
836+
file.write_text(out_path)
837+
797838
return util.SUCCESS
798839

799840

@@ -1104,6 +1145,7 @@ def nix_cached_failure_config(
11041145
def nix_skipped_build_config(
11051146
project: GitProject,
11061147
worker_names: list[str],
1148+
outputs_path: Path | None = None,
11071149
) -> BuilderConfig:
11081150
"""Dummy builder that is triggered when a build is skipped."""
11091151
factory = util.BuildFactory()
@@ -1132,6 +1174,14 @@ def nix_skipped_build_config(
11321174
set_properties={"report_status": False},
11331175
),
11341176
)
1177+
if outputs_path is not None:
1178+
factory.addStep(
1179+
UpdateBuildOutput(
1180+
project=project,
1181+
name="Update build output",
1182+
path=outputs_path,
1183+
),
1184+
)
11351185
return util.BuilderConfig(
11361186
name=f"{project.name}/nix-skipped-build",
11371187
project=project.name,
@@ -1282,7 +1332,7 @@ def config_for_project(
12821332
outputs_path=outputs_path,
12831333
post_build_steps=post_build_steps,
12841334
),
1285-
nix_skipped_build_config(project, [SKIPPED_BUILDER_NAME]),
1335+
nix_skipped_build_config(project, [SKIPPED_BUILDER_NAME], outputs_path),
12861336
nix_failed_eval_config(project, [SKIPPED_BUILDER_NAME]),
12871337
nix_dependency_failed_config(project, [SKIPPED_BUILDER_NAME]),
12881338
nix_cached_failure_config(project, [SKIPPED_BUILDER_NAME]),

0 commit comments

Comments
 (0)