Understanding GitHub Actions: Core Concepts and Fundamentals
Automation

Understanding GitHub Actions: Core Concepts and Fundamentals

Explore the core building blocks of GitHub Actionsβ€”from workflows and triggers to jobs and stepsβ€”and learn how to harness these fundamentals to automate your development process, saving you time and effort.

Introduction

Hey there everyone πŸ‘‹! Ever wished you had a tireless assistant who could automatically test your code every time you make changes? Someone who never forgets, never takes breaks, and catches problems before they reach your users? That’s exactly what we’re going to build today with GitHub Actions!

I’m excited to continue our journey through modern software development. In the previous articles, we explored the fundamentals of Git ( Part 1: Understanding Git ) and learned how to set up our first GitHub repository ( Part 2: Setting Up Your First GitHub Repository ). Now, we’re ready to take our development workflow to the next level with GitHub Actions!

So, what exactly is GitHub Actions? Simply put, it’s a powerful tool built right into GitHub that helps you automate all sorts of tasks within your software development lifecycle. Think of it as your personal robotic assistant that can automatically test your code, build your application, and even deploy it to your servers.

But why should we care about GitHub Actions in the first place? What’s wrong with building, testing, and deploying our applications the good old-fashioned way? Well, while there’s nothing inherently wrong with manual processes, they do come with some significant drawbacks. They’re often time-consuming, require a lot of mental context switching, and are prone to human error. This is where GitHub Actions shines! It provides a way to automate these repetitive tasks, freeing you up to focus on what you really love – writing code and building awesome features.

In this article, we’ll explore the fundamentals of GitHub Actions, how it integrates with your existing development workflow, and the basic building blocks that make up a GitHub action, such as workflows, jobs, and steps. Don’t worry if some of these concepts seem complex at first. We’ll break them down step by step, using clear examples and explanations.

Alright, let’s jump right into the exciting world of GitHub Actions!

How GitHub Actions Works

GitHub Actions Workflow Pipeline Figure 1: A visual representation of a typical GitHub Actions workflow, from code commit to deployment.

Remember that tireless assistant we talked about? Let’s see exactly how GitHub Actions becomes that assistant by following what happens when you push code to your repository.

Imagine you’ve just finished writing some code on your computer. You commit your changes (like we learned in Part 1) and push them to GitHub (like we did in Part 2). This is where GitHub Actions springs into life!

The moment your code lands on GitHub, something special happens. GitHub checks if you have any workflows defined in your repository. Think of a workflow as a recipe that tells GitHub Actions what to do. Just like a recipe has ingredients and steps, a workflow has events that trigger it and jobs that define the work to be done.

Let’s trace through what happens step by step:

  1. The Trigger: First, an event occurs - in this case, you pushing code. Events are like alarm bells that wake up GitHub Actions. Other events might include someone creating a pull request, a scheduled time arriving, or even a manual button click. We’ll explore more triggers in future articles!

  2. The Workflow Activates: When the right event happens, GitHub Actions looks for workflow files in a special folder (.github/workflows/) and says “Aha! This workflow wants to run when code is pushed. Let’s get to work!”

  3. Jobs Spring into Action: Your workflow contains one or more jobs. Each job is like a mini-mission with its own set of tasks. What’s cool is that jobs can run in parallel (at the same time) or sequentially (one after another), depending on what you need.

  4. Steps Execute in Order: Within each job, you have steps. These are the individual tasks that actually do the work - things like:

    • Checking out your code (getting a fresh copy to work with)
    • Installing dependencies (like npm packages for a JavaScript project)
    • Running your tests
    • Building your application
    • Deploying to a server
  5. The Runner Does the Heavy Lifting: Here’s where it gets interesting. Each job needs a place to run - a computer to execute all those steps. GitHub provides these computers, called runners, for free! When you see runs-on: ubuntu-latest (which we’ll use soon), you’re telling GitHub “Hey, give me a Linux computer to run this job.” Don’t worry about the details yet - we’ll explore runners more after you’ve seen them in action.

  6. Results and Feedback: As your workflow runs, GitHub Actions provides real-time feedback. You can watch each step execute, see their output, and quickly spot if anything goes wrong. Green checkmarks mean success, red X’s mean something needs attention.

The beauty of this system is that it all happens automatically. Once you set up a workflow, it runs consistently every time your chosen events occur. No more forgetting to run tests, no more manual deployments, no more “works on my machine” problems!

Now that you understand the flow, let’s build your first workflow and see these concepts come to life. Trust me, seeing that green checkmark appear for the first time is incredibly satisfying!

Your First GitHub Actions Workflow

Now that you understand how GitHub Actions works, let’s create your first workflow! There’s nothing quite like seeing your own automation spring to life, and I promise - that green checkmark at the end will feel incredibly satisfying.

Setting Up

Before we dive in, let’s make sure you have everything ready. You’ll need:

  • Your my-first-project repository from Part 2
  • VS Code (or your preferred text editor)
  • About 5 minutes of your time

If you’re joining us fresh or need to catch up, you can clone the repository:

git clone https://github.com/ahmedmuhi/my-first-project.git
cd my-first-project

Open the project in VS Code by selecting File β†’ Open Folder and choosing your project directory.

Creating the Workflow File

GitHub Actions looks for workflow files in a specific location: the .github/workflows directory. Let’s create this structure:

  1. In VS Code, right-click in the Explorer panel (the left sidebar)
  2. Select “New Folder”
  3. Name it .github (don’t forget the dot!)
  4. Right-click on the .github folder and create another folder inside it called workflows
  5. Finally, right-click on workflows and select “New File”
  6. Name your file main.yml

Now, let’s add our workflow code. Copy and paste this into your main.yml file:

name: Hello World

on: [push]

jobs:

  say-hello:
    runs-on: ubuntu-latest

    steps:
      - name: Say hello
        run: echo "Hello, GitHub Actions!"

      - name: Tell us the time
        run: date

VS Code setup Figure 2: Your first workflow file in VS Code

Understanding What You Just Wrote

Let’s break down what each line does as you look at your code:

  • name: Hello World - This names your workflow. You’ll see this in the Actions tab later.
  • on: [push] - This is your trigger! It tells GitHub Actions to run this workflow whenever you push code.
  • jobs: - This starts the section where you define what work needs to be done.
  • say-hello: - This is the name of your job. A workflow can have multiple jobs.
  • runs-on: ubuntu-latest - This tells GitHub to use a Linux computer for this job. (We’ll explain more about this later!)
  • steps: - These are the individual tasks within your job.
  • Each step has a name (describing what it does) and a run command (the actual command to execute).

Notice how the indentation creates a hierarchy? That’s YAML’s way of showing relationships - the steps belong to the job, the job belongs to the workflow.

Running Your Workflow

Here comes the exciting part - let’s get this workflow running! We need to save our file and push it to GitHub.

First, let’s stage our new workflow file:

  1. Click the Source Control icon in VS Code’s sidebar (it looks like a branching tree)
  2. You’ll see main.yml listed under “Changes”
  3. Click the + icon next to it to stage the file

Stage workflow file Figure 3: Staging your workflow file

Now let’s commit our changes:

  1. In the message box at the top of the Source Control panel, type: “Add Hello World workflow”
  2. Click the “Commit” button (the checkmark icon)

Commit workflow Figure 4: Committing your workflow

Time to push to GitHub! You’ll notice the Commit button has changed to “Sync Changes”:

Sync changes button Figure 5: Ready to sync with GitHub

Click “Sync Changes”. VS Code will show you a confirmation:

Sync confirmation Figure 6: Confirming the sync operation

Click “OK” to proceed. VS Code is now pushing your workflow to GitHub!

Watching the Magic Happen

Now for the moment of truth! Head over to your repository on GitHub and click the “Actions” tab. You should see your workflow already running or completed:

GitHub Actions tab Figure 7: Your workflow in action!

See that green checkmark? That means your workflow ran successfully! Click on “Add Hello World workflow” to see more details about your run.

Workflow summary Figure 8: Workflow run summary - notice the success status and timing

On this page, you can see:

  • The trigger that started the workflow (a push event)
  • The success status and how long it took (10 seconds!)
  • The jobs that ran (our “say-hello” job)
  • Any warnings or annotations (don’t worry about the Ubuntu version warning for now)

