# How actions/checkout Parses Inputs: A Deep Dive into the GitHub Actions Source Code

> actions/checkout parses inputs by reading context normalizing values into typed data and validating them before execution Explore the source code to understand the process.

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

---

**The actions/checkout action parses inputs in [`src/input-helper.ts`](https://github.com/actions/checkout/blob/main/src/input-helper.ts) by reading the GitHub Actions context, normalizing string values into typed data (booleans, numbers, arrays), and validating them against an `IGitSourceSettings` interface before execution.**

The `actions/checkout` repository powers one of the most executed steps in GitHub Actions workflows worldwide. Understanding how actions/checkout parses inputs reveals the robust type conversion and security validation logic that ensures reliable repository operations. All input processing logic resides in [`src/input-helper.ts`](https://github.com/actions/checkout/blob/main/src/input-helper.ts), which transforms raw workflow inputs into a structured configuration object consumed by the checkout engine.

## Input Processing Pipeline in src/input-helper.ts

The [`src/input-helper.ts`](https://github.com/actions/checkout/blob/main/src/input-helper.ts) file serves as the central parser for the action. It constructs an `IGitSourceSettings` object that drives the entire checkout operation, from repository identification to authentication setup.

### Workspace Validation and Repository Identification

First, the helper validates the execution environment by reading `process.env['GITHUB_WORKSPACE']`, resolving the path, and verifying the directory exists. For the repository input, it calls `core.getInput('repository')` and falls back to the workflow's default repository (`owner/repo`) if omitted. The code splits the repository string and validates the two-part format according to lines 22-27 in [`src/input-helper.ts`](https://github.com/actions/checkout/blob/main/src/input-helper.ts).

### Path Resolution and Security Constraints

The optional `path` input defaults to `.` and is resolved under the workspace. The helper enforces security by checking that the resolved path remains a subdirectory of the workspace. This prevents path traversal attacks by ensuring extracted files cannot write outside the designated directory.

### Ref and SHA Normalization

When parsing the `ref` input, the helper distinguishes between branch references and commit SHAs. If `ref` is omitted, it inherits `github.context.ref` and `github.context.sha` for the workflow's own repository. If the input matches a 40-character or 64-character hexadecimal pattern, the code stores it in the `commit` property and clears the `ref` field, as implemented in lines 60-78.

## Type Conversion and Normalization Logic

Raw inputs from [`action.yml`](https://github.com/actions/checkout/blob/main/action.yml) arrive as strings. The helper applies specific conversion logic for different data types to build the `IGitSourceSettings` object.

### Boolean Flag Parsing

Every toggle input follows a consistent boolean conversion pattern. The code reads the string value, applies a default, and converts it using strict case-insensitive comparison:

```typescript
result.clean = (core.getInput('clean') || 'true').toUpperCase() === 'TRUE'

```

This pattern applies to `clean`, `filter`, `sparse-checkout`, `fetch-tags`, `show-progress`, `lfs`, `submodules`, `persist-credentials`, `ssh-strict`, `set-safe-directory`, and `allow-unsafe-pr-checkout`.

### Numeric and Multiline Inputs

The `fetch-depth` input undergoes numeric conversion and validation:

```typescript
result.fetchDepth = Math.floor(Number(core.getInput('fetch-depth') || '1'))

```

The code clamps the value to ensure it is greater than or equal to 0.

For sparse checkout patterns, the helper uses `core.getMultilineInput('sparse-checkout')` to parse the input into an array of path patterns, as shown in lines 94-99 of [`src/input-helper.ts`](https://github.com/actions/checkout/blob/main/src/input-helper.ts).

### Authentication and SSH Configuration

The `token` input is fetched with `core.getInput('token', {required: true})`, defaulting to `${{ github.token }}` if not explicitly provided. SSH-related inputs including `ssh-key`, `ssh-known-hosts`, `ssh-strict`, and `ssh-user` are parsed in lines 43-48, enabling secure Git operations over SSH.

## Safety Validation and Workflow Context

After collecting inputs, the helper invokes `unsafePrCheckoutHelper.assertSafePrCheckout` to enforce the `allow-unsafe-pr-checkout` opt-in requirement for pull requests from forks. This safety check prevents credential leakage when checking out potentially malicious code.

The helper also captures workflow metadata by calling `workflow-context-helper.getOrganizationId()` and reading `github-server-url` for GitHub Enterprise Server (GHES) configurations, enabling support for self-hosted instances.

## Practical Configuration Examples

### Minimal Default Checkout

```yaml
steps:
  - uses: actions/checkout@v4

```

This configuration relies entirely on defaults; `input-helper` parses `github.context` to determine the repository and reference.

### Shallow Clone with Specific Reference

```yaml
steps:
  - uses: actions/checkout@v4
    with:
      ref: refs/heads/feature-xyz
      fetch-depth: 5

```

Here, `ref` is read directly (lines 61-63) while `fetch-depth` undergoes numeric conversion (lines 106-110).

### Sparse Checkout Configuration

```yaml
steps:
  - uses: actions/checkout@v4
    with:
      sparse-checkout: |
        src/
        docs/
      sparse-checkout-cone-mode: false

```

The multiline `sparse-checkout` becomes an array, while `sparse-checkout-cone-mode` converts to boolean via the standard boolean parsing logic.

### Custom Authentication

```yaml
steps:
  - uses: actions/checkout@v4
    with:
      token: ${{ secrets.PAT }}
      persist-credentials: false

```

The `token` is marked as required in the call to `core.getInput`, and `persist-credentials` is converted to boolean false.

## Summary

- **Centralized parsing**: All input processing occurs in [`src/input-helper.ts`](https://github.com/actions/checkout/blob/main/src/input-helper.ts), which builds an `IGitSourceSettings` object consumed by [`src/main.ts`](https://github.com/actions/checkout/blob/main/src/main.ts).
- **Type safety**: Boolean inputs use `.toUpperCase() === 'TRUE'` for strict conversion, while `fetch-depth` uses `Math.floor(Number())` for integer parsing.
- **Security validation**: The helper enforces workspace subdirectory constraints and invokes `unsafePrCheckoutHelper.assertSafePrCheckout` for fork PR safety.
- **Multiline support**: The `sparse-checkout` input uses `core.getMultilineInput()` to parse path patterns into arrays.
- **Context awareness**: The parser falls back to `github.context.ref` and `github.context.sha` when inputs are omitted, and supports GHES via `github-server-url`.

## Frequently Asked Questions

### How does actions/checkout handle boolean inputs that are not explicitly set?

When boolean inputs like `clean` or `persist-credentials` are omitted, the parser applies a default value (typically `'true'`) and converts it using a strict string comparison: `.toUpperCase() === 'TRUE'`. This ensures that only the explicit string "true" (case-insensitive) evaluates to boolean true, while any other value evaluates to false.

### What happens if the path input resolves outside the GitHub workspace?

The [`src/input-helper.ts`](https://github.com/actions/checkout/blob/main/src/input-helper.ts) file validates that the resolved path remains a subdirectory of `GITHUB_WORKSPACE`. If the path resolves outside this boundary, the action prevents the checkout operation, protecting against directory traversal attacks that could overwrite system files.

### How does the action distinguish between a branch ref and a commit SHA?

The parser checks if the `ref` input matches a 40-character or 64-character hexadecimal pattern. If it matches, the value is stored in the `commit` property of `IGitSourceSettings` and the `ref` property is cleared. Otherwise, the value is treated as a reference (branch or tag) and stored in `ref`.

### Where does the default GitHub token come from if not specified in the workflow?

If the `token` input is omitted, `core.getInput('token', {required: true})` automatically resolves to `${{ github.token }}`. This default token is granted based on the workflow's permissions settings and is used for authentication during the Git operations.