From 806931fc5e0c14e9410b67f615d28aa0f681c979 Mon Sep 17 00:00:00 2001 From: wenshao Date: Wed, 29 Jul 2026 00:42:51 +0800 Subject: [PATCH] fix(ci): give each job its own proxy wrapper directory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PR review job and the containerised triage jobs all built their gh/git proxy wrappers in one fixed directory under RUNNER_TEMP. On the shared self-hosted runner that path outlives a job, and the triage containers write it as root through the RUNNER_TEMP bind mount. Once that happened, the review job — running as the unprivileged runner user — could neither overwrite the wrapper nor remove the root-owned directory holding it, so every review scheduled on that runner died with EACCES while writing the wrapper, before the review itself had started. Each run now creates a private wrapper directory and removes it on exit, and the container jobs keep theirs on the container's own disk so they stop leaving root-owned state on the host. --- .github/workflows/qwen-code-pr-review.yml | 16 +++++++++++++--- .github/workflows/qwen-triage.yml | 18 ++++++++++++++---- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/.github/workflows/qwen-code-pr-review.yml b/.github/workflows/qwen-code-pr-review.yml index 5adefcac6a5..2d0950834b7 100644 --- a/.github/workflows/qwen-code-pr-review.yml +++ b/.github/workflows/qwen-code-pr-review.yml @@ -500,7 +500,9 @@ jobs: REPO="${GITHUB_REPOSITORY}" REVIEW_URL="${GITHUB_SERVER_URL}/${REPO}/pull/${PR_NUMBER}" LOG_PATH="${RUNNER_TEMP:-/tmp}/qwen-review-pr-${PR_NUMBER}.jsonl" - trap 'rm -f "$LOG_PATH"' EXIT + # Set by configure_qwen_network once the wrapper dir exists. + PROXY_BIN="" + trap 'rm -f "$LOG_PATH"; [ -z "$PROXY_BIN" ] || rm -rf "$PROXY_BIN"' EXIT if [ -z "${GH_TOKEN:-}" ]; then fail "CI_BOT_PAT secret is required for Qwen PR review." @@ -535,8 +537,16 @@ jobs: export QWEN_CI_https_proxy="${https_proxy:-}" export QWEN_CI_HTTP_PROXY="${HTTP_PROXY:-}" export QWEN_CI_http_proxy="${http_proxy:-}" - proxy_bin="${RUNNER_TEMP:-/tmp}/qwen-network-bin" - mkdir -p "$proxy_bin" + # A fixed path is a landmine on the shared self-hosted runner: + # RUNNER_TEMP survives across jobs, and the triage workflow's + # containerised jobs write this same path as root through the + # RUNNER_TEMP bind mount. This job runs as the unprivileged runner + # user, so once that happens it can neither overwrite the wrapper + # nor remove the root-owned directory holding it, and every review + # landing on that runner dies here with EACCES. Use a private + # directory per run, cleaned up by the EXIT trap. + proxy_bin="$(mktemp -d "${RUNNER_TEMP:-/tmp}/qwen-network-bin.XXXXXX")" + PROXY_BIN="$proxy_bin" if command -v gh >/dev/null 2>&1; then local real_gh diff --git a/.github/workflows/qwen-triage.yml b/.github/workflows/qwen-triage.yml index 8b29da3ed80..c291604fe79 100644 --- a/.github/workflows/qwen-triage.yml +++ b/.github/workflows/qwen-triage.yml @@ -1162,8 +1162,13 @@ jobs: export QWEN_CI_https_proxy="${https_proxy:-}" export QWEN_CI_HTTP_PROXY="${HTTP_PROXY:-}" export QWEN_CI_http_proxy="${http_proxy:-}" - proxy_bin="${RUNNER_TEMP:-/tmp}/qwen-network-bin" - mkdir -p "$proxy_bin" + # This job runs in a container, and RUNNER_TEMP is bind-mounted + # from the self-hosted runner's host filesystem. Writing the + # wrappers there leaves root-owned files on the host that later + # non-container jobs (the PR review) can neither overwrite nor + # delete, breaking every review scheduled on that runner. Keep + # them on the container's own disk, under a per-run directory. + proxy_bin="$(mktemp -d /tmp/qwen-network-bin.XXXXXX)" if command -v gh >/dev/null 2>&1; then local real_gh @@ -2415,8 +2420,13 @@ jobs: export QWEN_CI_https_proxy="${https_proxy:-}" export QWEN_CI_HTTP_PROXY="${HTTP_PROXY:-}" export QWEN_CI_http_proxy="${http_proxy:-}" - proxy_bin="${RUNNER_TEMP:-/tmp}/qwen-network-bin" - mkdir -p "$proxy_bin" + # This job runs in a container, and RUNNER_TEMP is bind-mounted + # from the self-hosted runner's host filesystem. Writing the + # wrappers there leaves root-owned files on the host that later + # non-container jobs (the PR review) can neither overwrite nor + # delete, breaking every review scheduled on that runner. Keep + # them on the container's own disk, under a per-run directory. + proxy_bin="$(mktemp -d /tmp/qwen-network-bin.XXXXXX)" if command -v gh >/dev/null 2>&1; then local real_gh