Click on the “say-hello” job to dive deeper into what actually happened:

Job steps collapsed Figure 9: Your job’s steps - click to expand and see the details

You’ll see four steps listed. Notice how GitHub automatically added “Set up job” and “Complete job”? These are standard steps that prepare and clean up the runner environment. Click on each step to expand it:

Job steps expanded Figure 10: Expanded view showing exactly what happened in each step

Let’s look at what each step did:

  • Set up job: GitHub prepared the Ubuntu runner with all necessary tools
  • Say hello: Your custom message “Hello, GitHub Actions!” appears right there!
  • Tell us the time: Shows exactly when your workflow ran
  • Complete job: GitHub cleaned up after your job finished

Congratulations! πŸŽ‰ You’ve just created and run your first GitHub Actions workflow! Take a moment to appreciate what just happened - you wrote some code, pushed it to GitHub, and GitHub automatically executed your instructions on a computer in the cloud.

In the next section, we’ll dive deeper into what actually happened behind the scenes, especially that mysterious ubuntu-latest runner. But for now, enjoy that green checkmark - you’ve earned it!

Understanding What Just Happened

Remember that feeling of seeing your workflow run successfully? Let’s peek under the hood and understand what actually happened. This knowledge will help you debug issues later and make more informed choices as your workflows grow more complex.

About Runners

Remember that line in your workflow that said runs-on: ubuntu-latest? You might have wondered, “What exactly is Ubuntu, and where is it running?” Let’s demystify this!

A runner is simply a server that executes your workflow. Think of it as a fresh computer that GitHub provides just for running your jobs. When your workflow triggered, GitHub did something remarkable:

  1. It spotted your runs-on: ubuntu-latest instruction
  2. It spun up a brand new virtual machine running Ubuntu Linux
  3. It ran all your steps on this machine
  4. When done, it destroyed the machine completely

This happens in seconds, automatically, every single time your workflow runs. Pretty amazing, right?

Why Ubuntu?

Ubuntu is a popular Linux operating system. When you specify ubuntu-latest, you’re telling GitHub: “Give me a Linux computer with a standard set of development tools already installed.” This includes things like:

  • Git (for checking out your code)
  • Various programming language runtimes
  • Common command-line tools
  • Package managers for installing additional software

The “latest” part means you’ll always get the most recent stable version that GitHub supports. Right now, that warning you saw about ubuntu-latest moving to Ubuntu 24.04? That’s just GitHub giving you a heads-up that they’re updating to a newer version. Your simple workflow will work just fine with any version!

GitHub-hosted vs Self-hosted Runners

What we just used is called a GitHub-hosted runner - GitHub manages everything for you. It’s like having a free computer in the cloud that appears when you need it and vanishes when you’re done. Perfect for getting started!

There’s another type called self-hosted runners where you provide your own computers to run workflows. Some teams use these for special requirements, but GitHub-hosted runners are fantastic for most needs. We’ll stick with GitHub-hosted runners throughout this series.

Reading the Logs

Now, let’s decode those logs you saw. Understanding logs is a superpower that will help you troubleshoot issues and understand exactly what your workflows are doing.

Remember when you expanded the steps? Let’s break down what you saw:

The Automatic Steps

GitHub automatically adds some steps to every job:

  1. Set up job - This is GitHub preparing your runner. In the logs, you saw things like:

    • Current runner version
    • Operating system details
    • Available tools and their versions

    This setup ensures your job has everything it needs to run successfully.

  2. Complete job - After your custom steps finish, GitHub cleans up. This includes:

    • Uploading any logs or artifacts
    • Cleaning up temporary files
    • Reporting the final status

These automatic steps are why your 2-step workflow showed 4 steps in the logs!

Your Custom Steps

Between the automatic steps, you saw your actual work:

  • Say hello: The log showed the exact command (echo "Hello, GitHub Actions!") and its output
  • Tell us the time: The date command and the actual timestamp

Notice how each step shows:

  • A green checkmark (βœ“) for success
  • The time it took to run (measured in seconds)
  • The exact commands that ran
  • Any output those commands produced

Success vs Failure

Your workflow showed green checkmarks everywhere - that’s what success looks like! But what happens when something goes wrong?

  • Green checkmark (βœ“): Step completed successfully
  • Red X (βœ—): Step failed and stopped the workflow
  • Yellow warning (⚠): Step has warnings but didn’t fail

When a step fails:

  1. Subsequent steps in that job won’t run (by default)
  2. The logs will show the error message
  3. GitHub will send you a notification (if you have them enabled)
  4. The workflow will be marked as failed in the Actions tab

The beauty of logs is they tell you exactly what went wrong and where. No more guessing why something didn’t work!

Making Sense of It All

What you’ve accomplished is actually quite sophisticated:

  1. You defined a workflow in code (Infrastructure as Code!)
  2. GitHub automatically provisioned a computer for you
  3. Your commands ran in a clean, isolated environment
  4. Everything was logged for full transparency
  5. The computer was cleaned up automatically

This is the same pattern whether you’re running simple echo commands or deploying applications to production. The concepts you’ve learned today scale all the way up to enterprise-level automation.

In our next section, we’ll look at common issues you might encounter and how to fix them. But first, take a moment to appreciate that you’re now officially automating with GitHub Actions!

Troubleshooting Common Issues

Even with the best instructions, you might run into a few bumps along the way. Don’t worry - every developer has been there! Let’s look at the most common issues you might face and how to solve them. Think of this as your “first aid kit” for GitHub Actions.

Issue 1: “My Workflow Isn’t Running!”

Symptoms: You pushed your code, but nothing appears in the Actions tab.

Common Causes and Solutions:

  1. Wrong file location

    • βœ… Correct: .github/workflows/main.yml
    • ❌ Common mistakes: .github/workflow/main.yml (missing ’s’), github/workflows/main.yml (missing dot)
    • Fix: Double-check your folder structure. The dot in .github is crucial!
  2. File naming issues

    • Your workflow file must end in .yml or .yaml
    • Fix: Rename your file if needed. Both extensions work!
  3. Branch mismatch

    • If your workflow has branch filters, make sure you’re pushing to the right branch
    • Fix: Check which branch you’re on with git branch

Issue 2: “Failed to Parse YAML”

Symptoms: Your workflow shows a red X immediately with an error about YAML syntax.

The Golden Rule: YAML cares deeply about indentation!

Here’s what to watch for:

# ❌ WRONG - Mixed indentation
name: My Workflow
on: [push]
jobs:
  my-job:
   runs-on: ubuntu-latest  # Only 3 spaces!
    steps:  # Now 4 spaces - inconsistent!

# βœ… CORRECT - Consistent 2-space indentation
name: My Workflow
on: [push]
jobs:
  my-job:
    runs-on: ubuntu-latest  # 4 spaces (2 levels)
    steps:  # 4 spaces (same level)
      - name: My Step  # 6 spaces (3 levels)
        run: echo "Hello"  # 8 spaces (4 levels)

Quick Fixes:

  • Use spaces, not tabs (configure your editor to convert tabs to spaces)
  • Each indentation level should be exactly 2 spaces
  • VS Code can help: Select all your YAML and use “Format Document” (Shift+Alt+F)

Issue 3: “Permission Denied” Errors

Symptoms: Your workflow fails with messages about permissions.

Common Scenario: Trying to run a script file that isn’t executable.

Fix: Make your script executable before committing:

chmod +x myscript.sh
git add myscript.sh
git commit -m "Make script executable"
git push

Issue 4: “Resource Not Accessible by Integration”

Symptoms: Your workflow fails when trying to do something with your repository.

What’s Happening: GitHub Actions has security permissions that sometimes need adjustment.

Quick Fix: For now, just know this exists. We’ll cover permissions in detail in a future article. If you see this error, it usually means your workflow is trying to do something it doesn’t have permission for yet.

Debugging Like a Pro

