Skip to content

Cleanup step fails on self-hosted runners (sudo password prompt), root cause is upstream #113

Description

@ancient-cthulhu

On self-hosted Linux runners, the cleanup step in veracode-clean-up.yml fails because sudo prompts for a password in a non-interactive job:

Sorry, try again.
sudo: 2 incorrect password attempts
Process completed with exit code 1
- name: Cleanup workspace and Docker - Linux
  if: contains(runner.os, 'Linux')
  run: |
    echo "Running final cleanup..."
    sudo rm -rf $GITHUB_WORKSPACE/*

Root cause is upstream of this step: build-linux in veracode-default-build.yml runs inside container: image: ${{ inputs.build_packager_image }}. Container jobs default to root, so everything written into the mounted $GITHUB_WORKSPACE is root-owned on the host. On GitHub-hosted runners this doesn't matter, the VM is destroyed after the job. On self-hosted runners the workspace persists, so every build poisons it, and the next run's cleanup (which runs first in most of our workflows) can't remove root-owned files without elevated privileges. That's why sudo was there. We don't want passwordless sudo, so replacing the sudo call alone just turns a password prompt into a silent Permission denied on every run.

Fix (two files)

veracode-default-build.yml, add a final step to build-linux to hand ownership back before the container exits:

- name: Restore workspace ownership
  if: always()
  shell: bash
  run: |
    if [ "$(id -u)" != "0" ]; then
      echo "Not running as root; skipping ownership restore."
      exit 0
    fi
    ref="$GITHUB_WORKSPACE"
    if [ "$(stat -c %u "$ref")" = "0" ]; then
      ref="$(dirname "$GITHUB_WORKSPACE")"
    fi
    owner="$(stat -c '%u:%g' "$ref")"
    echo "Restoring workspace ownership to $owner"
    chown -R "$owner" "$GITHUB_WORKSPACE"

Runs as root inside the container, so no sudo needed. Derives the runner's UID/GID from the workspace itself instead of hardcoding one, and no-ops on non-root images.

veracode-clean-up.yml, replace the sudo call with a non-interactive find, plus a guard clause and a check that the workspace is actually empty afterward:

- name: Cleanup workspace - Linux
  if: always() && contains(runner.os, 'Linux')
  shell: bash
  run: |
    set -euo pipefail
    echo "Workspace to clean: ${GITHUB_WORKSPACE:-<unset>}"

    if [ -z "${GITHUB_WORKSPACE:-}" ] || [ "$GITHUB_WORKSPACE" = "/" ]; then
      echo "::error::GITHUB_WORKSPACE is unset or unsafe ('${GITHUB_WORKSPACE:-}'). Aborting cleanup."
      exit 1
    fi

    find "$GITHUB_WORKSPACE" -mindepth 1 -maxdepth 1 \
      -exec rm -rf --one-file-system -- {} +

    remaining=$(find "$GITHUB_WORKSPACE" -mindepth 1 -maxdepth 1 -print -quit)
    if [ -n "$remaining" ]; then
      echo "::error::Workspace not empty after cleanup: $remaining"
      exit 1
    fi

    echo "Workspace clean."

Note: the old $GITHUB_WORKSPACE/* glob never matched dotfiles either, so hidden files/dirs were surviving cleanup regardless of the sudo issue. Fixed as a side effect.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions