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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions