A workflow is an automated process defined in a YAML file that GitHub Actions executes. It contains all the instructions for what should happen when triggered.
Workflow files must be placed in:
.github/workflows/
All files should be .yml or .yaml format.
name: My Workflow
on: push
jobs:
my-job:
runs-on: ubuntu-latest
steps:
- name: My Step
run: echo "Hello!"The name of your workflow (displayed in GitHub UI):
name: Build and TestWhen should this workflow run? See Triggers and Events for details:
on: pushContains one or more jobs that will run:
jobs:
build:
runs-on: ubuntu-latest
steps:
# steps hereA job is a collection of steps that run on the same runner (machine).
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: npm install
- run: npm test
- run: npm build| Property | Description |
|---|---|
runs-on |
The type of machine to run on |
steps |
Array of steps to execute |
needs |
Job dependencies (other jobs that must complete first) |
if |
Conditional execution |
strategy |
Matrix strategy for multiple configurations |
environment |
Environment name for this job |
A step is a single action in a job. Steps run sequentially on the same runner.
- run: echo "Hello World"- uses: actions/checkout@v3- name: Check out code
uses: actions/checkout@v3steps:
- name: Install dependencies
run: npm install
working-directory: ./app
shell: bash
if: success()| Property | Description |
|---|---|
name |
Human-readable name (displayed in logs) |
run |
Command line program to run |
uses |
Action to use (from marketplace or local) |
with |
Input parameters for actions |
env |
Environment variables |
if |
Conditional execution |
working-directory |
Working directory for this step |
Jobs run in parallel by default:
jobs:
test:
runs-on: ubuntu-latest
steps:
- run: npm test
lint:
runs-on: ubuntu-latest
steps:
- run: npm run lintBoth test and lint run at the same time!
Make one job wait for another:
jobs:
test:
runs-on: ubuntu-latest
steps:
- run: npm test
deploy:
needs: test # Wait for 'test' job to complete
runs-on: ubuntu-latest
steps:
- run: npm run deployNow deploy only runs after test completes successfully.
A runner is a server that executes your jobs.
runs-on: ubuntu-latest # Linux
runs-on: macos-latest # macOS
runs-on: windows-latest # Windows| Runner | OS | Pre-installed Tools |
|---|---|---|
ubuntu-latest |
Ubuntu 22.04 | Node, Python, Go, Ruby, Docker |
macos-latest |
macOS 13 | Xcode, Node, Python, Ruby |
windows-latest |
Windows Server 2022 | Visual Studio, Node, Python |
name: Build, Test, and Deploy
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
name: Build Application
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: npm install
- name: Build app
run: npm run build
test:
name: Run Tests
runs-on: ubuntu-latest
needs: build
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: npm install
- name: Run tests
run: npm test
deploy:
name: Deploy to Production
runs-on: ubuntu-latest
needs: test
if: github.ref == 'refs/heads/main'
steps:
- name: Deploy
run: echo "Deploying to production..."Execution Flow:
buildandtestare triggeredtestwaits forbuildto completedeployonly runs iftestsucceeds AND we're on main branch
✅ Use clear, descriptive names for workflows and steps
✅ Use actions from the marketplace instead of custom scripts
✅ Cache dependencies to speed up workflows
✅ Use conditions to prevent unnecessary runs
✅ Set timeouts to prevent hung workflows
✅ Keep workflows simple and focused
❌ Not checking out code with actions/checkout
❌ Using run instead of uses for actions
❌ Forgetting to set required with parameters
❌ Making jobs dependent when they should run in parallel
❌ Not using failure conditions properly
- Triggers and Events - Learn what events trigger workflows
- Jobs and Steps - Deep dive into jobs and steps
- Secrets and Environment Variables - Manage sensitive data
You now understand workflow basics! Ready to learn about triggers?