Skip to main content

COMMIT A FILE CHANGE AND OPEN A PULL REQUEST

This guide shows you how to propose a single-file change to a GitHub repository without a local checkout. You check whether a pull request already exists, rehearse the commit and the pull request with dry runs, and then make both for real. These methods use the local gh CLI login instead of a token.

Prerequisites

  • A Swamp repository
  • The gh CLI installed and authenticated (gh auth login) as an account that can push branches and open pull requests in the target repository

Pull the extension

swamp extension pull @hivemq/github/merge

The output looks like:

INF extension·pull: Pulling "@hivemq/github"@"2026.08.27.1787839782"
INF extension·pull: Identity verified: "@hivemq/github"@"2026.08.27.1787839782"
INF extension·pull: Pulled "@hivemq/github"@"2026.08.27.1787839782"
INF extension·pull: Extracted 21 files:

Create the behavior

Create a behavior named docs-pr of type @hivemq/github/merge with a default owner, so each run only needs to name the repository:

globalArguments:
  defaultOwner: example-org

The token global argument is only needed for the Octokit-backed methods such as createPullRequest and mergePullRequest, so leave it out here. Create and Run a Behavior shows the create command. To target a repository owned by someone other than the default owner, pass --input owner=<owner> to any of the runs below.

Check for an existing pull request

swamp behavior run docs-pr findPullRequest --input repo=website --input head=docs/update-contributing

This looks up a pull request from the docs/update-contributing branch in example-org/website and writes a pullRequestLookup resource. If no pull request exists, the resource reports found as false and the run does not fail.

If found is true, the change has already been proposed. Stop here, or pick a different branch name.

Rehearse the commit and the pull request

swamp behavior run docs-pr commitFile --input repo=website --input baseBranch=main --input newBranch=docs/update-contributing --input path=CONTRIBUTING.md --input 'content=Open an issue before sending a pull request.' --input 'commitMessage=docs: update contributing guide' --input 'dryRun:json=true'

With dryRun set to true, this resolves the main base branch but does not create the branch or write CONTRIBUTING.md.

swamp behavior run docs-pr openPullRequest --input repo=website --input head=docs/update-contributing --input base=main --input 'title=Update contributing guide' --input 'dryRun:json=true'

With dryRun set to true, this checks the pull request from docs/update-contributing into main without creating it.

Commit the file and open the pull request

When the dry runs show the expected repository and branches, run both methods again with dryRun set to false:

swamp behavior run docs-pr commitFile --input repo=website --input baseBranch=main --input newBranch=docs/update-contributing --input path=CONTRIBUTING.md --input 'content=Open an issue before sending a pull request.' --input 'commitMessage=docs: update contributing guide' --input 'dryRun:json=false'

This creates docs/update-contributing from main, commits the new CONTRIBUTING.md, and writes a fileCommit resource that records the new branch and its base branch.

swamp behavior run docs-pr openPullRequest --input repo=website --input head=docs/update-contributing --input base=main --input 'title=Update contributing guide' --input 'dryRun:json=false'

This opens the pull request and writes a pullRequest resource.

To change one line instead of replacing the whole file, use replaceInFile in place of commitFile. Its pattern must match exactly once. In a workflow, openPullRequest can read the branch names from the fileCommit resource through CEL. Refer to CEL Expressions, and to Make Workflows Idempotent for using findPullRequest as a guard.