Skip to content

fix(auth): forge selection uses url.contains("gitlab") — a GitHub repo whose slug contains "gitlab" gets no token #799

Description

@BryanFRD

token_for_url (src/git/auth.rs:16) picks the forge with a bare substring test against the whole URL:

if url.contains("gitlab") {
    if let Ok(token) = std::env::var("GITLAB_TOKEN") { ... }
} else if let Ok(token) = std::env::var("GITHUB_TOKEN") { ... }

contains is applied to the full URL, not the host, so the owner and repo name are in scope. A remote like:

  • https://github.com/acme/gitlab-migration-tool
  • https://github.com/gitlab-ce-mirrors/whatever

takes the GitLab branch, finds no GITLAB_TOKEN, and returns None. configure_git_command then attaches no credential helper at all and the push fails with an authentication error, despite GITHUB_TOKEN being set correctly. The failure message points at credentials, not at the repo name, so it is unpleasant to diagnose.

The mirror case is milder: with FERRFLOW_TOKEN set, the same test only picks the username (oauth2 vs x-access-token), which GitHub tolerates for basic-auth-over-HTTPS in most cases — so it usually works and hides the bug.

src/forge/mod.rs already does this properly: detect_forge_from_url + extract_host parse the URL and match on the host. git/auth.rs is the only place that reimplements detection by substring.

Fix

Reuse the existing detection. token_for_url should call forge::detect_forge_from_url(url) and map ForgeKind to the username and env var, falling back to the GitHub shape when detection returns None (self-hosted instances that neither module recognises). That also picks up Gitea/Forgejo and Bitbucket, which token_for_url currently has no branch for at all — a Gitea push today gets x-access-token + GITHUB_TOKEN, which is wrong on both counts.

While in there: the FERRFLOW_TOKEN branch does not filter empty values, unlike forge::resolve_token, so FERRFLOW_TOKEN="" shadows a perfectly good GITHUB_TOKEN.

Tests

  • token_for_url("https://github.com/acme/gitlab-migration-tool") with only GITHUB_TOKEN set returns the GitHub pair.
  • token_for_url("https://gitlab.com/acme/repo") with only GITLAB_TOKEN set returns ("oauth2", …).
  • A Gitea remote with GITEA_TOKEN set returns a token rather than falling through to the GitHub branch.
  • FERRFLOW_TOKEN="" falls through to the forge-specific var.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Low priority / somedaybugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions