Skip to content

GitHub Actions Fundamentals

7 min readGitHub Actions & CI/CD · Actions Fundamentals

Almost every problem people have with GitHub Actions comes from one of three places: not knowing which layer a setting belongs to, not knowing where a value comes from, or not knowing why a workflow did not run.

This cluster fixes all three, in that order.

Start with Lesson 1
Event
Workflow
Job
Runner
Step
Shell command or action

Six layers, and nearly every configuration key belongs to exactly one of them. permissions can be set on a workflow or a job. env can be set on a workflow, a job or a step. runs-on is a job property and means nothing anywhere else. with belongs only to a step that uses an action.

Holding the layers straight is most of what makes workflow YAML readable rather than a soup of keys that seem to work in some places and not others.

The eleven lessons fall into three groups.

The shape — what GitHub Actions is, a first workflow written line by line, and the YAML you actually need. Three lessons, and after them you can read most workflows you encounter.

The structure — events and triggers, jobs, steps, and what an action is. Four lessons covering the layers above, each in the detail the others assume.

The data — environment variables, secrets, outputs, and contexts and expressions. Four lessons about how values enter a workflow, move between its parts, and get used safely.

That last group is where most real difficulty lives. Writing a workflow that runs is easy; writing one that passes a value from a step in one job to a condition in another, without leaking anything into a log, is where the platform gets genuinely intricate.

You should be able toCovered in
Commit and push to a branchYour First Git Repository
Explain what a pull request isPull Requests Explained
Read a workflow run’s logsgh run
Work at a shell prompt

No prior CI experience is assumed. Some YAML familiarity helps and is not required — Lesson 3 teaches the subset that matters.

By the end of this cluster you should be able to:

  • Explain what happens between a push and a job running, and name each layer.
  • Write a workflow from scratch without copying one.
  • Read YAML confidently, including the constructs that behave unexpectedly.
  • Choose a trigger deliberately, filter it by branch or path, and say why some triggers are security-sensitive.
  • Structure work across jobs, with dependencies and conditions, rather than one long job.
  • Distinguish a shell step from an action step, and know when each is appropriate.
  • Explain what an action is, where it comes from, and why its version reference matters.
  • Move values between steps and jobs correctly, using $GITHUB_OUTPUT rather than deprecated syntax.
  • Use contexts and expressions, and recognise which context data is attacker-controlled.
  1. Lesson 1: 01. What Is GitHub Actions?GitHub Actions runs code in response to repository events. Learn workflows, jobs, runners, steps and actions — and how the platform compares with Jenkins, shell scripts and GitHub Apps.Beginner10 min read
  2. Lesson 2: 02. Your First WorkflowBuild a workflow from an empty repository — create the file, understand every line, push it, read the run, break it deliberately, and fix it.Beginner11 min read
  3. Lesson 3: 03. YAML SyntaxThe YAML that workflows actually need — indentation, quoting, multiline strings, the top-level keys, and the constructs that silently do the wrong thing.Beginner12 min read
  4. Lesson 4: 04. Events and TriggersEvery trigger a workflow can use — push, pull_request, schedule, workflow_dispatch, workflow_call and more — with branch and path filters, activity types and the security differences that matter.Beginner12 min read
  5. Lesson 5: 05. JobsJobs run in parallel on separate runners and share nothing. Learn needs, conditions, outputs, job permissions, timeouts, containers and service containers.Beginner11 min read
  6. Lesson 6: 06. StepsSteps are shell commands or actions. Learn ids, names, with, env, shell selection, working directories, conditions, outputs and continue-on-error.Beginner10 min read
  7. Lesson 7: 07. Actions ExplainedAn action is reusable code a step calls with uses. Learn Marketplace, repository and local actions, the three implementation types, version references and the security they carry.Beginner11 min read
  8. Lesson 8: 08. Environment Variablesenv at three scopes, default variables, $GITHUB_ENV, repository and organisation variables, the vars context, precedence and the difference from secrets.Beginner11 min read
  9. Lesson 9: 09. SecretsRepository, environment and organisation secrets, the secrets context, log masking and its limits, fork behaviour, rotation, and why OIDC removes most cloud secrets entirely.Beginner13 min read
  10. Lesson 10: 10. OutputsStep outputs with $GITHUB_OUTPUT, job outputs, reusable workflow outputs, structured values, size limits and the security of what you pass along.Beginner → Intermediate10 min read
  11. Lesson 11: 11. Contexts and ExpressionsEvery GitHub Actions context and the expression syntax — github, env, secrets, needs, steps, matrix, inputs — plus the injection mistake that turns a PR title into a shell command.Intermediate14 min read

