Skip to main content

git-push

git-push pushes committed changes or new tags from a specified working tree to the remote repository. This step typically follows a git-commit step and/or git-tag step and is often followed by a git-open-pr step.

This step also implements its own, internal retry logic. If a push fails, with the cause determined to be the presence of new commits in the remote branch that are not present in the local branch, the step will integrate the remote changes and retry the push. Any merge conflict requiring manual resolution will immediately halt further attempts.

How remote changes are integrated is controlled by the system-level push integration policy, which is configured by a Kargo operator. The available policies are:

  • AlwaysRebase — Unconditionally rebase. Simplest, but may re-sign or strip commit signatures.

  • RebaseOrMerge — Rebase when a signature-trust analysis determines it is safe; merge otherwise. This preserves linear history when possible without undermining trust.

  • RebaseOrFail — Rebase when the signature-trust analysis determines it is safe; fail the step otherwise.

  • AlwaysMerge — Unconditionally create a merge commit. Most conservative.

caution

The current default policy is AlwaysRebase.

Starting with v1.12.0, the default will change to RebaseOrMerge.

When the policy evaluates rebase safety (RebaseOrMerge and RebaseOrFail), the decision is based on the GPG signature status of the local commits that would be replayed:

  • If all local commits are signed by a trusted key and signing is configured for the committer, a rebase is performed. The replacement commits are re-signed by the committer.

  • If all local commits are unsigned and signing is not configured, a rebase is performed. The replacement commits remain unsigned.

  • In all other cases, the policy's fallback behavior applies (merge or fail).

A "trusted key" is one that has been imported into the committer's GPG keyring with ultimate trust. When a committer with a signingKey is specified in this step's configuration, that key is the only trusted key. When committer is not specified, the trusted key (if any) is the one configured during the git-clone step -- either from the author field or from system-level defaults set by a Kargo admin.

info

For more information on configuring the push integration policy, see the operator guide.

info

This step's internal retry logic is helpful in scenarios when concurrent Promotions to multiple Stages may all write to the same branch of the same repository.

Because conflicts requiring manual resolution will halt further attempts, it is recommended to design your Promotion processes such that Promotions to multiple Stages that write to the same branch do not write to the same files.

note

For a tag push, there is no pull/rebase retry loop.

Credentials

Git steps are utilizing the repository credentials system to access the git repos.

Configuration

NameTypeRequiredDescription
pathstringYPath to a Git working tree containing committed changes.
targetBranchstringNThe branch to push to in the remote repository. Mutually exclusive with generateTargetBranch=true and tag. If none of these are provided, the target branch will be the same as the branch currently checked out in the working tree.
maxAttemptsint32NThe maximum number of attempts to make when pushing to the remote repository. Default is 50.
generateTargetBranchbooleanNWhether to push to a remote branch named like kargo/promotion/<promotionName>. If such a branch does not already exist, it will be created. A value of true is mutually exclusive with targetBranch and tag. If none of these are provided, the target branch will be the currently checked out branch. This option is useful when a subsequent promotion step will open a pull request against a Stage-specific branch. In such a case, the generated target branch pushed to by the git-push step can later be utilized as the source branch of the pull request.
committerobjectNOptional committer information for merge commits or replacement commits created when integrating remote changes before pushing. If provided, this takes precedence over both system-level defaults and any default authorship information configured in the git-clone step.
committer.namestringYThe committer's name.
committer.emailstringYThe committer's email address.
committer.signingKeystringNA GPG signing key for the committer. This field is optional.
tagstringNAn tag to push to the remote repository. Mutually exclusive with generateTargetBranch and targetBranch.
forcebooleanNWhether to force push to the target branch, overwriting any existing history. This is useful for scenarios where you want to completely replace the branch content (e.g., pushing rendered manifests that don't depend on previous state). Use with caution as this will overwrite any commits that exist on the remote branch but not in your local branch. Default is false. A value of true is mutually exclusive with tag.
providerstringNThe name of the Git provider to use. Currently 'azure', 'bitbucket', 'gitea', 'github', and 'gitlab' are supported. Kargo will try to infer the provider if it is not explicitly specified. This setting does not affect the push operation but helps generate the correct commitURL output when working with repositories where the provider cannot be automatically determined, such as self-hosted instances.

Output

NameTypeDescription
branchstringThe name of the remote branch pushed to by this step. This is especially useful when the generateTargetBranch=true option has been used, in which case a subsequent git-open-pr will typically reference this output to learn what branch to use as the head branch of a new pull request.
commitstringThe ID (SHA) of the commit pushed by this step.
commitURLstringThe URL of the commit that was pushed to the remote repository.

Examples

Common Usage

In this example, changes prepared in a working directory are committed and pushed to the same branch that was checked out. The git-push step takes the path to the working directory containing the committed changes and pushes them to the remote repository.

This is the most basic and common pattern for updating a branch with new changes during a promotion process.

steps:
# Clone, prepare the contents of ./out, etc...
- uses: git-commit
config:
path: ./out
message: rendered updated manifests
- uses: git-push
config:
path: ./out

For Use With a Pull Request

In this example, changes are pushed to a generated branch name that follows the pattern kargo/promotion/<promotionName>. By setting generateTargetBranch: true, the step creates a unique branch name that can be referenced by subsequent steps.

This is commonly used as part of a pull request workflow, where changes are first pushed to an intermediate branch before being proposed as a pull request. The step's output includes the generated branch name, which can then be used by a subsequent git-open-pr step.

steps:
# Clone, prepare the contents of ./out, etc...
- uses: git-commit
config:
path: ./out
message: rendered updated manifests
- uses: git-push
as: push
config:
path: ./out
generateTargetBranch: true
# Open a PR and wait for it to be merged or closed...

Push with Custom Committer

The committer field can be used to specify the identity used for merge commits or replacement commits created when integrating remote changes before pushing.

steps:
# Clone, prepare the contents of ./out, etc...
- uses: git-commit
config:
path: ./out
message: rendered updated manifests
- uses: git-push
config:
path: ./out
committer:
name: Kargo
email: kargo@example.com

Push with Signed Commits

In this example, the git-push step uses a GPG signing key for the committer, sourced from an existing secret in the same namespace using the secret() expression function. This ensures that any merge commits or replacement commits created when integrating remote changes bear a valid GPG signature.

note

Committer information may have been configured at the system level by a Kargo admin. If system-level configuration exists, the example shown below would override it.

steps:
# Clone, prepare the contents of ./out, etc...
- uses: git-commit
config:
path: ./out
message: rendered updated manifests
- uses: git-push
config:
path: ./out
committer:
name: Me
email: me@example.com
signingKey: ${{ secret('my-gpg-secret').privateKey }}
note

If committer.signingKey is provided, but committer.name and committer.email do not match the key's UID, the push will fail.

Pushing Tags

In this example, a new tag is pushed to the remote repository.

# Create a new tag
- uses: git-tag
config:
path: ./out
tag: v1.0.0
- uses: git-push
config:
path: ./out
tag: v1.0.0
caution

If the specified tag already exists in the remote repository, the git-push step will fail.