Custom GitHub Actions

Automate, customize, and execute your software development workflows right in your repository with GitHub Actions

Custom Github Action with pre-compiled docker image

Actions are individual tasks that you can combine to create jobs and customize your workflow. You can create your own actions, or use and customize actions shared by the GitHub community

For this example, I will create a PCL-Build-Action in docker to compile pcl-cmake based projects. See Types of actions for other types.

This action will use a pre-compiled pcl-alpine-docker image to execute the action. This means that the job in Github actions will pull the image from Docker Hub instead of building a custom image in the execution of the workflow. The advantage of this is that, the building process won't be in the job, making the running process faster.

In the next section, I will run the same example, but letting Github create a custom docker image using the Dockerfile provided in the PCL-Build-Action repository which will be use to execute the action.

  1. Create a Github Repository called: PCL-Build-Action
  2. Create an action.yml file
  3. name: PCL Build Action
    description: Action for building PCL-CMake project which depends on vtk-9/qt5
    author: Daniel T.
    
    inputs:
        build_type:
            description: "Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)"
            default: "Release"
            required: false
            type: string
    
    runs:
        using: "docker"
        image: docker://codebydant/pcl-docker:1.12.1-alpine3.15-All-GA-v1
    
    # https://actions-cool.github.io/github-action-branding/
    branding:
        icon: "package"
        color: "gray-dark"
    
  4. Create a README.md
  5. Save, commit and push the changes to the PCL-Build-Action repository
  6. [Optional] deploy the custom github action to the Marketplace

How Does It Work?

A Github action is a Github repository with a .yml manifest

action.yml: manifest

Actions require a metadata file to define the inputs, outputs and main entrypoint for your action. The metadata filename must be either 'action.yml' or 'action.yaml'. For more information, see "Metadata syntax for GitHub Actions."

The first 3 lines ('name', 'description', 'author') are the metadata for this custom action. The name must be unique since there might be another github action in the marketplace with the same name.

In this example, I have defined one input called: build_type which is passed to the Docker container as an environment variable in the entrypoint.sh file.

The 'runs' section defined the type of action to be executed. In this example, I am telling to Github to use a 'docker' action with a public docker hub image called: docker://codebydant/pcl-docker:1.12.1-alpine3.15-All-GA-v1.

You can set "image: Dockerfile" to use the provided Dockerfile in the PCL-Build-Action repository (see next section), but be aware that every time a new job is executed, an image from the Dockerfile will be compiled (this will cause increasing times in the job execution + possible billing fees from Github).

The last section is 'branding', which correspond to the logo and colour for the Github Action Marketplace. See "github-action-branding"

README.md

This file will be the description of the custom action in the marketplace. In this document you explain the usage of your custom action.

Usage

You must release/tag a version of your github action in your repository and then, add the following line to your ''.github/workflows/ci.yml' file in your project.
steps:
- name: Clone repository
  uses: actions/checkout@v3

- name: PCL Build Action
  uses: codebydant/PCL-Build-Action@v1
Where 'codebydant' is the name of your Github account, 'PCL-Build-Action' is the name of your custom github action repository and '@v1' is the tag release.

You can tag/release your github action with:

# How to tag source code
git tag -a -m "PCL-Build-Action release" v1
git push origin main --follow-tags

# How to delete tag remote/local
git tag --delete v1
git push --delete origin v1

Custom Github Action with Dockerfile

In this section I will run the custom github action letting Github to build a custom docker image using the provided Dockerfile in the repository. Be aware that this procedure might increase running times in the workflow since Github will need to build a new image, everytime a job is launched.
  1. Create a Github Repository called: PCL-Build-Action
  2. Create an action.yml file
  3. name: PCL Build Action
    description: Action for building PCL-CMake project which depends on vtk-9/qt5
    author: Daniel T.
    
    inputs:
        build_type:
            description: "Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)"
            default: "Release"
            required: false
            type: string
    
    runs:
        using: "docker"
        image: "Dockerfile"
    
    # https://actions-cool.github.io/github-action-branding/
    branding:
        icon: "package"
        color: "gray-dark"
    
    Notice that the selected image is "Dockerfile".
  4. Create a Dockerfile
  5. FROM codebydant/pcl-docker:1.12.1-alpine3.15-All-dev AS build
    COPY entrypoint.sh /entrypoint.sh
    RUN chmod +x /entrypoint.sh
    ENTRYPOINT ["/entrypoint.sh"]
    
  6. Create an entrypoint.sh file
  7. #!/bin/sh -l
    cmake -B `pwd`/build -DCMAKE_BUILD_TYPE=$INPUT_BUILD_TYPE
    cmake --build `pwd`/build --parallel $(nproc) --config $INPUT_BUILD_TYPE
    
  8. Create a README.md
  9. Save, commit and push the changes to the PCL-Build-Action repository
  10. [Optional] deploy the custom github action to the Marketplace

How Does It Work?

Dockerfile

This file will be the action to be executed. In this example, the 'Dockefile' will create an image that executes an 'entrypoint.sh' file. The 'codebydant/pcl-docker:1.12.1-alpine3.15-All-dev' is the base image to be used where all pcl dependencies such us 'VTK', 'OpenG'L, 'Boost', 'Flann', 'Eigen' are compiled.

The 'Dockerfile' itself contains the action instructions, where the "backend" will be the base image and the instructions will be given by the 'entrypoint.sh' bash script. 'Github/act' will build a new image base on this Dockerfile generally called:

act-pcl-build-action-dockeraction  ...   latest  
The name will be base on the github action name. See image below for a Github example.

entrypoint.sh

This file is the main entrypoint to the Docker container. Will run the cmake commands to compile the project and read any 'INPUT_ARG' provided in the 'yml manifest' as an environment variable. This will be similar to have:
docker run -e INPUT_BUILD_TYPE -v GITHUB_WORKSPACE act-pcl-build-action-dockeraction(NAME OF THE CUSTOM BUILT IMAGE BY GITHUB OR ACT)
Every input defined in the yml manifest must be prefixed with INPUT_ in the main 'entrypoint.sh' file, otherwise won't be recognized. See "Specifying inputs".

Running custom Github Action locally with nektos/act

The Dockerfile defined in the custom action can be executed locally using nektos/act. You can download the PCL Build Action repository and run the 'act' command. You will need to modify the 'yml manifest' (action.yml) in the 'PCL Build Action' repository folder to use "Dockerfile" instead.

The project structure to run the custom github action using the Dockerfile locally is the following:

More information about colored ls output see https://github.com/athityakumar/colorls

In this example, I have a 'pcl-visualizer' repository where I have a '.github/workflow/ci.yml' file with the following content.
# ci.yml
name: Continuous integration

on:
  push:
    branches-ignore:
      - documentation
  pull_request:
    branches-ignore:
      - documentation

jobs:
  build-and-test:
    runs-on: ubuntu-20.04

    steps:
      - name: Clone repository
        uses: actions/checkout@v3

      - name: PCL Build Action
        uses: ./PCL-Build-Action
This ci.yml is instructing Github to use the local PCL-Build-Action repository to run the action. This means, that Github/act won't pull a public docker hub image, but instead will compile a new one using the Dockerfile in the Github-Action local repository. Note: The image above has a wrong project path. It is actually: 'danieltc at ~/Downloads/project'.

As you see in the image above, Github/act is building a new custom image from the Dockerfile provided in the repository which is being used later to execute the action instructions.

Deploy to Marketplace

You can deploy your custom github action to the marketplace You will need to tag your repository and then, release the action to the marketplace.

Note

One thing to have in mind is that, regardless the chosen method (use a pre-compiled image or Dockerfile), a new image must be built if there are updates, modifications, or refactorizations in the action code. Also, be aware that if you are running the workflow locally with nektos/act, everytime a new workflow is executed an image is being stored with your docker images. So, everytime you modify/update your custom github action, you must delete/remove the older images since nektos/act will check if a previous image exists with the same name and then will try to pull it. This means that the new updates won't be tested since nektos/act will be pulling the older image version.