<

Automating Synchronization with GitHub Actions and Pull Requests

Happy New Year. I am silverbirder, who drew the best fortune for the first time in my life at a shrine.

In my daily work, I feel that the communication to synchronize things like Figma's design tokens, API schema files, and i18n message files to the frontend is unproductive. Therefore, I will introduce a mechanism to reduce synchronization communication using GitHub Actions and Pull Requests.

It may not be new information, but I hope it will be helpful to those who have the same problems.

What to use with GitHub Actions

The core of the mechanism I will introduce this time is the repository-dispatch trigger of GitHub Actions.

https://docs.github.com/ja/rest/repos/repos?apiVersion=2022-11-28#create-a-repository-dispatch-event

This trigger allows you to start a GitHub Actions workflow via the GitHub API. Therefore, you can link GitHub Actions workflows in different repositories as follows.

repository-dispatch and create-pull-request are the following GitHub Actions.

https://github.com/peter-evans/repository-dispatch https://github.com/peter-evans/create-pull-request

  • respository-dispatch
    • Action to dispatch a repository-dispatch-event
  • create-pull-request
    • Action to create a Pull Request

You can substitute these GitHub Actions with gh and others, but I will use convenient tools to make it easier.

Triggers from outside GitHub repositories

Not only from a GitHub repository (username/other) but also from other services can trigger. For example, if it's from Google Sheets, you can call the GitHub API from Google Apps Script.

Additionally, there is a method where the Kibela's outgoing webhook is received by the Server, and the Server calls the GitHub API.

The server can be a service like IFTTT or Zapier, or it can be your own server.

Automatic commit

You may want to generate types from the schema file (yarn codegen). In such cases, add the following flow.

The git-auto-commit-action is an Action that simply commits changed files to git.

https://github.com/stefanzweifel/git-auto-commit-action

Even with create-pull-request alone, you can automatically commit. I used it in the following cases:

  • Creating a Pull Request from Figma with Design Tokens.
    • I want to commit the build of the style dictionary with GitHub Actions
on:
  pull_request:
    types: [opened]
jobs:
  update:
    if: startsWith(github.head_ref, 'figma/')
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
      - run: npm ci
      - run: npx style-dictionary build
      - uses: stefanzweifel/git-auto-commit-action@v4

Preview

When you update Figma's design tokens or i18n message files, having a mechanism to preview is good because you can check the screen.

For example, previews from vercel or chromatic.

https://vercel.com/docs/concepts/deployments/preview-deployments https://www.chromatic.com/docs/review

Sample Code

I will introduce GitHub Actions to synchronize i18n message files to the frontend.

repositoryWhat to do
username/frontendUse i18n message files
username/messageManage i18n message files
# <username/message>/.github/workflows/main.yml
on:
  push:
    branches:
      - main
    paths:
      - "i18n/**"
jobs:
  dispath:
    name: Setup
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: peter-evans/repository-dispatch@v1
        with:
          repository: username/frontend
          token: ${{ secrets.PAT }}
          event-type: create-pull-request-message
          client-payload: '{"ref": "${{ github.ref }}"}'
# <username/frontend>/.github/workflows/main.yml
on:
  repository_dispatch:
    types: [create-pull-request-message]
jobs:
  createPullRequest:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/checkout@v3
        with:
          repository: username/message
          ref: ${{ github.event.client_payload.ref }}
          path: "tmp/"
      - run: |
          mv tmp/message.json src/message.json
          rm -rf tmp
      - uses: actions/setup-node@v3
      - run: npm ci
      - run: yarn generate:message
      - uses: peter-evans/create-pull-request@v4

Managing Acceptance Tests with Markdown

To ensure that you can merge with confidence, let's prepare acceptance tests.

Specifically, we will manage the specifications with cucumber in Markdown(MARKDOWN_WITH_GHERKIN).

For example, it's a specification like this.

# Feature: Staying alive

This is about actually staying alive,
not the [Bee Gees song](https://www.youtube.com/watch?v=I_izvAbhExY).

## Rule: If you don't eat you die

<Image
	src="https://res.cloudinary.com/silverbirder/image/upload/v1693363969/silver-birder.github.io/blog/lunch_2x.png"
	width={604}
	height={801}
	layout="constrained"
	alt="xkcd"
/>

`@important` `@essential`

### Scenario Outline: eating

- Given there are <start> cucumbers
- When I eat <eat> cucumbers
- Then I should have <left> cucumbers

#### Examples:

| start | eat | left |
| ----- | --- | ---- |
| 12    | 5   | 7    |
| 20    | 5   | 15   |

Let's put this Markdown on the flow to make a Pull Request with GitHub Actions. If a new scenario is added, it will result in an error if there is no test code on the cucumber library.

By managing the scenarios you want to guarantee with the feature in Markdown, you have the following benefits.

  • The specifications become clear
  • If the acceptance test (cucumber) is run and successful in CI, it will be in a state that meets the specifications

Things I got stuck on

Can't trigger other workflows with commit from GitHub Actions Bot

https://github.com/orgs/community/discussions/27028

You can solve this by changing the token to pass PAT.

Another solution is to use the trigger of workflow_run.

https://docs.github.com/ja/actions/using-workflows/events-that-trigger-workflows#workflow_run

However, it only works on the default branch.

There are restrictions on POST of repository-dispatch in JSON

https://github.com/peter-evans/repository-dispatch#client-payload

Initially, I was thinking of converting the files I wanted to sync to json and including them in the dispatch event payload. However, I rejected it because of the following concerns.

  • Comments disappear when converted to json
  • There is an upper limit to the byte size of JSON

So, I switched to a policy of including the github.ref of the repository I want to sync in the event payload, and the recipient of the event checks out and uses the source code.

In conclusion

By utilizing GitHub Actions and Pull Requests, you can easily build a system that automatically updates the source code of your application. With such Ops, you can reduce the number of times you have to rally messages on Slack. Please make use of it.

If it was helpful, support me with a ☕!

Share

Related tags