How actions/checkout Determines the Repository URL: A Deep Dive into the Source Code

The actions/checkout action constructs repository URLs in src/url-helper.ts by combining the server base URL with URL-encoded owner and repository names, automatically switching between HTTPS and SSH transport based on the presence of an SSH key.

Understanding how actions/checkout determines the repository URL is essential for troubleshooting authentication issues and configuring custom GitHub Enterprise Server environments. The action implements a deterministic URL resolution pipeline that handles everything from public GitHub repositories to private self-hosted instances. This article examines the exact source code implementation that powers one of the most widely used GitHub Actions.

The URL Resolution Pipeline

The repository URL determination logic centers on the getFetchUrl function exported from src/url-helper.ts. This function receives configuration settings and returns either an HTTPS or SSH URL depending on the authentication method configured.

Input Parameters via IGitSourceSettings

The URL construction process begins with the IGitSourceSettings interface defined in src/git-source-settings.ts. The function extracts five critical fields:

  • repositoryOwner – The organization or user name owning the repository
  • repositoryName – The specific repository identifier
  • githubServerUrl – Optional override for GitHub Enterprise Server instances
  • sshKey – When present, triggers SSH URL generation instead of HTTPS
  • sshUser – Optional SSH username (defaults to git)

Server URL Resolution

Before building the final URL, getFetchUrl calls getServerUrl to determine the base endpoint:

const serviceUrl = getServerUrl(settings.githubServerUrl)   // ← src/url-helper.ts

This helper implements the following priority order:

  1. Use the explicit githubServerUrl parameter if provided
  2. Fall back to the GITHUB_SERVER_URL environment variable
  3. Default to https://github.com for public GitHub instances

HTTPS vs SSH URL Construction

The getFetchUrl function branches based on whether an SSH key is configured, producing distinctly different URL formats for each transport protocol.

HTTPS URL Format

When no sshKey is present, the function returns a standard HTTPS origin URL:

return `${serviceUrl.origin}/${encodeURIComponent(settings.repositoryOwner)}/${encodeURIComponent(settings.repositoryName)}`

This construction concatenates:

  • The scheme and hostname (e.g., https://github.com or https://ghe.mycompany.com)
  • URL-encoded owner and repository names
  • Resulting format: https://github.com/owner/repo

SSH URL Format

If sshKey contains a value, the function builds an SSH URL with a custom user component:

const user = settings.sshUser.length > 0 ? settings.sshUser : 'git'
return `${user}@${serviceUrl.hostname}:${encodedOwner}/${encodedName}.git`

Key characteristics of the SSH implementation:

  • Defaults to the git user when sshUser is unspecified
  • Uses the hostname only (not the full origin) from the service URL
  • Appends the .git extension automatically
  • Produces format: git@github.com:owner/repo.git

Code Implementation Examples

The following TypeScript examples demonstrate how the URL helper processes different configuration scenarios:

import {IGitSourceSettings} from './git-source-settings.js';
import {getFetchUrl} from './url-helper.js';

// Example 1 – default public GitHub (HTTPS)
const httpsSettings: IGitSourceSettings = {
  repositoryOwner: 'actions',
  repositoryName: 'checkout',
  // … other required fields omitted for brevity …
  sshKey: '',
  sshUser: '',
  githubServerUrl: undefined,
};
console.log(getFetchUrl(httpsSettings));
// → https://github.com/actions/checkout

// Example 2 – custom GitHub Enterprise Server (HTTPS)
const gheSettings = {...httpsSettings, githubServerUrl: 'https://ghe.mycompany.com'};
console.log(getFetchUrl(gheSettings));
// → https://ghe.mycompany.com/actions/checkout

// Example 3 – SSH checkout with a custom user
const sshSettings = {...httpsSettings, sshKey: 'my-ssh-key', sshUser: 'myuser'};
console.log(getFetchUrl(sshSettings));
// → myuser@ghe.mycompany.com:actions/checkout.git

Integration with Git Operations

The computed URL flows directly into the Git workflow through src/git-source-provider.ts. At lines 23-24, the provider invokes getFetchUrl and passes the result to git remote add origin, establishing the remote repository connection.

The same URL resolution logic also powers:

  • Default branch detection algorithms
  • Submodule initialization when recursive checkout is enabled
  • API endpoint determination via the related getServerApiUrl function

Additional helper functions in src/url-helper.ts support GitHub Enterprise detection. The isGhes function (lines 47-58) identifies when the target server is a GitHub Enterprise instance, ensuring proper API URL generation for internal deployments.

Summary

  • src/url-helper.ts contains the core getFetchUrl function that determines whether to use HTTPS or SSH transport based on the sshKey setting.
  • Server URL resolution prioritizes explicit configuration, then environment variables, then defaults to https://github.com.
  • HTTPS URLs combine the server origin with URL-encoded owner and repository names.
  • SSH URLs use the format user@hostname:owner/repo.git with a default user of git.
  • src/git-source-provider.ts consumes these URLs to execute git remote add origin and manage the repository workspace.

Frequently Asked Questions

What file handles the repository URL construction in actions/checkout?

The src/url-helper.ts file exports the getFetchUrl function, which is responsible for constructing both HTTPS and SSH repository URLs. This module also contains getServerUrl for resolving the base GitHub server address and isGhes for detecting GitHub Enterprise Server instances.

How does actions/checkout handle GitHub Enterprise Server URLs?

When the githubServerUrl input parameter is provided or the GITHUB_SERVER_URL environment variable is set, the getServerUrl function uses that value as the base URL instead of the default https://github.com. This allows the action to generate correct fetch URLs for private GitHub Enterprise Server instances using the same URL construction logic.

Can I customize the SSH user when using SSH authentication?

Yes. The IGitSourceSettings interface includes an optional sshUser field. When provided, getFetchUrl uses this value instead of the default git user. If sshUser is empty or undefined, the function automatically falls back to git as the SSH username.

Are repository names URL-encoded in the final fetch URL?

Yes. Both the repository owner and repository name are passed through encodeURIComponent before being concatenated into the final URL. This ensures that special characters, spaces, or Unicode characters in repository names are properly escaped according to URL standards, preventing fetch errors caused by malformed repository addresses.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →