GITHUB ACTIONS, ONE SMALL STEP AT A TIME

Your first workflow.
Without the guesswork.

Pick a starting point, see the YAML take shape, and learn what each piece means. No sign-in. No tokens. Everything stays in your browser.

Build a workflow Free · static · beginner-friendly

01 / THE WORKBENCH

Start small. Make it yours.

Generating a file does not run a workflow.

1. Choose a starting point

The friendly name shown in the Actions tab.

A simple name ending in .yml or .yaml, e.g. build.yml.

2. Decide when it runs

Blank means all branches. Applies to push and PR target branches, not manual or scheduled runs. Simple names and * globs only; no negation.

17 9 * * 1-5 = weekdays at 09:17 UTC. Numeric fields, lists, ranges and /steps supported. At least 5 minutes apart. Schedules use the default branch and can be delayed; public inactive repos may have schedules disabled after 60 days.

3. Set up the job & step

All command steps use Bash, including on Windows. Make and CMake templates require Ubuntu's preinstalled build tools. Hosted images change over time.

Repository-relative folder, e.g. . or src. It must already exist. No absolute paths, .. or shell syntax.

Available as "$LEARNING_MESSAGE" in Bash. Plain text only; never enter secrets.

Only use commands you understand. These run later on GitHub, not here. Raw Actions expressions are deliberately rejected in commands; pass context values through env instead. Shell correctness and project files are your responsibility.

Your workflow

YAML

Read-only repository permission. Immutable action SHAs. No saved credentials. No backend execution.

02 / THE BASICS

Read YAML like a recipe.

Open a lesson. Try one idea at a time.

1. Spaces tell you what belongs where

Use spaces, never tabs. This app uses two spaces per level. Children are indented beneath a parent; siblings line up. A wrong indent can change the meaning, even if the YAML still parses.

jobs:
  build:
    runs-on: "ubuntu-latest"

build belongs to jobs; runs-on belongs to build.

2. Mappings, lists, strings & quotes

A mapping is key: value. A list uses - for each item. Strings are text. Quote text such as "3.13", "yes", or "hello: world" to avoid accidental numbers, booleans or mappings. Inside double quotes, escaped characters such as \n mean a newline.

steps:
  - name: "Say hello"
    run: "echo hello"

| introduces a multiline string that preserves line breaks. YAML 1.1 tools can misread unquoted on as a boolean; the generator quotes keys too, so "on" stays a string.

3. The workflow's six building blocks

name: display label. on: events that start runs. jobs: work grouped into jobs. runs-on: the runner machine. steps: ordered tasks within a job. A step either uses a reusable action or runs commands with run.

Jobs usually run in parallel; steps in one job run in order. Checkout downloads your repository before commands can use its files. with supplies inputs to an action.

4. Pick events deliberately

push reacts to commits. pull_request checks proposed changes (normally the merge result), and branch filters refer to the PR's base branch. A branch filter on push excludes tag pushes. workflow_dispatch enables manual runs once the workflow exists on the default branch.

schedule uses UTC cron: minute, hour, day of month, month, day of week (0 or 7 = Sunday). Both day fields are matched with OR if both are restricted. Schedule files must exist on the default branch. This tool supports a small numeric cron subset, not every possible Actions configuration.

5. Expressions, contexts, env & secrets

An expression like ${{ github.ref }} reads a context value. Contexts include github (run metadata), env (variables) and secrets (configured secrets). Shell $LEARNING_MESSAGE is different: Bash expands an environment variable at runtime.

- name: "Read a branch safely"
  env:
    BRANCH: ${{ github.head_ref }}
  run: |
    printf '%s\n' "$BRANCH"

Never insert event text directly into run, use eval, or execute untrusted branch text. The example passes it as data through env. To use a secret, configure it in repository Settings > Secrets and variables > Actions, then reference ${{ secrets.MY_SECRET }} through an action input or env. Never paste values here, commit them, or print secrets. Fork PRs normally do not receive repository secrets.

6. Permissions & pinned actions

permissions: contents: read limits the automatic GITHUB_TOKEN to reading repository contents; unspecified permissions are none. Checkout uses persist-credentials: false. This tool intentionally excludes pull_request_target and deployment/write-token templates.

Actions are dependencies. A full commit SHA is immutable; a tag such as @v7 can move. Generated files pin reviewed official action revisions and include version comments. Review updates (for example with Dependabot); pinning alone does not guarantee an action is safe. These Node 24 actions target current GitHub-hosted runners, not old self-hosted installations.

A quick check

Which key picks the machine that executes a job?

Choose an answer to check your understanding.

03 / FROM FILE TO FIRST RUN

Ready? Put it in your repository.

  1. Copy or download your YAML. Review every command and confirm the template's required project files exist.
  2. Create .github/workflows/ at your repository root. Save the file there, for example .github/workflows/ci.yml.
  3. Commit and push to GitHub (or use Add file in GitHub's web editor). Check your repository's Actions policy and runner usage limits.
  4. Open the repository's Actions tab. Choose the workflow, then a run to inspect each job's logs. For manual runs, add the file to the default branch first, then select Run workflow.

Valid YAML is not a guarantee of a successful run. Missing files, shell mistakes, dependency failures, repository policy and runner changes can still cause failures. This site never starts a workflow or contacts GitHub's API.