august 9, 2024
Merge requests with Github Actions
Managing dependencies across multiple repositories can be challenging and so so time-consuming. In our project, we have four private Github repositories, with one of these serving as a shared package, called "shared-components". This package is published to NPM and installed as a dependency in the other projects.
Having one centralized place for the code to exist is beneficial for consistency and reducing duplicated code. But it's slow... and tedious. Each time we push a new version to NPM, we need to create three separate merge requests for the other repos, which can take up to ten minutes per update.
Github Action
To streamline this process, we've implemented a GitHub Action that automates the update procedure. This action:
- Retrieves the current version of "shared-components" from NPM
- Installs the new version
- Commits the changes to a new branch
- Creates a merge request against the main branch, if there are differences
name: Update Shared Components
on:
workflow_dispatch:
jobs:
update-package:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: "18.20.4"
- name: Get latest version of shared-components
id: get-version
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
echo "Fetching latest version of @company/shared-components"
LATEST_VERSION=$(npm view @company/shared-components version)
echo "version=$LATEST_VERSION" >> $GITHUB_OUTPUT
- name: Update package.json
id: update-package-json
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
LATEST_VERSION=${{ steps.get-version.outputs.version }}
TIMESTAMP=$(date +%s)
BRANCH_NAME="update-shared-components-${LATEST_VERSION}-${TIMESTAMP}"
echo "Updating package.json with version $LATEST_VERSION"
npm install @company/shared-components@$LATEST_VERSION
git config --global user.name 'github-actions[bot]'
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
git add package.json package-lock.json
git commit -m "chore: shared-components bump package to $LATEST_VERSION"
echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT
- name: Create Pull Request
uses: peter-evans/create-pull-request@v6
with:
token: ${{ secrets.GITHUB_TOKEN }}
branch: ${{ steps.update-package-json.outputs.branch_name }}
commit-message: "chore: shared-components bump package to ${{ steps.get-version.outputs.version }}"
title: "chore: shared-components bump package to ${{ steps.get-version.outputs.version }}"
body: |
This PR updates the @company/shared-components package to version ${{ steps.get-version.outputs.version }}
Auto-generated by [create-pull-request][1]
[1]: https://github.com/peter-evans/create-pull-request
base: main
This automation significantly reduces the time and effort required to keep all repositories up-to-date with the latest shared components.
To implement this solution, create a new file in the .github/workflows
directory of your project, naming it appropriately (e.g., create-merge-request.yml
).
One key component of our GitHub Action is the use of peter-evans/create-pull-request
. This powerful action automates the process of creating pull requests, making it an ideal tool for our use case. It allows us to programmatically create a pull request with the updated shared components, saving time and reducing the potential for human error.
Here's a breakdown of the workflow:
- Trigger: The workflow is set to run on workflow_dispatch, meaning it can be manually triggered when needed.
- Node.js Setup: We're using Node.js version 18.20.4, which ensures compatibility with our project requirements.
- Version Fetching: The action fetches the latest version of the shared components package from NPM.
- Package Update: It updates the package.json and package-lock.json files with the new version of shared components.
- Git Configuration: The action sets up a Git user for the commit, using the github-actions[bot] identity.
- Branch Naming: A unique branch name is generated using the new version number and a timestamp, ensuring no conflicts with existing branches.
- Pull Request Creation: The peter-evans/create-pull-request action is used to create a pull request with a descriptive title and body, targeting the main branch.
- Security: The workflow uses GitHub secrets (GITHUB_TOKEN and NPM_TOKEN) to securely handle authentication for both GitHub and NPM operations.
💡 Note: If your NPM package is private, you'll need to set up an NPM_TOKEN secret in your GitHub repository to allow the action to access the private registry.
By leveraging this GitHub Action, you can maintain consistency across your repositories more efficiently, allowing your team to focus on developing features rather than managing dependencies manually.