When something goes wrong, here’s your debugging checklist:

  1. Check the Actions Tab First

    • Look for red X marks - they show exactly which step failed
    • Click through to see the detailed error message
  2. Read the Error Message Carefully

    • GitHub Actions provides helpful error messages
    • The line number where the error occurred is usually shown
    • Look for keywords like “syntax error”, “not found”, or “permission denied”
  3. Use the Raw Logs

    • Click the gear icon in the logs and select “View raw logs”
    • This shows everything without formatting - sometimes helpful for tricky issues
  4. Test Locally First

    • If a command fails in your workflow, try running it on your own computer
    • This helps determine if it’s a command issue or a GitHub Actions issue
  5. Add Debug Output

    • Temporarily add echo statements to understand what’s happening:
    - name: Debug info
      run: |
        echo "Current directory: $(pwd)"
        echo "Files here: $(ls -la)"
        echo "Who am I: $(whoami)"
    

The “Works on My Machine” Problem

Remember, GitHub Actions runs in a fresh environment every time. This means:

  • No files from previous runs exist
  • No software you installed in a previous run is available
  • Environment variables you set locally don’t exist

This is actually a feature! It ensures your workflows are reproducible and reliable.

Getting Help

Still stuck? Here’s where to find help:

  1. The error messages usually point you in the right direction
  2. The GitHub Actions documentation is comprehensive
  3. Stack Overflow has a growing collection of GitHub Actions questions
  4. The GitHub Community Forum has an Actions section

Remember: every expert was once a beginner who got stuck on YAML indentation. You’re in good company!

What’s Next

Wow, what a journey! Let’s take a moment to appreciate everything you’ve accomplished in this article. You’ve gone from knowing nothing about GitHub Actions to successfully creating and running your own automated workflow. That’s huge!

What You’ve Learned

You now understand:

  • What GitHub Actions is - Your tireless automation assistant that never sleeps
  • How workflows work - From triggers to runners to completed jobs
  • The key components - Workflows, events, jobs, steps, and how they fit together
  • How to create workflows - You built your first one from scratch!
  • How to read the logs - No more mystery about what’s happening behind the scenes
  • What runners are - Those magical computers in the cloud that run your code
  • How to troubleshoot - You have your debugging toolkit ready

But here’s the best part: everything you learned today scales up. The same concepts that power your “Hello World” workflow are used by teams deploying applications millions of people use every day. You’re now part of the automation revolution!

Coming Up Next: Taking Control with Triggers

In our next article, we’ll explore one of the most powerful features of GitHub Actions: triggers. Right now, your workflow runs every time you push code. But what if you want more control?

In Part 4, you’ll learn how to:

  • Run workflows only when specific files change
  • Trigger workflows on pull requests for code review automation
  • Set up different workflows for different branches
  • Combine multiple triggers for sophisticated automation

Imagine having workflows that automatically run tests when someone opens a pull request, or only deploy when changes are made to your main branch. That’s the power of triggers, and that’s what we’ll build together next time!

Your Homework (Optional but Fun!)

Before we meet again, why not experiment a bit? Here are some ideas:

  • Modify your workflow to print a custom message
  • Add more steps to your workflow
  • Try making a step fail on purpose to see what happens
  • Create a second workflow file and watch them both run

Remember, you can’t break anything - GitHub Actions runs in isolation, so experiment freely!

Final Thoughts

You’ve taken your first steps into a larger world. GitHub Actions is used by millions of developers to automate everything from simple tasks to complex deployment pipelines. And now you’re one of them!

Every expert GitHub Actions user started exactly where you are now - with a simple “Hello World” workflow and a sense of curiosity. Keep that curiosity alive, keep experimenting, and most importantly, have fun automating!

Thank you for joining me on this journey. I can’t wait to see what you’ll automate next!

See you in Part 4: Understanding Push and Pull Request Triggers where we’ll take your GitHub Actions skills to the next level! πŸš€


Have questions or want to share your first workflow? Drop a comment below - I’d love to hear about your experience!

Ahmed Muhi

About Ahmed Muhi

Principal Cloud and DevOps Consultant, Microsoft Azure MVP with 20 years in the industry. I guide clients through their cloud journey, specializing in Azure solutions. When not architecting cloud solutions, I create content on my YouTube channel and run the Aotearoa Azure Meetup. Always learning, always sharing! πŸš€

Comments