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 1The model everything else assumes
Section titled “The model everything else assumes”Event ↓Workflow ↓Job ↓Runner ↓Step ↓Shell command or actionSix 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.
What this cluster covers
Section titled “What this cluster covers”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.
Prerequisites
Section titled “Prerequisites”| You should be able to | Covered in |
|---|---|
| Commit and push to a branch | Your First Git Repository |
| Explain what a pull request is | Pull Requests Explained |
| Read a workflow run’s logs | gh 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.
Learning objectives
Section titled “Learning objectives”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_OUTPUTrather than deprecated syntax. - Use contexts and expressions, and recognise which context data is attacker-controlled.
The learning path
Section titled “The learning path”- 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.
- 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.
- 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.
- 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.
- Lesson 5: 05. JobsJobs run in parallel on separate runners and share nothing. Learn needs, conditions, outputs, job permissions, timeouts, containers and service containers.
- Lesson 6: 06. StepsSteps are shell commands or actions. Learn ids, names, with, env, shell selection, working directories, conditions, outputs and continue-on-error.
- 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.
- 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.
- 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.
- 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.
- 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.
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.
Difficulty and pacing
Section titled “Difficulty and pacing”The cluster is ordered so each lesson can assume the previous ones, but difficulty is not uniform.
| Lessons | Level | Why |
|---|---|---|
| What Is GitHub Actions? → Actions Explained | Beginner | Concepts and structure; nothing subtle |
| Environment Variables, Secrets | Beginner | Simple mechanics, real security consequences |
| Outputs | Beginner → Intermediate | Passing values between isolated jobs |
| Contexts and Expressions | Intermediate | The 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.
A note on YAML
Section titled “A note on YAML”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.
onis a word YAML 1.1 parsers may read as a boolean. GitHub parses it as the stringon, 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.10is 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.
Reading a workflow you did not write
Section titled “Reading a workflow you did not write”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.
What this cluster does not cover
Section titled “What this cluster does not cover”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.
The exercises build one repository
Section titled “The exercises build one repository”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.
If something does not work
Section titled “If something does not work”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.
Then what?
Section titled “Then what?”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?