GitHub Push Action
Tags: github, githubactions
Published: 2021-03-27 07:07:19

---
title: GitHub Push Action
published: true
date: 2021-03-26 19:59:46 UTC
tags: github, githubactions
canonical_url: https://michaelheap.com/github-push-action/
series: Action Spotlight
---

Today we’re looking at [ad-m/github-push-action](https://github.com/ad-m/github-push-action), the third and final action related to pushing changes made during a GitHub Actions workflow run back to a repo.

## What does it do?

Unlike `git-auto-commit-action` and `add-and-push`, `github-push-action` doesn’t handle committing files for you. It expects your workflow to add and commit any files you need and handles the act of pushing changes to GitHub.

You might be thinking that this seems like an odd action to build; surely it’s as simple as running `git push` and it works? Unfortunately not! The repository provided in your workspace doesn’t have permission to push changes back so you need to configure your repo to use the `GITHUB_TOKEN` provided in order to have write permission.

## How does it work?

This action is an interesting one as it uses both `javascript` and `bash` components to get the job done. `start.js` is the main entry point, which allows the action to run `start.sh` on Linux, MacOS and Windows runners.

Let’s take a look at `start.js` first as it’s the main entry point:

- [The action accepts](https://github.com/ad-m/github-push-action/blob/057a6ba835d986bfe495dd476a6c4db1d5f9503c/start.js#L43-L44) both `branch` and `repository` as inputs.
- If `repository` isn’t provided [it defaults](https://github.com/ad-m/github-push-action/blob/057a6ba835d986bfe495dd476a6c4db1d5f9503c/start.js#L44) to `GITHUB_REPOSITORY` in the environment. If it is provided, that will be used as the destination repository, allowing your workflow to push to other repositories.
- If `branch` is provided it is used as-is. If it is not provided the script uses the GitHub API to [fetch the default branch](https://github.com/ad-m/github-push-action/blob/057a6ba835d986bfe495dd476a6c4db1d5f9503c/start.js#L46-L51) for the repo and uses that as the input value
- Finally, it [executes](https://github.com/ad-m/github-push-action/blob/057a6ba835d986bfe495dd476a6c4db1d5f9503c/start.js#L53-L59) `start.sh` ensuring that both `INPUT_BRANCH` and `INPUT_REPOSITORY` have values

What’s interesting to note here is that `start.js` does not have any dependencies. It uses the `http` module for [making HTTP requests](https://github.com/ad-m/github-push-action/blob/057a6ba835d986bfe495dd476a6c4db1d5f9503c/start.js#L6-L22) and the `child_process` module to [execute](https://github.com/ad-m/github-push-action/blob/057a6ba835d986bfe495dd476a6c4db1d5f9503c/start.js#L24-L36)`start.sh`. `actions/exec` is typically used for this use case, but `github-push-action` does not use any dependencies so that there is no build step required for the JS action.

Now, on to `start.sh`:

- 

We see [some new inputs](https://github.com/ad-m/github-push-action/blob/057a6ba835d986bfe495dd476a6c4db1d5f9503c/start.sh#L4-L8) that have defaults set in the script

  - `INPUT_FORCE` (default `false`) which will run `git push --force`
  - `INPUT_TAGS` (default `false`) which will run `git push --tags`
  - `INPUT_DIRECTORY` (default `.`, the current directory) which controls which directory the push is run from
  - `REPOSITORY`, which is set to `INPUT_REPOSITORY` or `GITHUB_REPOSITORY`. This is a [duplication of the logic](https://github.com/ad-m/github-push-action/blob/057a6ba835d986bfe495dd476a6c4db1d5f9503c/start.js#L44) in `start.js`
- The `GITHUB_TOKEN` secret is required to push to the repo, so we [check that it’s been set](https://github.com/ad-m/github-push-action/blob/057a6ba835d986bfe495dd476a6c4db1d5f9503c/start.sh#L11-L14) as `INPUT_GITHUB_TOKEN`
- If `INPUT_FORCE` is true then add `--force` [to the push options](https://github.com/ad-m/github-push-action/blob/057a6ba835d986bfe495dd476a6c4db1d5f9503c/start.sh#L16-L18)
- If `INPUT_TAGS` is set then add `--tags` [to the push options](https://github.com/ad-m/github-push-action/blob/057a6ba835d986bfe495dd476a6c4db1d5f9503c/start.sh#L20-L22)
- [Configure the remote URL](https://github.com/ad-m/github-push-action/blob/057a6ba835d986bfe495dd476a6c4db1d5f9503c/start.sh#L26) using the `user:password@github.com` format
- [Push the current](https://github.com/ad-m/github-push-action/blob/057a6ba835d986bfe495dd476a6c4db1d5f9503c/start.sh#L28) `HEAD` commit to `INPUT_BRANCH`

## Common use cases

As with the last post, this action is most useful for committing back changed files such as style fixes or build artefacts.

Run `eslint` and commit back:

```yaml
name: Lint source code
on: push

jobs:
  run:
    name: Lint with ESLint
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repo
        uses: actions/checkout@v2

      - name: Set up Node.js
        uses: actions/setup-node@v1
        with:
          node-version: 12.x

      - name: Install dependencies
        run: npm install

      - name: Update source code
        run: eslint "src/**" --fix

      - name: Commit files
        run: |
          git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
          git config --local user.name "github-actions[bot]"
          git add src
          git commit -m "ESLint fixes"

      - name: Push changes
        uses: ad-m/github-push-action@master
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          branch: ${{ github.ref }}
```

Or build your project and commit back the files:

```yaml
name: Automatic Compile
on: push

jobs:
  run:
    name: Compile
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repo
        uses: actions/checkout@v2

      - name: Set up Node.js
        uses: actions/setup-node@v1
        with:
          node-version: 12.x

      - name: Install dependencies
        run: npm install

      - name: Compile
        run: npm run build

      - name: Commit files
        run: |
          git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
          git config --local user.name "github-actions[bot]"
          git add lib
          git commit -m "Built files"

      - name: Push changes
        uses: ad-m/github-push-action@master
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          branch: ${{ github.ref }}
```

## Useful links

- [GitHub Marketplace](https://github.com/marketplace/actions/github-push)
- [GitHub Repo](https://github.com/ad-m/github-push-action)