Three things worth knowing before you start

Section titled “Three things worth knowing before you start”

Workflows live in your repository. They are versioned, reviewed and diffed like code — and a change to one changes what runs with your repository’s credentials. This is why workflow files deserve more review scrutiny than most code, not less.

Jobs are isolated from each other. Each job gets its own runner, its own filesystem and its own clean environment. Two jobs in the same workflow share nothing automatically — not files, not variables, not the checked-out repository. Passing anything between them is deliberate, using outputs or artifacts.

Not everything that looks like a variable is one. ${{ }} is an expression evaluated by GitHub before the shell ever sees it. $VAR is a shell variable evaluated by the shell. They look similar, behave completely differently, and the difference is the root of both a common class of bug and a common class of vulnerability.

The cluster is ordered so each lesson can assume the previous ones, but difficulty is not uniform.

LessonsLevelWhy
What Is GitHub Actions? → Actions ExplainedBeginnerConcepts and structure; nothing subtle
Environment Variables, SecretsBeginnerSimple mechanics, real security consequences
OutputsBeginner → IntermediatePassing values between isolated jobs
Contexts and ExpressionsIntermediateThe evaluation model, and untrusted input

The last lesson is the longest and the most reference-like. It is the one people return to, and it is worth reading once properly before using it as a lookup.

Workflow files are YAML, and YAML has a small number of behaviours that produce genuinely confusing failures:

  • Indentation is structural. Two spaces versus four changes meaning, and tabs are invalid.
  • on is a word YAML 1.1 parsers may read as a boolean. GitHub parses it as the string on, which is why it works — but a local linter using a YAML 1.1 library may disagree with GitHub about your file.
  • Unquoted values get type-guessed. version: 3.10 is the number 3.1; version: "3.10" is the string you meant. This one silently breaks language version matrices.
  • Multiline strings have several forms, and | versus > is the difference between preserving newlines and folding them.

YAML Syntax covers these properly rather than teaching YAML in general. The 3.10 case alone justifies the lesson.

A practical skill worth naming, since you will do it far more often than writing one from scratch. Read in this order:

Those four answers tell you what a workflow does and what it risks, usually in under a minute, without reading a single step.

Language-specific pipelines. Building and testing Python or Go is the Continuous Integration cluster. Here, examples are deliberately trivial so the mechanism stays visible.

Deployment. Nothing here deploys anything. Environments, approvals and cloud credentials are later, and they build on this.

Reusable workflows and custom actions. Consuming an action is covered; authoring one is Advanced.

Security in depth. Permissions, secrets handling and untrusted input appear where they are relevant — every lesson raises them — but the systematic treatment is the Security cluster.

Each lesson has an exercise, and they accumulate rather than starting over. By the end of the cluster you will have a repository containing:

  • A workflow triggered on pushes, pull requests and manual dispatch
  • Several jobs, some parallel and some dependent
  • Values passed between steps and between jobs
  • A secret consumed safely, and a demonstration of masking’s limits
  • A conditional step gated on branch, event and label
  • Annotations and a job summary that render on the run page

That is a working reference implementation of everything in the cluster, in one place you can return to. Keeping it is worth more than the individual exercises — later clusters extend it rather than introducing new scaffolding.

The three failure modes that account for most early problems, with their signatures:

Nothing happened. The trigger did not match — wrong branch, wrong path, wrong event, or the file is not on the branch you pushed to. Silence rather than an error is the signature.

“No such file or directory”. The runner started empty and nothing checked out the repository, or you expected a file from another job. Jobs share nothing.

An empty value where you expected one. A missing id, an output not declared at job level, a needs that is absent, or a context unavailable in that position. Expressions evaluate to empty rather than failing, which makes these quiet.

Each has a lesson that covers it properly, and recognising the signature is usually enough to know which one.

With the fundamentals in place, the next cluster builds real pipelines: Continuous Integration works through eight complete workflows for actual project types, each with dependency caching, matrix testing and artifacts.

If you already have CI and are here to improve it, Advanced GitHub Actions and the Security cluster are the ones to go to next.

Begin: What Is GitHub Actions?