Skip to content

Commit e54709a

Browse files
committed
feedback
1 parent e79528a commit e54709a

3 files changed

Lines changed: 38 additions & 26 deletions

File tree

.github/workflows/check-rendered-specs.yml

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,25 +74,31 @@ jobs:
7474
run: |
7575
docker build \
7676
--build-arg UID=$(id -u) \
77-
-t azldev-render \
77+
-t localhost/azldev-render \
7878
-f .github/workflows/containers/render.Dockerfile \
7979
.github/workflows/containers/
8080
81-
# Render runs inside a privileged container because mock needs mount
82-
# namespaces. Only the PR checkout is mounted (not the full workspace) —
83-
# this prevents a malicious spec's %() macro from writing to the trusted
84-
# base checkout where our scripts live. The azldev binary is mounted
85-
# read-only from the host's GOPATH.
81+
# Render runs inside a container with SYS_ADMIN capability because mock
82+
# needs mount namespaces for chroot operations. We avoid --privileged to
83+
# limit the blast radius if a malicious spec's %() macro achieves code
84+
# execution inside the container. Only the PR checkout is mounted (not
85+
# the full workspace) — the trusted base checkout where our scripts live
86+
# is not accessible. The azldev binary is mounted read-only.
87+
#
88+
# NOTE: --security-opt no-new-privileges would be ideal but mock's
89+
# userhelper requires setuid, which that flag blocks.
8690
- name: Render specs
8791
env:
8892
WORKSPACE: ${{ github.workspace }}
8993
run: |
9094
set -o pipefail
91-
docker run --privileged --rm \
95+
docker run --rm \
96+
--cap-add=SYS_ADMIN \
97+
--security-opt seccomp=unconfined \
9298
-v "$WORKSPACE/pr-head:/workdir" \
9399
-v "$(go env GOPATH)/bin:/gobin:ro" \
94100
-e PATH="/gobin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" \
95-
azldev-render \
101+
localhost/azldev-render \
96102
azldev component render -q -a --clean-stale -O json \
97103
| tee render-output.json
98104

.github/workflows/scripts/check_rendered_specs.py

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@
2020
import argparse
2121
import difflib
2222
import json
23+
import os
2324
import re
2425
import subprocess
2526
import sys
27+
import tempfile
2628
from pathlib import Path
2729

2830
# ---------------------------------------------------------------------------
@@ -203,9 +205,10 @@ def _unique_components(items: list[dict]) -> list[str]:
203205
return out
204206

205207

208+
# NOTE: _unique_components and _render_command are duplicated in post_render_comment.py
206209
def _render_command(components: list[str], use_all: bool = False) -> str:
207210
if use_all or len(components) > 30:
208-
return "azldev component render -a"
211+
return "azldev component render -a --clean-stale"
209212
return f"azldev component render {' '.join(components)}"
210213

211214

@@ -225,51 +228,53 @@ def generate_patch(
225228
if not paths:
226229
return b""
227230

228-
# Write paths to a file to avoid ARG_MAX limits
229-
pathspec_file = Path("render-check-pathspec.txt")
230-
pathspec_file.write_text("\n".join(paths), encoding="utf-8")
231+
# Write paths to temp files outside CWD (which may be an untrusted
232+
# PR checkout where symlinks could redirect writes).
233+
pathspec_fd, pathspec_path = tempfile.mkstemp(prefix="render-check-", suffix=".txt")
234+
with os.fdopen(pathspec_fd, "w") as f:
235+
f.write("\n".join(paths))
231236

232237
# Mark untracked files as intent-to-add so git diff includes them
238+
extra_pathspec_path = None
233239
if extra_files:
234-
extra_pathspec = Path("render-check-extra-pathspec.txt")
235-
extra_pathspec.write_text("\n".join(extra_files), encoding="utf-8")
240+
extra_fd, extra_pathspec_path = tempfile.mkstemp(
241+
prefix="render-check-extra-", suffix=".txt"
242+
)
243+
with os.fdopen(extra_fd, "w") as f:
244+
f.write("\n".join(extra_files))
236245
try:
237246
subprocess.run(
238-
["git", "add", "-N", "--pathspec-from-file", str(extra_pathspec)],
247+
["git", "add", "-N", "--pathspec-from-file", extra_pathspec_path],
239248
check=True,
240249
capture_output=True,
241250
)
242251
except subprocess.CalledProcessError:
243252
pass
244-
finally:
245-
extra_pathspec.unlink(missing_ok=True)
246253

247254
try:
248255
result = subprocess.run(
249-
["git", "diff", "--pathspec-from-file", str(pathspec_file)],
256+
["git", "diff", "--pathspec-from-file", pathspec_path],
250257
capture_output=True,
251258
check=True,
252259
)
253260
patch = result.stdout
254261
except subprocess.CalledProcessError:
255262
patch = b""
256263
finally:
257-
pathspec_file.unlink(missing_ok=True)
264+
Path(pathspec_path).unlink(missing_ok=True)
258265

259266
# Undo the intent-to-add so we don't leave index dirty
260-
if extra_files:
261-
extra_pathspec = Path("render-check-extra-pathspec.txt")
262-
extra_pathspec.write_text("\n".join(extra_files), encoding="utf-8")
267+
if extra_pathspec_path:
263268
try:
264269
subprocess.run(
265-
["git", "reset", "--pathspec-from-file", str(extra_pathspec)],
270+
["git", "reset", "--pathspec-from-file", extra_pathspec_path],
266271
check=True,
267272
capture_output=True,
268273
)
269274
except subprocess.CalledProcessError:
270275
pass
271276
finally:
272-
extra_pathspec.unlink(missing_ok=True)
277+
Path(extra_pathspec_path).unlink(missing_ok=True)
273278

274279
return patch
275280

.github/workflows/scripts/post_render_comment.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,10 @@ def _unique_components(items: list[dict]) -> list[str]:
5757
return out
5858

5959

60+
# NOTE: _unique_components and _render_command are duplicated in check_rendered_specs.py
6061
def _render_command(components: list[str], use_all: bool = False) -> str:
6162
if use_all or len(components) > 30:
62-
return "azldev component render -a"
63+
return "azldev component render -a --clean-stale"
6364
return f"azldev component render {' '.join(components)}"
6465

6566

@@ -84,7 +85,7 @@ def format_comment(
8485
all_comps: list[str] = sorted(
8586
set(_unique_components(content_diffs) + _unique_components(missing_files))
8687
)
87-
use_all = bool(extra_files)
88+
use_all = bool(extra_files) or bool(missing_files)
8889
remediation_cmd = _render_command([] if use_all else all_comps, use_all=use_all)
8990

9091
lines: list[str] = [

0 commit comments

Comments
 (0)