How to Push Commits Back to a Repository After Using actions/checkout

To push commits back after using actions/checkout, configure a Git identity and use standard git commands, leveraging the automatically persisted GITHUB_TOKEN that the action embeds in the remote URL.

The actions/checkout action creates a fully functional Git repository in your workflow runner, enabling subsequent steps to modify source files and push changes back to GitHub. When you use the action with default settings, it automatically persists the GITHUB_TOKEN in the remote configuration via src/git-auth-helper.ts, eliminating the need for manual authentication setup. This allows you to treat the checked-out repository exactly like a local clone where you can commit and push changes programmatically.

How actions/checkout Handles Authentication

By default, actions/checkout@v4 runs with persist-credentials: true as defined in action.yml. This setting instructs the action to store the authentication token in the Git remote URL, formatted as https://x-access-token:<TOKEN>@github.com/.... The src/main.ts file orchestrates this process by calling src/git-auth-helper.ts to construct the authenticated remote URL, while src/input-helper.ts parses the input parameters including the token and persist-credentials options.

When credential persistence is enabled, the repository is ready for authenticated operations immediately after checkout. You do not need to manually provide credentials when pushing, as the token is already embedded in the remote configuration.

Step-by-Step: Push Commits Back to the Repository

Pushing commits requires three specific steps after the checkout action completes.

Configure Git Identity

Git requires a user.name and user.email to create commits, which actions/checkout does not set automatically. You must configure these using git config before committing:

- name: Configure Git
  run: |
    git config user.name "${{ github.actor }}"
    git config user.email "${{ github.actor }}@users.noreply.github.com"

Execute Git Commands

Once the identity is configured, use standard Git commands to stage, commit, and push changes. Because the token is persisted in the remote URL, the push succeeds without additional authentication:

- name: Commit and push
  run: |
    git add .
    git commit -m "Automated update"
    git push

Complete Workflow Examples

Example 1: Push Directly to the Same Branch

This workflow appends a timestamp to README.md and pushes directly to the branch that triggered the workflow:

name: Update README

on:
  workflow_dispatch:

jobs:
  update-readme:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Configure Git
        run: |
          git config user.name "${{ github.actor }}"
          git config user.email "${{ github.actor }}@users.noreply.github.com"

      - name: Append timestamp
        run: |
          echo "\nUpdated on $(date)" >> README.md

      - name: Commit and push
        run: |
          git add README.md
          git commit -m "Update README with timestamp"
          git push

Example 2: Create a Pull Request with Changes

This workflow creates a new branch, pushes formatting changes, and opens a pull request:

name: Auto-format code

on:
  push:
    branches:
      - main

jobs:
  format:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Git identity
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"

      - name: Run prettier
        run: npx prettier --write .

      - name: Commit and push
        env:
          BRANCH: format-${{ github.run_id }}
        run: |
          git checkout -b $BRANCH
          git add .
          git commit -m "Apply prettier formatting"
          git push --set-upstream origin $BRANCH

      - name: Create PR
        uses: peter-evans/create-pull-request@v5
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          branch: ${{ env.BRANCH }}
          title: "Auto-format with Prettier"
          body: "This PR was created by a workflow."

Example 3: Push to a Different Repository Using a PAT

To push to a repository other than the one checked out, use a Personal Access Token (PAT) and disable the default credential persistence:

- uses: actions/checkout@v4
  with:
    token: ${{ secrets.PAT_REPO_WRITE }}
    persist-credentials: false

- name: Set remote with PAT
  run: |
    git remote set-url origin https://x-access-token:${{ secrets.PAT_REPO_WRITE }}@github.com/owner/target-repo.git

- name: Configure Git and push
  run: |
    git config user.name "github-actions[bot]"
    git config user.email "github-actions[bot]@users.noreply.github.com"
    # ... make changes, commit, and push ...

Key Implementation Files in actions/checkout

Understanding the source code helps explain why this workflow behaves as it does:

  • action.yml: Declares the token and persist-credentials inputs, with the default value of persist-credentials set to true.
  • src/main.ts: Contains the core execution logic that initializes the repository and invokes the authentication helper.
  • src/git-auth-helper.ts: Implements the logic that constructs the authenticated remote URL using the provided token.
  • src/input-helper.ts: Parses workflow inputs including token and persist-credentials, passing them to the main execution context.

Summary

  • actions/checkout persists the GITHUB_TOKEN in the remote URL by default, enabling authenticated pushes without manual credential configuration.
  • You must manually configure Git identity (user.name and user.email) before committing, as the action does not set these values.
  • Use standard git add, git commit, and git push commands to push changes back to the repository.
  • To push to a different repository, provide a Personal Access Token (PAT) via the token input and set persist-credentials: false, then manually configure the remote URL.

Frequently Asked Questions

Does actions/checkout automatically configure Git user.name and user.email?

No. While actions/checkout handles repository authentication, it does not set Git identity configurations. You must explicitly run git config user.name and git config user.email before creating commits, otherwise Git will error with "Author identity unknown".

Why does pushing fail when I set persist-credentials: false?

When you disable credential persistence, the action does not embed the token in the remote URL. According to the implementation in src/git-auth-helper.ts, the authenticated remote URL is only configured when persist-credentials is true. Without this, you must manually set the remote URL with a token or use SSH keys to authenticate the push.

Can I push to a repository different from the one checked out?

Yes. Provide a Personal Access Token with write access to the target repository via the token input, and optionally set persist-credentials: false. Then use git remote set-url to point to the target repository URL, including the token in the format https://x-access-token:<TOKEN>@github.com/owner/repo.git.

What permissions does the GITHUB_TOKEN need to push commits?

The default GITHUB_TOKEN provided to workflows has sufficient permissions to push to the same repository, provided the workflow job has contents: write permissions. If pushing to a different repository, you must use a Personal Access Token with appropriate repository scopes, as the built-in GITHUB_TOKEN is scoped only to the current repository.

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 →