GitHub Actions Certification Prep - Part 1

Actions can be used in 3 ways (using tags, branch and SHA values)

An action has Workflows which has jobs and steps mentioned

These workflow are kept within the .github/workflows/ folder

A workflow contains jobs

And jobs contain series of steps

For example, in this job, we asked github to use ubuntu, macos and windows to run our job

Basically, windows and ubuntu is hosted on Azure and MacOs is hosted on GitHub’s own MacOs cloud.

Then the steps are executed in all of the runners

Once the steps are completed properly , you can see that via GitHub

Runner types

GitHub hosted and Self Hosted runners

Hands-on workflow

Go to your github account and create a repository named “actions-1”
Once done, open the repository in the cloud using

https://github.dev/<user_id>/actions_1/tree/main

A new page is going to pop up. Create .github/workflows folder

Install github actions as well

Let’s create first action, named “first-example.yaml”

Then write them down.

Here we first gave a name for our workflow which is “My first workflow”

Then we mentioned to trigger this when any commit is pushed, then we defined our first job named “first_job”. Then we mentioned where to run the job which is the ubuntu-latest version (runs on microsoft azure).

Then we start to mention the steps we want to run. Here we have defined 3 steps. One step name is Welcome message which executes echo “Welcome to our………” and another step name is ls which executes “ls”. Finally the third step name is Read files which executes “cat README.md”

Once done, we push the changes to our repository.

So, here we go

But if you go to the Actions tab, you can see the workflow has failed

If you check the issues, you will see that the workflow couldn’t find README.md file and therefore failed.

Before we solve our issue, let’s analyze more GitHub Actions Core concepts.

This is how a workflow looks like which has multiple jobs and steps within them.

Let’s now solve our workflow issue. Go to GitHub Marketplace and choose actions . Look for the checkout actions

Now how to use it and why to use it?

Because it will help us load the files within our repository. We actually had README.md file

in the actions repository but was not loaded properly.

So, load that using checkout.

As we are using another external actions, we write use instead of run

Then push the changes.

Once the commit is done, the actions look like this

You can see the workflow has been successful now as the folder is loaded properly now using checkout actions.

You can also check the content of the README.md file

Now let’s upgrade our yaml file. Rather than using different steps, let’s just make a single step add all of the other steps there

We have added pipe to add all of these codes in a single run command. Then modify the step name to give relevant details

Finally let’s create another step and use cowsay library to generate a content and save it in the dragon.txt file

Then push the changes!!

We can see the job has failed

The error shows that it could not find cowsay command. So, we have to install that.

Let’s create another workflow named generate_ascii and push it

Here first we wanted the checkout actions to get the content of the repo, then installed the cowwsay library, then executed the command we wanted to run earlier, then we tried to check if we have the work “dragon” in the ascii generated content.

The ascii content will have “Run for your life…viewer!”. So, the word “dragon” is surely not there.

So, we expect an error.

Finally read the content of the dragon.txt file and then check the list of all files in the repo.Let’s push the file then.

This time , 2 commit were as we have 2 workflows created and they both works on the push commit.

Check the one which has #1 meaning 1st action for the workflow.

Once done, it shows the error which we were expecting!!

Let’s correct this issue by changing the content of the dragon.txt file

Here I have added a line with dragon word. Finally, push it.

Now, check the latest actions and you can see out ascii_job is successful

While doing that, you again noticed we had 2 workflows launching this time.

Let’s disable the first workflow we created so that, we don’t find the error with it ( The occurred as it couldn’t find cowsay command)

Done!

Now, when we push any commit, only the “Generate ASCII content” will work only.

Using shell scrip in workflow

Let’s first create a shell scrip in our repo named “ascii_script.sh”

Let’s keep all of the commands we used in generate_ascii.yaml here

Then in the generate_ascii.yaml, let’s modify to use the commands written in ascii_script.sh

Once pushed, you can see an error

