Automatically Create a Pull Request Against a Feature Branch with GitHub Actions
Tags: github, git, npm, devops
Published: 2023-06-12 13:26:04

---
title: Automatically Create a Pull Request Against a Feature Branch with GitHub Actions
published: true
date: 2023-06-11 00:00:00 UTC
tags: github,git,npm,devops
canonical_url: https://www.paigeniedringhaus.com/blog/automatically-create-a-pull-request-against-a-feature-branch-with-git-hub-actions
---

[![Old school typewriter](https://www.paigeniedringhaus.com/static/209618d5209ec7dd5a2720fdbd1a80dd/15ec7/typewriter-hero.jpg "Old school typewriter")](/static/209618d5209ec7dd5a2720fdbd1a80dd/0f98f/typewriter-hero.jpg)

## Introduction

This blog post is the second in a [short series](https://www.paigeniedringhaus.com/blog/use-git-hub-actions-to-automatically-publish-a-repo-subfolder-as-an-npm-library) I'm writing about the many things I learned in the course of building my first open source API library for the IoT startup I work for, [Blues](https://blues.io/?&utm_source=paigeniedringhaus.com&utm_medium=web&utm_campaign=nf&utm_content=notehub-js).

It was a great learning experience for me and a new, unique challenge because I needed to do the following things:

- Make a copy of the `openapi.yaml` file from the Blues cloud's repository, [Notehub](https://notehub.io/?&utm_source=dev.to&utm_medium=web&utm_campaign=nf&utm_content=notehub-js), whenever the file was updated.
- Open a new pull request against the [Notehub JS repo](https://github.com/blues/notehub-js) with the copy of the `openapi.yaml` file.
- Generate a fresh version of the Notehub JS API library based on the that file via the [OpenAPI Generator CLI](https://openapi-generator.tech/docs/installation).
- And publish the updated Notehub JS library to [npm](https://www.npmjs.com/package/@blues-inc/notehub-js).

And I wanted to automate as many of these steps as possible through the use of GitHub Actions workflows.

Since I didn't know how often the Notehub's `openapi.yaml` file would be updated, I needed a way to notify myself when a new version of the Notehub's API file needed review in the Notehub JS repository. The best solution I could think of was to open a new pull request in the Notehub JS repo after copying the updated `openapi.yaml` file into a feature branch and tagging myself to review it.

**Today, I'll walk through how to use a GitHub Actions workflow to create (or update) a pull request whenever a new feature branch is made in that repository.**

---

## Notehub JS

Before we get to the actual GitHub Actions workflow, let me give you just a little background on the [**Notehub JS**](https://github.com/blues/notehub-js) project because it's a bit different than most.

> This section helps explain the folder structure for the repo in case you want to explore it in GitHub, if you just want the solutions, feel free to jump down to the next section.

Notehub JS is a JavaScript-based library for interacting with the native [**Notehub API**](https://dev.blues.io/reference/notehub-api/api-introduction/?&utm_source=paigeniedringhaus.com&utm_medium=web&utm_campaign=nf&utm_content=notehub-js), and it's generated from the Notehub project's own `openapi.yaml` file, which follows the [OpenAPI specification](https://swagger.io/specification/) standards.

The [OpenAPI Generator CLI]((https://openapi-generator.tech/docs/installation)) is a tool that can use the `openapi.yaml` file to create an entire library complete with documentation, models, endpoints, and scripts to package it up for publishing as an npm module. The end library that I care about publishing to npm is a _subfolder_ inside of the main Notehub JS repo. At the root of the project are the `openapi.yaml` file, the GitHub Actions workflows, and a few other config files.

Here's a simplified view of the [Notehub JS repo](https://github.com/blues/notehub-js)'s folder structure:

```
root/
├── .github/ 
| ├── workflows/
| | ├── create-pr.yml 
| ├── PULL_REQUEST_TEMPLATE.md
├── src/ <- this is the folder generated by the OpenAPI Generator CLI
| ├── dist/
| ├── docs/
| ├── src/ 
| | ├── api/ 
| | ├── model/
| | ├── index.js 
| openapi.yaml
| config.json
| package.json
```

As you can see in the diagram above, the `openapi.yaml` file that this library is generated from lives at the root of the repo, and the `src/` folder is what actually holds all the Notehub API JavaScript code that powers the [Notehub JS library](https://www.npmjs.com/package/@blues-inc/notehub-js).

This `openapi.yaml` file is what gets copied from the Notehub repo when changes are made to it. And changes are made to the file whenever the Notehub API is updated with new features and functionality, so making sure that the Notehub JS library keeps up with the new additions to the API it's designed to interact with is important.

Now that I've explained a bit more about the Notehub JS repo and why keeping it in sync with the Notehub API is important, we can get down to the business of automating PRs for this repo.

> **Looking for more details about Notehub JS?**
> 
> Check out my [previous blog post](https://www.paigeniedringhaus.com/blog/use-git-hub-actions-to-automatically-publish-a-repo-subfolder-as-an-npm-library) about how to use GitHub Actions to automatically publish new releases to npm - I do a fairly deep dive on Notehub JS there.

### Create a standard PR template for the repo

When I was just a few years into my own web development career, I was introduced to [GitHub PR templates](https://betterprogramming.pub/github-templates-the-smarter-way-to-formalize-pull-requests-among-development-teams-89f8d6a204f), an easier way to keep pull requests uniform for a repository worked on by multiple developers. It made the task of creating decent PRs so much better.

There is not a team or repo I join now without adding a `./github/` directory folder and `PULL_REQUEST_TEMPLATE.md` file if it doesn't already exist.

For the Notehub JS repo, as it's mostly autogenerated, I included a couple of sections to fill in: `Problem Context`: a brief description of the updates in the PR, and `Changes`: what code changes were actually made in the PR. Simple enough for any dev to fill out.

[**`PULL_REQUEST_TEMPLATE.md`**](https://github.com/blues/notehub-js/blob/main/.github/PULL_REQUEST_TEMPLATE.md)

```markdown
# Problem Context

## Changes

```

That's all I wanted to add to the repo before focusing on the GitHub Actions workflow itself. We'll get to it next.

### Set up a GitHub Actions workflow to automatically create pull requests

> **Need a refresher on GitHub Actions?**
> 
> If you want a quick primer on what GitHub Actions are, I recommend you check out a previous article I wrote about them [here](https://www.paigeniedringhaus.com/blog/use-secret-environment-variables-in-git-hub-actions#what-is-github-actions).

For this particular workflow, I was able to string together a few premade [GitHub Actions](https://docs.github.com/en/actions) to do just what I needed:

- Create a new pull request whenever a new feature branch was pushed to the GitHub repository.
- Use the `PULL_REQUEST_TEMPLATE.md` file to format the PR.
- Notify me when a PR is there for review.

Here's what the final `create-pr.yml` file looks like inside of the `./github/workflows/` directory. I'll dissect it below.

[**`create-pr.yml`**](https://github.com/blues/notehub-js/blob/main/.github/workflows/create-pr.yml)

```yaml
name: Automatically create / update pull request

# run this workflow only on new feature branches, not when they're merged to main
on:
  push:
    branches-ignore:
      - "main"

jobs:
  create_pr_repo_sync:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Create pull request
        id: open-pr
        uses: repo-sync/pull-request@v2
        with:
          destination_branch: "main"
          pr_title: "feat: PLACEHOLDER TITLE"
          pr_template: ".github/PULL_REQUEST_TEMPLATE.md"
          pr_reviewer: "paigen11"
          pr_draft: true
```

Each workflow file needs a **`name`** , so I chose to name this one: `Automatically create / update pull request`.

This workflow should be triggered whenever a new branch is pushed to the repo _but_ it should ignore the `"main"` branch. `"main"` is the main branch of this repo that gets published to npm and doesn't need a PR to be created for it.

```yaml
on:
  push:
    branches-ignore:
      - "main"
```

- [**`on`**](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#on) is how a workflow is triggered.
- [**`push`**](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#onpushbranchestagsbranches-ignoretags-ignore) is the event that triggers the workflow.
- [**`branches-ignore`**](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#example-excluding-branches-and-tags) is how to exclude the workflow from running on certain branch patterns. This gives us more fine-grained control of when the workflow should run.

Then the **`jobs`** section runs inside of the workflow. This particular script only has one job, `create_pr_repo_sync`, but if there's multiple jobs, they'll run sequentially unless otherwise specified.

The `create_pr_repo_sync` job defines that it runs on the latest version of Ubuntu in **`runs-on`**.

Finally, I get to the **`steps`**.

The steps are as follows:

1. Checkout the code so the workflow can access it using the GitHub Action [`actions/checkout@v3`](https://github.com/actions/checkout).
2. Create a pull request using the GitHub Action [`repo-sync/pull-request@v2`](https://github.com/repo-sync/pull-request)
3. Pass the PR action a custom `pr_title`, `pr_template`, and `pr_reviewer`. Set it to be created as a `pr_draft` (I like PRs to be drafts until I've looked them over and know they're ready for review), and open the PR branch against the `destination_branch: "main"`.

In the `pr_template` section, I pass the path to the PR template file I made in the previous section, and for the `pr_reviewer` I add my own GitHub username so that I get an email notification when the new PR is created in GitHub.

### Test out the workflow

If you want to test this functionality out, create a new local branch of the repo, make a change in the branch, and push it to GitHub. When that new branch registers, the GitHub Actions workflow will be triggered to run.

If you visit the **Actions** page in the GitHub repo, you should see the "Automatically create / update pull request" job running.

[![GitHub Actions workflow running in Notehub JS repo's Actions tab](https://www.paigeniedringhaus.com/static/9e62484e7aa49007e3d6008d55472a64/1e043/gh-action-workflow.png "GitHub Actions workflow running in Notehub JS repo's Actions tab")](/static/9e62484e7aa49007e3d6008d55472a64/20766/gh-action-workflow.png)

And after the action finishes running, there should be an email sent to the folks tagged as the PR reviewers in the GitHub Action (me, in this case).

[![Notification email from GitHub to review the newly created PR](https://www.paigeniedringhaus.com/static/fe8357b2a004d3efa65400b7ed177268/1e043/gh_action_email.png "Notification email from GitHub to review the newly created PR")](/static/fe8357b2a004d3efa65400b7ed177268/2a333/gh_action_email.png)

And with that, the workflow working has been confirmed, and the reviewers know it's time to take action in that repo.

---

## Conclusion

When I built my first open source software library, I learned a lot. My software is a JavaScript library based on my company's API, Notehub, so every time the Notehub API gets updated, the JS library based off of it, needs to be updated too.

I needed a programmatic way to let myself know whenever new changes were made to the JS repo that needed to be reviewed.

The easiest way I could think to accomplish this was by automating the pull request creation so that when a new feature branch was pushed to the repo, it opened a PR and tagged myself as the reviewer.

Luckily, a GitHub Action existed for just such a scenario, allowing for designating a PR template, a PR reviewer, giving the PR a placeholder title, and a whole host of other configurations. The workflow made it quite straightforward, and gave me the peace of mind that whenever changes are made that I need to review, I get an email to look at what's changed.

Check back in a few weeks — I’ll be writing more about the useful things I learned while building this project in addition to other topics on JavaScript, React, IoT, or something else related to web development.

If you’d like to make sure you never miss an article I write, sign up for my newsletter here: https://paigeniedringhaus.substack.com

Thanks for reading. I hope learning to use GitHub Actions workflows to automate a new PR when a feature branch is pushed to a repository proves useful. Enjoy!

---

## References & Further Resources

- Previous OSS article [using GH Actions to publish a package to npm](https://www.paigeniedringhaus.com/blog/use-git-hub-actions-to-automatically-publish-a-repo-subfolder-as-an-npm-library)
- [Notehub JS](https://github.com/blues/notehub-js) GitHub repo
- [GitHub PR templates](https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/creating-a-pull-request-template-for-your-repository)
- [Pull request](https://github.com/repo-sync/pull-request) GitHub Action