Skip to content

setup.sh: create_dir() does not use sudo on Linux, breaks self-hosted runners where runner user lacks write access to /opt/ #20283

@Rubyj

Description

@Rubyj

Description

The create_dir() helper in actions/setup/setup.sh uses sudo on macOS but performs a plain mkdir -p on Linux:

create_dir() {
  if [[ "$(uname -s)" == "Darwin" ]]; then
    sudo mkdir -p "$1"
    sudo chown -R "$(whoami)" "$1"
  else
    mkdir -p "$1"  # no sudo on Linux
  fi
}

This fails on self-hosted Linux runners where the runner service runs as an unprivileged user (e.g., ec2-user on Amazon Linux 2023) that does not have write access to /opt/.

Error

Copying activation files to /opt/gh-aw/actions
Safe-output custom tokens support: false
mkdir: cannot create directory '/opt/gh-aw': Permission denied

Environment

  • Runner: Self-hosted EC2 (Amazon Linux 2023, ec2-user)
  • Runner user: ec2-user (no write access to /opt/)
  • gh-aw version: v0.53.6
  • Affected jobs: activation, agent, conclusion, safe_outputs — any job that calls github/gh-aw/actions/setup

Why this matters

gh-aw already requires sudo for the AWF firewall step (sudo -E awf ...), so self-hosted runners are expected to have passwordless sudo available. The create_dir() function should be consistent and use sudo on Linux as well, since /opt/ is typically root-owned on standard Linux distributions.

Suggested fix

Try sudo first, fall back to plain mkdir:

create_dir() {
  if sudo mkdir -p "$1" 2>/dev/null && sudo chown -R "$(whoami)" "$1" 2>/dev/null; then
    : # sudo worked
  else
    mkdir -p "$1"  # fall back if sudo is not available
  fi
}

This handles both GitHub-hosted runners (where the runner user already has /opt/ write access) and self-hosted runners that require sudo.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions