# Open a pull request with generated code

To get generated code from [Skmtc Hub](https://skmtc.dev) into a GitHub
repository, make a pipeline with a **Pull request** action. The pipeline
generates code for one API with one stack. Then it pushes the code to the
branch `skmtc/{project}` of your repository and opens a pull request against
the base branch. Each new revision of the API updates the same pull request.

This page tells you how to set up the pull request, check it, and run it. For
all the pipeline settings, see [Pipelines](/docs/pipelines).

## Before you start [#before-you-start]

- Sign in to Hub. To make a pipeline for an organization, you must be an
  owner of the organization.
- Find the API on Hub. The pipeline follows the latest revision of that API.
- Find the stack that generates the code. A stack is a set of generators that
  its owner publishes on Hub.
- Have write access to the GitHub repository that gets the pull request.

## Step 1: Add a GitHub credential [#step-1-add-a-github-credential]

A pipeline uses a credential of the account that owns it. Add the credential
to that account before you make the pipeline.

1. Open the settings of the account. For your own account, open
   `https://skmtc.dev/settings/git-credentials`. For an organization, open
   `https://skmtc.dev/{organization}/settings`.
2. Select **Install the GitHub App** and give it access to the repository.
   Or select **Add token** and paste a fine-grained GitHub token. The token
   must have read and write access to **Contents** and **Pull requests** on
   the repository.

Use a token from a GitHub account that your team shares, not a personal one.
Then the pipeline continues to work when a person leaves the team.

## Step 2: Make the pipeline [#step-2-make-the-pipeline]

1. Open the page of the API on Hub.
2. Open the **Pipelines** menu and select **New pipeline for this API**.
3. Under **Subscription**, enter a **Name** for the pipeline.
4. Optional: in **Owner**, select the account that owns the pipeline. Select
   the account that has the credential from step 1. You cannot change the
   owner later.
5. Under **Actions**, in **Select stack**, select the stack.
6. Select **Add action**, then select **Pull request**.
7. In **Git credential**, select the credential from step 1.
8. In **Repository**, select or enter the repository as `owner/name`, for
   example `acme/payments-app`.
9. Optional: in **Base branch**, enter the branch that the pull request
   targets. If you leave it empty, Hub uses the default branch of the
   repository.

Do not select **Create and run now** yet. Check the pipeline first, as step 3
tells you.

## Step 3: Check the pull request with a dry run [#step-3-check-the-pull-request-with-a-dry-run]

A dry run shows what the pull request will contain, and changes nothing in
the repository.

1. Save the pipeline.
2. On the page of the pipeline (`https://skmtc.dev/{owner}/pipelines/{name}`),
   select **Dry run**.
3. Read the list of files that the pull request adds or changes. Hub compares
   the generated files with the base branch.

If the list is wrong, edit the stack selection or the base branch, save, and
do the dry run again.

## Step 4: Run the pipeline [#step-4-run-the-pipeline]

- On the page of the pipeline, select **Run now**. If you have not saved the
  pipeline yet, select **Create and run now** on the form instead.

Hub starts a delivery for the latest revision of the API. When the delivery
finishes, the **Pull request** action shows `Pushed to` and the URL of the pull
request. Open the URL to review and merge the code.

The pull request has the title `Regenerate for {account}/{api}`. Its
description links to the pipeline and names the API revision, the stack and
its version, and the number of generated files.

## What happens on later revisions [#what-happens-on-later-revisions]

Each time the API gets a new latest revision, the pipeline runs again:

- Hub generates the code again and force-pushes it to the same branch,
  `skmtc/{project}`. Do not commit your own changes to this branch, because the
  next delivery overwrites them.
- Hub updates the open pull request from the branch. If the branch has no
  open pull request, for example after you merge it, Hub opens a new one.
- If no generated file differs from the base branch, Hub pushes nothing. The
  action shows `No file changes against the base branch.`
- Hub does not delete files from the branch. If the stack no longer makes a
  file, delete the file yourself.

To stop new pull requests, select **Pause** on the page of the pipeline. To
keep the pipeline but skip only the pull request, turn on **Skip** for the
**Pull request** action.

## Troubleshooting [#troubleshooting]

If the **Pull request** action fails, the page of the delivery shows the error.

| Error | Cause | Fix |
| --- | --- | --- |
| `git_credential_invalid` | GitHub rejected the credential or denied access to the repository. | Give the GitHub App access to the repository, or select **Replace** on the credential and paste a token with **Contents** and **Pull requests** access. |
| `repo_not_found` | GitHub cannot find the repository with this credential. | Check the `owner/name` in **Repository**, and that the credential can read it. |
| `branch_protected` | A branch protection rule stops the push to `skmtc/{project}`. | Exclude `skmtc/*` branches from the rule, or let force-pushes to them. |
| `github_rate_limited` | GitHub limited the requests. | Hub tries again. This failure does not count toward the automatic pause. |

Five failed deliveries in a row pause the pipeline. After you fix the cause,
select **Resume**.

## Set up the pull request from an agent [#set-up-the-pull-request-from-an-agent]

The [pipeline tools](/docs/mcp#pipeline-tools) of the Skmtc Hub MCP server
create, dry run and run pipelines. A **Pull request** action needs the
`credentialId` of a credential, and no MCP tool lists credentials. Thus add
the **Pull request** action in the browser, as step 2 tells you. Then an agent
can dry run and run the pipeline with `dry_run_pipeline` and `run_pipeline`.

## See also [#see-also]

- [Pipelines](/docs/pipelines): all actions with their fields, and how
  deliveries run.
- [API change webhooks](/docs/api-change-webhooks): get a signed request with
  the URL of the pull request after each delivery.
