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

> Discover how actions/checkout determines the repository URL by examining its source code. Learn about URL construction, HTTPS, and SSH transport switching.

- Repository: [GitHub Actions/checkout](https://github.com/actions/checkout)
- Tags: deep-dive
- Published: 2026-07-05

---

**The actions/checkout action constructs repository URLs in [`src/url-helper.ts`](https://github.com/actions/checkout/blob/main/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`](https://github.com/actions/checkout/blob/main/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`](https://github.com/actions/checkout/blob/main/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:

```typescript
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:

```typescript
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:

```typescript
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:

```typescript
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`](https://github.com/actions/checkout/blob/main/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`](https://github.com/actions/checkout/blob/main/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`](https://github.com/actions/checkout/blob/main/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`](https://github.com/actions/checkout/blob/main/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`](https://github.com/actions/checkout/blob/main/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.