Skip to content

actions/checkout@v6 broken on non-GitHub runners (Forgejo, Gitea, etc.) - hardcoded GitHub paths in includeIf directives break authentication #2321

@nrdufour

Description

@nrdufour

Problem

actions/checkout@v6 is incompatible with self-hosted runners on non-GitHub platforms (Forgejo, Gitea, GitLab CI, etc.). Git authentication fails because v6 uses hardcoded GitHub Actions runner paths in its includeIf.gitdir directives. When these paths don't exist, git cannot find credentials and falls back to interactive username/password prompts, causing workflows to hang and timeout.

Root Cause

PR #2286 ("Persist creds to a separate file") replaced v4/v5's universal HTTP Authorization header approach with a path-dependent includeIf.gitdir mechanism that only works on GitHub Actions:

v4/v5 (working everywhere):
[http.https://forge.internal/.extraheader]
AUTHORIZATION: basic

v6 (broken on non-GitHub runners):
[includeIf "gitdir:/github/workspace/.git"]
path = /github/runner_temp/git-credentials-.config
[includeIf "gitdir:/var/lib/gitea-runner/first/action-cache-dir/.../hostexecutor/.git"]
path = /var/lib/gitea-runner/.../tmp/git-credentials-.config

The hardcoded /github/workspace/ and /github/runner_temp/ paths are only meaningful on GitHub Actions. When git tries to find matching credentials on Forgejo (or any other self-hosted runner), the includeIf directives don't match because:

  1. The repository isn't located at /github/workspace/
  2. The credentials file isn't at /github/runner_temp/

Git then has no credentials available and prompts for interactive authentication, which times out in CI environments.

Reproduction

  1. Set up a Forgejo instance with GitHub Actions runners
  2. Use actions/checkout@v6 in a workflow
  3. Run any git operation that requires authentication (commit, push, etc.)

Expected: Git authenticates silently
Actual: Git prompts for username/password and times out

Evidence

Git config comparison after checkout

v4:
remote.origin.url=https://forge.internal/user/repo
http.https://forge.internal/.extraheader=AUTHORIZATION: basic ***
✅ Push succeeds immediately

v6:
remote.origin.url=https://forge.internal/user/repo
includeIf.gitdir:/github/workspace/.git.path=/github/runner_temp/git-credentials-.config
includeIf.gitdir:/var/lib/gitea-runner/first/action-cache-dir/.../hostexecutor/.git.path=/var/lib/gitea-runner/.../tmp/git-credentials-.config
git push prompts for username and times out with exit code 124

Tested workarounds

  • persist-credentials: false - does not help (no credentials set at all)
  • Using specific token input - does not help (still uses includeIf mechanism)
  • Using ssh-key input - does not help (still uses includeIf mechanism)

Related Issues

This is part of a broader design flaw with v6's path-dependent approach:

Impact

  • All Forgejo users are blocked from using v6
  • All Gitea users are blocked from using v6
  • All non-GitHub self-hosted runners are blocked from using v6
  • Users are forced to downgrade to v4 or v5

Proposed Solutions

  1. Revert to universal HTTP Authorization header approach (v4/v5 behavior) - works everywhere, no path dependencies
  2. Support environment variables for custom credential paths (e.g., RUNNER_TEMP, ACTIONS_WORKSPACE) that can be overridden
  3. At minimum: Document that v6 only supports GitHub Actions and recommend v5 for self-hosted runners
  4. Detect runner environment at runtime and use appropriate credential mechanism (not hardcoded paths)

Workaround

Use actions/checkout@v5 which uses the universal HTTP Authorization header approach and works on all platforms.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    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