Vincent Bouvier
fulll
Published in
4 min readAug 30, 2019

--

Light bulb idea creativity socket — picture by ColiN00B

GitHub’s Actions v2 — Tips and Tricks

This article relates different tips and tricks we have been using to either compensate for some limitations or achieve actions that are not yet instinctive in terms of usage.

Keep in mind that GitHub’s actions are still in beta and that things may change along the development process.

Trigger a workflow from within a workflow

Problem statement

One documented limitation of workflow is that every activity performed on the git repository won’t trigger any other event on that repository.

An action in a workflow run can’t trigger a new workflow run. For example, if an action pushes code using the repository’s GITHUB_TOKEN, a new workflow will not run even when the repository contains a workflow configured to run when push events occur. (source: event that trigger workflow)

This limitation is very understandable. A workflow could end up in an infinite loop calling itself again and again.

However, there are some cases where it is interesting to trigger a new event, especially during continuous deployment. Let’s consider the following pseudo-coded workflows:

create_deployment.yml
on: push
create a new deployment on GitHub
---deploy.yml
on: deployment
update deployment status to in_progress
perform the deployment

if success: update deployment status to success
else: update deployment status to failure

This workflow is very common, and it has the main advantage of performing the CD while being in a deployment context.

Workaround

When executing a workflow, GitHub provides a GitHub token inside the secrets variable. If you create the deployment using this token, then GitHub won’t trigger any event for creating the deployment.

If you use a personal token instead, this will do the trick. If you are part of an organization, then we recommend you to create a bot user for it. Then create a GitHub Token for this user and add it to the secrets of your workflow.

Generate a token in Developer Settings from your Profile Settings

Trigger a workflow on every branch but master and dev

Problem statement

In a typical git project workflow, you may have a master branch for the production product, and a dev branch for the staging product. Developers usually work on another branch (feature branch). Then, a pull request merges the branch into one of the main branches (master or dev).

You may want to perform some tasks only on the feature branch like continuous integration (CI).

When GitHub actions were released, it was possible to do so very quickly using the following syntax :

on:
push:
branches:
- !master
- !dev

This syntax was very convenient and very clear to read. Unfortunately, it is not working anymore. From now on, a workflow must have at least one positively valid condition. In addition, order matter as stated in the new documentation:

When you specify a branches or tags filter, the workflow only runs if at least one pattern matches. Any changes to branches or tags that don't match a defined pattern will not trigger a workflow. The order that you define patterns matters:
- A matching negative pattern after a positive match will exclude the ref again.
- A matching positive pattern after a negative match will include the ref again.

(source: workflow syntax for github actions)

Workaround

The workaround for this one is very simple. You need to include the wildcard "*" before every other branch to exclude like so:

ci.yml
on:
push:
branches:
- '*'
- '!master'
- '!dev'

Define an environment or variable within a step

Problem Statement

GitHub defined a toolkit to develop your own actions in order to use them in one or many of your workflows. In the @actions/core toolkit, it is possible to export an environment variable or an output variable. However, when you only use an inline shell script, you may want to export an environment variable or output.

Workaround

In a shell, it is very easy to export an environment variable with export foo=bar. In the context of a step, the variable won't be visible to the other steps. Use the following syntax to properly export an environment variable or an output:

run: echo “##[set-env name=foo;]bar”run: echo “##[set-output name=foo;]bar”

⚠️ The variable won't be visible until the next step

Interrupt a Job on purpose

Problem Statement

Sometimes you may want to run a job based on certain conditions. When the conditions are not met, you may want to interrupt the job.

Workaround

The workaround for this one is simple, run the following script as soon as you want to interrupt a job:

run: exit 1

You may want to consider some optimization when the stop condition is accessible at an early step and does not require much of resources to be computed (e.g., the information is available on the GitHub event variable)

Optimization

When a job executes and uses external resources (docker container, external GitHub action…), all the resources are downloaded beforehand. When the stop condition is accessible at an early step, the download is performed uselessly.

The optimization consists of defining a job aimed to check the condition. The job has to fail if the condition is not met. Then you can define a second job that needs the first one to be terminated successfully to run.

Interrupt a Job — the optimization

⚠️ Be careful though: remember that jobs run in different instances and that resources are not shared between each other. If the "checking" step contains heavy loads that need to be repeated in the second step, then use only one job. This is all about what's using what is best for your use case.

This is not the end yet

GitHub's actions are still in beta yet it is already very powerful. We hope this article will help some of you. Feel free to share your tips and tricks with the community for better use of Github Actions.

--

--