DEV Community

Cover image for Fixing GitHub Actions development using GitHub Actions
Kris Kaczor
Kris Kaczor

Posted on

Fixing GitHub Actions development using GitHub Actions

If you ever browsed the source code of any GitHub Action that you had encountered in the wild, for sure you realized that most authors push bundled JavaScript code directly to a git repository. Usually - it's a single file like action.js, but in the worst case it's a set of files with the whole node_modules committed directly to the git 😱

Why is it a bad idea?

There are various reasons why you might want to avoid that. First of all, it makes code reviews harder. Reviewers now have to take a look at the committed bundle or add additional tooling to verify if the user doesn't try pushing anything fishy instead of a proper bundle. It's a 10k line blob - who's gonna check it anyway?

Bundled files can easily produce merge conflicts which add even more unnecessary work for maintainers. It's confusing for newcomers too, "should I commit this blob or what?". Not to mention, it's just plain ugly to keep these files in the git repo.

node_modules meme

Automation for the rescue

Usually, committing anything that can be derived from the source to the git repositories is a bad practice. Sadly, we can't get rid of pushing JavaScript bundles entirely because GitHub Actions Runner requires it but at least we can hide that fact.

GitHub Actions are all about making developing code easier so let's use GitHub Actions to develop GitHub Actions!

The plan is to develop GitHub Actions as any other JavaScript code - with bundles/node_modules git-ignored. Let's have another branch for build artifacts. This release branch will be automatically updated by GitHub Actions on every push to the main branch.

To make this task easier I've created a helper action called: branch-push-action.

Here's the complete workflow:

name: Deploy

on:
  push:
    branches:
      - master

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
      - uses: actions/setup-node@v1
        with:
          node-version: 12.x
      - run: yarn --no-progress --non-interactive --frozen-lockfile

      - run: yarn build

      - uses: ActionwareIO/branch-push-action@action
        with:
          branch: action
          files: |
            README.md
            action.yml
            ./dist/index.js
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Enter fullscreen mode Exit fullscreen mode

The build task uses ncc to produce a single file bundle. branch-push-action will save specified files, checkout target branch (action in this example), and commit updates. A branch will be automatically created if it doesn't exist and it will contain only necessary files.

The last thing is that you need to point users of your GitHub Action to the branch with bundled code like:

- uses: your-awesome-action@action
Enter fullscreen mode Exit fullscreen mode

Of course, you can tweak this workflow to your needs - use dev and master branches or even commit files to the same branch. I prefer to keep build artifacts on a separate branch as this allows me to completely git ignore any unnecessary files on the default branch.

Summary

Now you can develop GitHub Actions without worrying about build artifacts. I prefer to use TypeScript while creating Actions and pushing compiled JavaScript code was messing up language statistics on GitHub. Now I can brag about that beautiful 100% TypeScript badge ;)

In case you're wondering - yes, branch-push-action is also deployed using itself ;) For the complete solution for automatic deployment browse its source code.

Now, you know how to continuously deploy GitHub Actions, but you wouldn't want to push a broken release, would you? In my next article, I will dive into testing GitHub Actions properly - given their nature, which is full of side effects, it's not that easy. If you don't want to miss it follow me on 🤜 twitter 🤛!

Oldest comments (3)

Collapse
 
bdougieyo profile image
Brian Douglas

Hey Kris, this is clever. While reading I replicating the gh-pages pattern here, curious if that inspired you. I think will be using your branch-push-action for a future project that I need to deploy to multiple providers.

Great stuff!

Collapse
 
krzkaczor profile image
Kris Kaczor • Edited

Awesome! Let me know how it goes ;)

Yes, it's a kinda similar pattern of having a "special" branch for a different thing.

Collapse
 
zemse profile image
zemse

That’s awesome! Especially the title is cool!