In this tutorial, I would like to show you how to set up a new GitHub Actions workflow and a few interesting things that will help you configure it in no time.
At the end of this tutorial, you will know precisely how to:
- navigate in GitHub actions and create new workflows,
- trigger workflows manually,
- create a job that runs only when another job succeeds,
- use GitHub context and access its data.
Video Tutorial
If you prefer video content, then check out my video:
If you find this content useful, please leave a subscription ๐
What Is GitHub Actions?
GitHub Actions is nothing else than a CI/CD (continuous integration/continuous delivery) platform.
To put it simply, it is a platform, that allows us to automate builds, testing, deployments, and many other things related to the process in your company, or the project.
In practice, we define so-called workflows, which are triggered whenever some event happens in our repository. An event can be a merge to the main, a push to the remote branch, a deployment update, and plenty more.
Each workflow consists of jobs running inside their own machine runner and each job can have multiple steps responsible for performing an actual action, like code check, running a test, or creating a deployment.
Lastly, each workflow is nothing else than a YAML file placed within the .github/workflows
directory.
Create First Workflow
With all of that said, let’s navigate to our GitHub repository and select the actions tab. Alternatively, you can do that with the following link: https://github.com/codersee-blog/{YOUR_REPO_NAME}/actions/new.
Nextly, let’s click the configure button:
As a result, we should see the editor with the following code:
# This is a basic workflow to help you get started with Actions name: CI # Controls when the workflow will run on: # Triggers the workflow on push or pull request events but only for the "main" branch push: branches: [ "main" ] pull_request: branches: [ "main" ] # Allows you to run this workflow manually from the Actions tab workflow_dispatch: # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: # This workflow contains a single job called "build" build: # The type of runner that the job will run on runs-on: ubuntu-latest # Steps represent a sequence of tasks that will be executed as part of the job steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - uses: actions/checkout@v3 # Runs a single command using the runners shell - name: Run a one-line script run: echo Hello, world! # Runs a set of commands using the runners shell - name: Run a multi-line script run: | echo Add other actions to build, echo test, and deploy your project.
So, let’s clean it up a bit to avoid distraction:
name: CI on: push: branches: [ "main" ] jobs: build: runs-on: ubuntu-latest steps: - name: Run a one-line script run: echo Hello, world! - name: Run a multi-line script run: | echo Add other actions to build, echo test, and deploy your project.
To sum up, we’ve defined a new GitHub Actions workflow, named CI, which will be triggered whenever we push a new commit to the main branch.
Our workflow consists of one job, build, which will be run on the Ubuntu runner. This job will invoke has two steps, which will be run one after another:
- firstly, it will print out a one-line script,
- lastly, it will invoke the multiline script.
Quite easy, isn’t it?
So with all of that done, let’s change the name of the file to ci.yml
and let’s commit our changes to the main branch:
How To View Workflow Run?
With all of that done, let’s see how we can see the result of our triggered workflow.
To do so, let’s navigate to the following URL: https://github.com/codersee-blog/{your-repo-name}/actions/workflows/ci.yml.
On this page, we should see that our workflow run has completed successfully:
As the next step, let’s click on the build
job and let’s see the output:
Excellent!
Both our scripts run successfully and we can see the expected output.
How To Trigger Flow Manually?
At this point, you might be wondering if (and if yes, then how) we can manually trigger the flow.
Well, unfortunately, to do so, we must edit our YAML file a little:
name: CI on: push: branches: [ "main" ] workflow_dispatch: jobs: build: runs-on: ubuntu-latest steps: - name: Run a one-line script run: echo Hello, world! - name: Run a multi-line script run: | echo Add other actions to build, echo test, and deploy your project.
As we can see, the only thing we need to add is the workflow_dispatch
.
This event, allows us to trigger our workflow using the GitHub API, GitHub CLI, or GitHub browser interface:
How To Disable The Workflow?
But can we disable the workflow without deleting the file?
Yes, we can.
We can do that simply by using the Disable workflow button from the workflow runs page:
Contexts And Debugging
Wonderful. At this point, we already know the basics of workflows and navigation in GitHub Actions.
As the next step, let’s learn a bit more about contexts.
Contexts allow us to access information about the workflow runs, variables, runner environments, jobs, and steps. If you are looking for commit sha, PR author, branch name, or maybe GitHub access token, then that’s the place you should check out.
For the full list of contexts with descriptions please take a look at the official documentation.
But from my end, I wanted to show you a useful tip if you would like to debug anything:
name: CI on: push: branches: [ "main" ] workflow_dispatch: jobs: build: runs-on: ubuntu-latest steps: - name: Run a one-line script run: echo Hello, world! - name: Run a multi-line script run: | echo Add other actions to build, echo test, and deploy your project. - name: Who initialized the flow? run: echo "${{ github.actor }} initialized the flow." - name: Debug GitHub context run: | echo " ${{ toJSON(github) }}"
As we can see, the third step – Who initialized the flow?- prints out the “actor” (or simply the account) that initialized the flow.
The fourth step- Debug GitHub context- prints out github
context to the output.
The toJson
function returns a pretty-print JSON representation of our value.
As a result, we should see the following:
Whatsoever, when debugging we don’t need to worry about exposing our secrets.
GitHub hides them by default.
Run Job After Another Job Finishes Successfully
Excellent! At this point, we learned quite a lot about the GitHub Actions workflows.
We know how to declare them, how to debug contexts, and how to navigate inside the GitHub world.
As the last thing for our first meeting, let’s learn how we can make one job dependent on the other.
To do so, let’s edit our YAML file once again:
name: CI on: push: branches: [ "main" ] workflow_dispatch: jobs: build: runs-on: ubuntu-latest steps: - name: Run a one-line script run: echo Hello, world! - name: Run a multi-line script run: | echo Add other actions to build, echo test, and deploy your project. second_job: needs: build runs-on: ubuntu-latest steps: - name: I run only when build succeeds run: echo Hi!
As we can see, the only thing we need here is needs: build
.
To be more specific, the needs
instruction allows us to specify jobs that must be completed successfully before our job starts.
Of course, we can define multiple jobs using the array syntax: needs: [job1, job2]
.
Summary
And that’s all for this quick tutorial on how to create GitHub Actions workflows.
If you are interested in learning more about this topic, then I highly encourage you to check out their documentation. I’m pretty sure you will find there anything you need.
But if that’s not the case, then let me know in the comments section or by using the contact form ๐