We can see that it’s permission issue. Let’s make it executable by giving the executable permission +x (Also add the pipe as we have 2 commands given now)

Then push it.

Now , you can see the workflow is successful

Working with multiple jobs

Let’s modify the generate_ascii.yaml file now and replace the old job with this new job “build_job_1” which installs the cowsay library, generate a content and waits for 30 seconds.

Then added another job which waits for 10 second and then checks if the word “dragon” exits in dragon.txt

Finally add another job which shows the content in the dragon.txt file and prints echo Deploying…..

Let’s push it now!!!

You can see this workfiow is working and they are running in parallel.

Finally we can see that, 2 jobs failed

But why?

As 3 jobs were running in 3 different machines (ubuntu-latest), in job 1 (build_job_1), we did install cowsay and created the dragon.txt file.

Surely, that’s not accessible by the job 2 and job 3(test_job_2, deploy_job_3)

So, we have to make them dependent or use other jobs.

So, this time in our workflow, we mentioned that, test_job_2 required build_job_1 to be completed and then it will work.

In the same manner, deploy_job_3 requires test_job_2 and build_job_1 to be be completed. Once done, it will work.

Once done, let’s push the changes.

Now if you check the workflow, you can see the sequence. You can also see the jobs are running in sequence

Sadly we made changes to run jobs one by one. But we haven’t yet made content of the job to be accessible. So, the job 2 fails (as the second job looks the content from dragon.txt)

To solve this issue, we need to upload the content (artifact) we have in one job. And then download that in another job which requires the file.

We are going to use Upload a build artifact to upload our content

Also, use Download a Build Artifact to download for other jobs

Let’s use the upload action, and set the artifact (content upload is given an easy name)

The path is also set as the file name (dragon.txt)

Then added the download step in the other jobs

Finally we push the commit.

This time the workflow was successful!

From job 1, you can see that the file was uploaded with the name dragon-text-file and was zipped first.

If you check the job 2 now, you can see the artifact was downloaded and the content is printed this time

Also we can download the artifact easily from the workflow

Work with Variable secrets

Assume, we want to build docker image, login to it and publish the image. Then deploy it.

While doing that, we have to pass our real dockerUsername and password and imageName. But this is not safe. If someone gets this yaml file, your account is gone!!

name: Exploring Variables and secrets.

on:

push

jobs:

docker:

runs-on: ubuntu-latest

steps:

- name: Docker Build

run: docker build -t docker.io/dockerUsername/imageName:latest - name: Docker login

run: docker login --username=dockerUsername --password=s3cUePaSsw0rd

- name: Docker publish

run: docker push docker.io/dockerUsername/imageName:latest

deploy: needs: docker

runs-on: ubuntu-latest

steps: - name: Docker Run

run: docker run -d -p 8080:80 docker.io/dockerUsername/imageName:latest

So, rather than this, use this variable version

Here we did set the variables in each step (step level)

We can also set that in the job level / workflow levelso that, we don’t need to mention this every time.

job level variable ==>

Workflow level variable ==>

Then we can push the file.

Note: This workflow will give error as I haven’t provided real docker user name and password here. Make sure to use your own account and password here. Still it’s not safe as the variable value is set in the yaml file.

Variables set in a repository level

As mentioned earlier, docker user name and password should not be written in the yaml file. Therefore, set them in the repository level

Set DOCKER_PASSWORD as secret and DOCKER_USERNAME as a variable

For our folder, we have just saved them here just like this

Use the real user id and password here without any doubt.

Now modify the yaml file like this and push it

As we set DOCKER_USERNAME in variable and DOCKER_PASSWORD in the secrets, we have used vars.DOCKER_USERNAME and secrets.DOCKER_PASSWORD

This time the workflow has worked properly

0
Subscribe to my newsletter

Read articles from Md Shahriyar Al Mustakim Mitul directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Md Shahriyar Al Mustakim Mitul
Md Shahriyar Al Mustakim Mitul