How to Use actions/checkout in GitHub Actions: Complete Implementation Guide
The actions/checkout action clones your repository into $GITHUB_WORKSPACE by parsing workflow inputs through src/input-helper.ts and executing Git commands via src/git-source-provider.ts, making your code available to subsequent steps.
The actions/checkout action is the standard mechanism for accessing repository code inside GitHub Actions workflows. Understanding how to use actions/checkout in GitHub Actions effectively requires knowledge of its input parameters, internal execution flow, and security safeguards as implemented in the actions/checkout repository.
How the Checkout Action Works
actions/checkout is a JavaScript-based action that orchestrates repository access through a specific execution pipeline. The runner reads action.yml to determine available inputs and entry points, then executes the workflow defined in src/main.ts.
The execution flow follows these stages:
- Input Parsing – The
getInputs()function insrc/input-helper.tsreads workflow parameters, applies defaults (such asclean: trueandfetch-depth: 1), and constructs anIGitSourceSettingsobject. - Safety Validation –
src/unsafe-pr-checkout-helper.tsvalidates theallow-unsafe-pr-checkoutflag against pull request origins to prevent fork-based attacks. - Git Configuration –
src/git-source-provider.tsinitializes the repository, configures authentication tokens, and prepares the working directory under$GITHUB_WORKSPACE/<path>. - Fetch and Checkout – Based on settings like
fetch-depth,filter, andfetch-tags, the provider executesgit fetchand checks out the requestedref. - Credential Cleanup – Unless
persist-credentials: falseis set, the action removes temporary tokens from Git config during the post-step cleanup.
Basic Usage Examples
Minimal Checkout
The simplest usage checks out the current repository at the default branch:
- uses: actions/checkout@v4
Checkout Specific Branches or Tags
Use the ref input to checkout a specific branch, tag, or commit SHA:
- uses: actions/checkout@v4
with:
ref: my-branch
Fetch Full History
By default, the action performs a shallow fetch (depth 1). Set fetch-depth: 0 to retrieve complete history for commands like git log or git describe:
- uses: actions/checkout@v4
with:
fetch-depth: 0
Advanced Configuration
Sparse Checkout
Limit downloaded data by configuring sparse checkout patterns in src/git-source-provider.ts before the fetch:
- uses: actions/checkout@v4
with:
sparse-checkout: |
README.md
src/
sparse-checkout-cone-mode: false
Large File Storage (LFS)
Enable Git LFS to handle large files:
- uses: actions/checkout@v4
with:
lfs: true
Submodule Handling
Checkout nested submodules recursively:
- uses: actions/checkout@v4
with:
submodules: recursive
Cross-Repository Access
Access private repositories using a Personal Access Token (PAT) stored in secrets:
- uses: actions/checkout@v4
with:
repository: my-org/private-repo
token: ${{ secrets.PAT }}
Security Considerations
The action includes security protections implemented in src/unsafe-pr-checkout-helper.ts. By default, it refuses to checkout code from forked pull requests unless explicitly authorized.
To checkout the PR head SHA instead of the merge commit:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
To opt-in to potentially unsafe checkouts (only after reviewing security implications):
- uses: actions/checkout@v4
with:
allow-unsafe-pr-checkout: true
Summary
actions/checkoutclones repositories into$GITHUB_WORKSPACEusing a TypeScript-based implementation split across specialized source files.- Input processing occurs in
src/input-helper.ts, which validates parameters and applies defaults before passing settings to the Git provider. - Security protections in
src/unsafe-pr-checkout-helper.tsprevent accidental execution of untrusted fork code without explicit opt-in. - Advanced features include sparse checkout, LFS support, submodule handling, and cross-repository access via PAT authentication.
Frequently Asked Questions
How do I checkout a pull request branch instead of the merge commit?
Set the ref input to ${{ github.event.pull_request.head.sha }} to checkout the actual PR head rather than the merge commit. This configuration is useful when you need the exact commit state without GitHub's automatic merge into the base branch.
Why does my workflow fail when accessing private repositories?
Private repository access requires authentication via the token input. Configure a Personal Access Token with repo scope stored in repository secrets, then pass it to the action using token: ${{ secrets.PAT }}. The default GITHUB_TOKEN only has access to the current repository.
When should I use fetch-depth: 0 versus the default shallow checkout?
Use fetch-depth: 0 when your workflow requires complete Git history, such as for semantic versioning tools, git describe, or changelog generation. The default shallow checkout (depth 1) improves performance and reduces disk usage for builds that only need the latest commit.
What files control the actions/checkout behavior?
The action behavior is defined in action.yml (interface definition), src/main.ts (entry point), src/input-helper.ts (input validation), and src/git-source-provider.ts (Git command execution). Understanding these files helps debug complex checkout scenarios or contribute to the action.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →