Building GitHub Action part 1

When to build a custom action?

Normally when a project are getting bigger with number of build and deploy arises, DevOps uses custom build action to deploy the application. The standard workflow look like this

Checkout ---> Build ---> Deploy

In yml representation:

jobs:
    build_and_deploy
        steps:
            - name: Checkout
            - uses: actions/checkout@v1
            
            - name: Build
              run: make all
              
            - name: Deploy
              uses: actions/deploy@v1
              with:
                  environment: Staging
    

Keyword run is an interface to a command prompt.

Keyword uses lets us invoke the action. Action relies on some other command line tool to do the job. It acts like the adapters between the workflow and the command line tools.

When do we used either action or invoking the command itself?

We need to consider 4 things:

  • Control flow

  • Diagnostics

  • Complexity

  • Reuse

Imagine you want to run an npm script called build.

- name: Build
  run: npm run build

Before the "run build", restore first the packages by running the npm install or npm ci command.

- name: Build
  run: 
    npm ci
    npm run build

But considering that we only want to run build when the restore is done. The above code will not behave as such it will still run the build even the restore fails.

In order to prevent this, we use a control flow. A flow in to do something only if the certain condition is met.

- name: Build
  run: |
    npm ci && npm run build

Since run can be interpreted via shell, we can use any control flow structures that are build into the shell itself.

The above code will requires restore to pass before the build.

Now imagine that we have more than one package to build this workflow. We can use the working-directory keyword to run the same command on multiple project.

- name: Build
  run: |
    npm ci && npm run build
  working-directories: |
    ./src/project

But we have to duplicate the same shell command in different places.

- name: Build
  run: |
    npm ci && npm run build
  working-directories: |
    ./src/project
- - name: Build one
  run: |
    npm ci && npm run build
  working-directories: |
    ./src/project
- name: Build two
  run: |
    npm ci && npm run build
  working-directories: |
    ./src/project
- name: Build three
  run: |
    npm ci && npm run build
  working-directories: |
    ./src/project

This defeats the purpose of KISS(Keep it simple and short). This is the run keyword limitation. A better solution is to package the build logic inside an actions that accepts one or more working directories as an input.

- name: Build
  uses: actions/npm-build@v1
  with:
    working-directories: |
      - /src/projectOne
      - /src/projectTwo
      - /src/projectThree 

There is also an option to split the commands into separate jobs

jobs:
    install:
        steps:
            - name: Clean Install
              run: npm ci
    build:
        needs: install
        steps:
            - name: Build
              run: npm run build

Notice that under build jobs, it requires the install by using the keyword needs. This is almost the same as using with ampersand.

In summary:

Last updated