From 566d6bdc6d49b0fbd56b0200e17e14aab7312793 Mon Sep 17 00:00:00 2001 From: robert lestak Date: Tue, 16 Dec 2025 09:27:02 -0800 Subject: [PATCH 1/2] feat: add build logs to stdout forwarding Add optional feature to forward GitHub Actions build logs to pod stdout after job completion, enabling capture through Kubernetes logging solutions. Changes: - Add logForwarding.enabled config option (default: false) - Create forward-logs.sh script to output worker logs with delimiters - Integrate with job-completed hook system - Update all Dockerfile variants to include script - Modify Helm templates to pass FORWARD_BUILD_LOGS env var - Support all container modes (default, dind, kubernetes, kubernetes-novolume) Resolves #2478 --- .../templates/_helpers.tpl | 18 ++++++++++- charts/gha-runner-scale-set/values.yaml | 6 ++++ ...nner-dind-rootless.ubuntu-20.04.dockerfile | 2 +- ...nner-dind-rootless.ubuntu-22.04.dockerfile | 2 +- ...nner-dind-rootless.ubuntu-24.04.dockerfile | 2 +- ...ctions-runner-dind.ubuntu-20.04.dockerfile | 2 +- ...ctions-runner-dind.ubuntu-22.04.dockerfile | 2 +- ...ctions-runner-dind.ubuntu-24.04.dockerfile | 2 +- runner/actions-runner.ubuntu-20.04.dockerfile | 2 +- runner/actions-runner.ubuntu-22.04.dockerfile | 2 +- runner/actions-runner.ubuntu-24.04.dockerfile | 2 +- runner/forward-logs.sh | 32 +++++++++++++++++++ runner/hooks/job-completed.d/forward-logs | 4 +++ 13 files changed, 68 insertions(+), 10 deletions(-) create mode 100755 runner/forward-logs.sh create mode 100755 runner/hooks/job-completed.d/forward-logs diff --git a/charts/gha-runner-scale-set/templates/_helpers.tpl b/charts/gha-runner-scale-set/templates/_helpers.tpl index 9dfb615f..67e209c5 100644 --- a/charts/gha-runner-scale-set/templates/_helpers.tpl +++ b/charts/gha-runner-scale-set/templates/_helpers.tpl @@ -240,6 +240,10 @@ env: - name: RUNNER_WAIT_FOR_DOCKER_IN_SECONDS value: "120" {{- end }} + {{- if $.Values.logForwarding.enabled }} + - name: FORWARD_BUILD_LOGS + value: "true" + {{- end }} {{- if $setNodeExtraCaCerts }} - name: NODE_EXTRA_CA_CERTS value: {{ clean (print $tlsConfig.runnerMountPath "/" $tlsConfig.certificateFrom.configMapKeyRef.key) }} @@ -337,6 +341,10 @@ env: {{- end }} {{- if $setRequireJobContainer }} - name: ACTIONS_RUNNER_REQUIRE_JOB_CONTAINER + value: "true" + {{- end }} + {{- if $.Values.logForwarding.enabled }} + - name: FORWARD_BUILD_LOGS value: "true" {{- end }} {{- if $setNodeExtraCaCerts }} @@ -442,6 +450,10 @@ env: - name: ACTIONS_RUNNER_IMAGE value: "{{- $setRunnerImage -}}" {{- end }} + {{- if $.Values.logForwarding.enabled }} + - name: FORWARD_BUILD_LOGS + value: "true" + {{- end }} {{- if $setNodeExtraCaCerts }} - name: NODE_EXTRA_CA_CERTS value: {{ clean (print $tlsConfig.runnerMountPath "/" $tlsConfig.certificateFrom.configMapKeyRef.key) }} @@ -492,7 +504,7 @@ volumeMounts: {{- end }} {{- $mountGitHubServerTLS := 0 }} - {{- if or $container.env $setNodeExtraCaCerts $setRunnerUpdateCaCerts }} + {{- if or $container.env $setNodeExtraCaCerts $setRunnerUpdateCaCerts $.Values.logForwarding.enabled }} env: {{- with $container.env }} {{- range $i, $env := . }} @@ -505,6 +517,10 @@ volumeMounts: - {{ $env | toYaml | nindent 6 }} {{- end }} {{- end }} + {{- if $.Values.logForwarding.enabled }} + - name: FORWARD_BUILD_LOGS + value: "true" + {{- end }} {{- if $setNodeExtraCaCerts }} - name: NODE_EXTRA_CA_CERTS value: {{ clean (print $tlsConfig.runnerMountPath "/" $tlsConfig.certificateFrom.configMapKeyRef.key) }} diff --git a/charts/gha-runner-scale-set/values.yaml b/charts/gha-runner-scale-set/values.yaml index 8a9b64e9..e2d67c79 100644 --- a/charts/gha-runner-scale-set/values.yaml +++ b/charts/gha-runner-scale-set/values.yaml @@ -13,6 +13,12 @@ githubConfigSecret: # Example: # github_token: "ghp_sampleSampleSampleSampleSampleSample" github_token: "" + +## logForwarding controls whether GitHub Actions build logs are forwarded to stdout +## When enabled, job execution logs will be output to the pod's stdout after job completion +## This allows capturing build logs through Kubernetes logging solutions +logForwarding: + enabled: false # ## (Variation B) When using a GitHub App, the syntax is as follows: # githubConfigSecret: diff --git a/runner/actions-runner-dind-rootless.ubuntu-20.04.dockerfile b/runner/actions-runner-dind-rootless.ubuntu-20.04.dockerfile index f902043f..eba9b65b 100644 --- a/runner/actions-runner-dind-rootless.ubuntu-20.04.dockerfile +++ b/runner/actions-runner-dind-rootless.ubuntu-20.04.dockerfile @@ -110,7 +110,7 @@ RUN mkdir /run/user/$RUNNER_UID \ # We place the scripts in `/usr/bin` so that users who extend this image can # override them with scripts of the same name placed in `/usr/local/bin`. -COPY entrypoint-dind-rootless.sh startup.sh logger.sh graceful-stop.sh update-status /usr/bin/ +COPY entrypoint-dind-rootless.sh startup.sh logger.sh graceful-stop.sh update-status forward-logs.sh /usr/bin/ RUN chmod +x /usr/bin/entrypoint-dind-rootless.sh /usr/bin/startup.sh # Copy the docker shim which propagates the docker MTU to underlying networks diff --git a/runner/actions-runner-dind-rootless.ubuntu-22.04.dockerfile b/runner/actions-runner-dind-rootless.ubuntu-22.04.dockerfile index ef769b63..bb55687b 100644 --- a/runner/actions-runner-dind-rootless.ubuntu-22.04.dockerfile +++ b/runner/actions-runner-dind-rootless.ubuntu-22.04.dockerfile @@ -88,7 +88,7 @@ RUN mkdir /run/user/1000 \ # We place the scripts in `/usr/bin` so that users who extend this image can # override them with scripts of the same name placed in `/usr/local/bin`. -COPY entrypoint-dind-rootless.sh startup.sh logger.sh graceful-stop.sh update-status /usr/bin/ +COPY entrypoint-dind-rootless.sh startup.sh logger.sh graceful-stop.sh update-status forward-logs.sh /usr/bin/ RUN chmod +x /usr/bin/entrypoint-dind-rootless.sh /usr/bin/startup.sh # Copy the docker shim which propagates the docker MTU to underlying networks diff --git a/runner/actions-runner-dind-rootless.ubuntu-24.04.dockerfile b/runner/actions-runner-dind-rootless.ubuntu-24.04.dockerfile index 2a81b145..512ffbab 100644 --- a/runner/actions-runner-dind-rootless.ubuntu-24.04.dockerfile +++ b/runner/actions-runner-dind-rootless.ubuntu-24.04.dockerfile @@ -88,7 +88,7 @@ RUN mkdir /run/user/1000 \ # We place the scripts in `/usr/bin` so that users who extend this image can # override them with scripts of the same name placed in `/usr/local/bin`. -COPY entrypoint-dind-rootless.sh startup.sh logger.sh graceful-stop.sh update-status /usr/bin/ +COPY entrypoint-dind-rootless.sh startup.sh logger.sh graceful-stop.sh update-status forward-logs.sh /usr/bin/ RUN chmod +x /usr/bin/entrypoint-dind-rootless.sh /usr/bin/startup.sh # Copy the docker shim which propagates the docker MTU to underlying networks diff --git a/runner/actions-runner-dind.ubuntu-20.04.dockerfile b/runner/actions-runner-dind.ubuntu-20.04.dockerfile index 7c590ffc..45722cfc 100644 --- a/runner/actions-runner-dind.ubuntu-20.04.dockerfile +++ b/runner/actions-runner-dind.ubuntu-20.04.dockerfile @@ -118,7 +118,7 @@ RUN export ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \ # We place the scripts in `/usr/bin` so that users who extend this image can # override them with scripts of the same name placed in `/usr/local/bin`. -COPY entrypoint-dind.sh startup.sh logger.sh wait.sh graceful-stop.sh update-status /usr/bin/ +COPY entrypoint-dind.sh startup.sh logger.sh wait.sh graceful-stop.sh update-status forward-logs.sh /usr/bin/ RUN chmod +x /usr/bin/entrypoint-dind.sh /usr/bin/startup.sh # Copy the docker shim which propagates the docker MTU to underlying networks diff --git a/runner/actions-runner-dind.ubuntu-22.04.dockerfile b/runner/actions-runner-dind.ubuntu-22.04.dockerfile index 3a5a508b..527a2a12 100644 --- a/runner/actions-runner-dind.ubuntu-22.04.dockerfile +++ b/runner/actions-runner-dind.ubuntu-22.04.dockerfile @@ -94,7 +94,7 @@ RUN export ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \ # We place the scripts in `/usr/bin` so that users who extend this image can # override them with scripts of the same name placed in `/usr/local/bin`. -COPY entrypoint-dind.sh startup.sh logger.sh wait.sh graceful-stop.sh update-status /usr/bin/ +COPY entrypoint-dind.sh startup.sh logger.sh wait.sh graceful-stop.sh update-status forward-logs.sh /usr/bin/ RUN chmod +x /usr/bin/entrypoint-dind.sh /usr/bin/startup.sh # Copy the docker shim which propagates the docker MTU to underlying networks diff --git a/runner/actions-runner-dind.ubuntu-24.04.dockerfile b/runner/actions-runner-dind.ubuntu-24.04.dockerfile index a9ca2b51..8f766dd8 100644 --- a/runner/actions-runner-dind.ubuntu-24.04.dockerfile +++ b/runner/actions-runner-dind.ubuntu-24.04.dockerfile @@ -94,7 +94,7 @@ RUN export ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \ # We place the scripts in `/usr/bin` so that users who extend this image can # override them with scripts of the same name placed in `/usr/local/bin`. -COPY entrypoint-dind.sh startup.sh logger.sh wait.sh graceful-stop.sh update-status /usr/bin/ +COPY entrypoint-dind.sh startup.sh logger.sh wait.sh graceful-stop.sh update-status forward-logs.sh /usr/bin/ RUN chmod +x /usr/bin/entrypoint-dind.sh /usr/bin/startup.sh # Copy the docker shim which propagates the docker MTU to underlying networks diff --git a/runner/actions-runner.ubuntu-20.04.dockerfile b/runner/actions-runner.ubuntu-20.04.dockerfile index 901ce75d..e6178e7f 100644 --- a/runner/actions-runner.ubuntu-20.04.dockerfile +++ b/runner/actions-runner.ubuntu-20.04.dockerfile @@ -115,7 +115,7 @@ RUN export ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \ # We place the scripts in `/usr/bin` so that users who extend this image can # override them with scripts of the same name placed in `/usr/local/bin`. -COPY entrypoint.sh startup.sh logger.sh graceful-stop.sh update-status /usr/bin/ +COPY entrypoint.sh startup.sh logger.sh graceful-stop.sh update-status forward-logs.sh /usr/bin/ # Copy the docker shim which propagates the docker MTU to underlying networks # to replace the docker binary in the PATH. diff --git a/runner/actions-runner.ubuntu-22.04.dockerfile b/runner/actions-runner.ubuntu-22.04.dockerfile index d2989504..ca1b37ce 100644 --- a/runner/actions-runner.ubuntu-22.04.dockerfile +++ b/runner/actions-runner.ubuntu-22.04.dockerfile @@ -92,7 +92,7 @@ RUN export ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \ # We place the scripts in `/usr/bin` so that users who extend this image can # override them with scripts of the same name placed in `/usr/local/bin`. -COPY entrypoint.sh startup.sh logger.sh graceful-stop.sh update-status /usr/bin/ +COPY entrypoint.sh startup.sh logger.sh graceful-stop.sh update-status forward-logs.sh /usr/bin/ # Copy the docker shim which propagates the docker MTU to underlying networks # to replace the docker binary in the PATH. diff --git a/runner/actions-runner.ubuntu-24.04.dockerfile b/runner/actions-runner.ubuntu-24.04.dockerfile index 90bffa79..b1f6408b 100644 --- a/runner/actions-runner.ubuntu-24.04.dockerfile +++ b/runner/actions-runner.ubuntu-24.04.dockerfile @@ -92,7 +92,7 @@ RUN export ARCH=$(echo ${TARGETPLATFORM} | cut -d / -f2) \ # We place the scripts in `/usr/bin` so that users who extend this image can # override them with scripts of the same name placed in `/usr/local/bin`. -COPY entrypoint.sh startup.sh logger.sh graceful-stop.sh update-status /usr/bin/ +COPY entrypoint.sh startup.sh logger.sh graceful-stop.sh update-status forward-logs.sh /usr/bin/ # Copy the docker shim which propagates the docker MTU to underlying networks # to replace the docker binary in the PATH. diff --git a/runner/forward-logs.sh b/runner/forward-logs.sh new file mode 100755 index 00000000..054ecbae --- /dev/null +++ b/runner/forward-logs.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Forward GitHub Actions build logs to stdout +# This script finds and outputs worker log files that contain job execution logs + +if [ "${FORWARD_BUILD_LOGS:-false}" != "true" ]; then + exit 0 +fi + +RUNNER_HOME=${RUNNER_HOME:-/runner} +DIAG_DIR="${RUNNER_HOME}/_diag/pages" + +if [ ! -d "$DIAG_DIR" ]; then + echo "No diagnostic logs directory found at $DIAG_DIR" + exit 0 +fi + +# Find worker log files (these contain the actual job execution logs) +WORKER_LOGS=$(find "$DIAG_DIR" -name "Worker_*.log" -type f 2>/dev/null || true) + +if [ -z "$WORKER_LOGS" ]; then + echo "No worker log files found" + exit 0 +fi + +echo "=== GITHUB ACTIONS BUILD LOGS START ===" +for log_file in $WORKER_LOGS; do + echo "--- Log from: $(basename "$log_file") ---" + cat "$log_file" +done +echo "=== GITHUB ACTIONS BUILD LOGS END ===" diff --git a/runner/hooks/job-completed.d/forward-logs b/runner/hooks/job-completed.d/forward-logs new file mode 100755 index 00000000..18c1164c --- /dev/null +++ b/runner/hooks/job-completed.d/forward-logs @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -u + +exec forward-logs.sh From fac29b778d61037a314de2fef107a728e045af15 Mon Sep 17 00:00:00 2001 From: robert lestak Date: Tue, 16 Dec 2025 13:58:01 -0800 Subject: [PATCH 2/2] fix: address copilot review feedback - Fix shell scripting issue with unquoted variables in forward-logs.sh - Add error handling to hook script before executing forward-logs.sh - Use null-terminated while loop to handle filenames with spaces --- runner/forward-logs.sh | 15 +++++++-------- runner/hooks/job-completed.d/forward-logs | 7 ++++++- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/runner/forward-logs.sh b/runner/forward-logs.sh index 054ecbae..1cd4739f 100755 --- a/runner/forward-logs.sh +++ b/runner/forward-logs.sh @@ -17,16 +17,15 @@ if [ ! -d "$DIAG_DIR" ]; then fi # Find worker log files (these contain the actual job execution logs) -WORKER_LOGS=$(find "$DIAG_DIR" -name "Worker_*.log" -type f 2>/dev/null || true) - -if [ -z "$WORKER_LOGS" ]; then - echo "No worker log files found" - exit 0 -fi - echo "=== GITHUB ACTIONS BUILD LOGS START ===" -for log_file in $WORKER_LOGS; do +found_logs=0 +find "$DIAG_DIR" -name "Worker_*.log" -type f -print0 2>/dev/null | while IFS= read -r -d '' log_file; do + found_logs=1 echo "--- Log from: $(basename "$log_file") ---" cat "$log_file" done + +if [ "$found_logs" -eq 0 ]; then + echo "No worker log files found" +fi echo "=== GITHUB ACTIONS BUILD LOGS END ===" diff --git a/runner/hooks/job-completed.d/forward-logs b/runner/hooks/job-completed.d/forward-logs index 18c1164c..e4a6a2c5 100755 --- a/runner/hooks/job-completed.d/forward-logs +++ b/runner/hooks/job-completed.d/forward-logs @@ -1,4 +1,9 @@ #!/usr/bin/env bash set -u -exec forward-logs.sh +if command -v forward-logs.sh >/dev/null 2>&1; then + exec forward-logs.sh +else + echo "forward-logs.sh not found in PATH" + exit 1 +fi