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.
On self-hosted Linux runners, the cleanup step in
veracode-clean-up.ymlfails becausesudoprompts for a password in a non-interactive job:Root cause is upstream of this step:
build-linuxinveracode-default-build.ymlruns insidecontainer: image: ${{ inputs.build_packager_image }}. Container jobs default to root, so everything written into the mounted$GITHUB_WORKSPACEis 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 silentPermission deniedon every run.Fix (two files)
veracode-default-build.yml, add a final step tobuild-linuxto hand ownership back before the container exits: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-interactivefind, plus a guard clause and a check that the workspace is actually empty afterward: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.