Part 2: YAML Syntax and Workflow Fundamentals

Introduction

When I first started writing GitHub Actions workflows, I made a costly mistake: I indented with tabs instead of spaces in my YAML file. The workflow failed with a cryptic error message, and it took me an hour to figure out why. YAML is notoriously picky about formatting, but once you understand its rules, it becomes a powerful way to define your automation.

In this part, I'll teach you everything about YAML syntax for GitHub Actions, based on the mistakes I've made and the patterns I've refined in production workflows.

YAML Basics for GitHub Actions

What is YAML?

YAML (YAML Ain't Markup Language) is a human-readable data serialization format. GitHub Actions uses YAML to define workflows.

Key Rules:

  • Use spaces for indentation (never tabs!)

  • Indentation matters (like Python)

  • Use 2 spaces per indentation level

  • Case-sensitive

  • Comments start with #

Basic YAML Syntax

# This is a comment

# String (no quotes needed)
name: CI Pipeline

# String with quotes (needed for special characters)
message: "Hello, World!"

# Number
timeout: 30

# Boolean
enabled: true
disabled: false

# List (array)
branches:
  - main
  - develop
  - staging

# Alternative list syntax
branches: [main, develop, staging]

# Object (dictionary/map)
environment:
  name: production
  url: https://api.example.com

# Nested structures
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3

Complete Workflow Structure

Here's the complete structure of a GitHub Actions workflow file:

Workflow Triggers (on)

Push Events

Real example from my API service:

Pull Request Events

Release Events

My production deployment workflow:

Scheduled Events (Cron)

My dependency update check:

Manual Workflow Dispatch

Multiple Triggers

Jobs Configuration

Basic Job

Job Dependencies

My production workflow:

Conditional Jobs

Job Outputs

Steps Configuration

Using Actions

Running Commands

Environment Variables in Steps

Conditional Steps

Environment Variables and Secrets

Workflow-Level Environment Variables

Job-Level Environment Variables

Using Secrets

Setting secrets in GitHub:

  1. Go to repository Settings

  2. Click Secrets and variables → Actions

  3. Click "New repository secret"

  4. Add name and value

Default Environment Variables

GitHub provides built-in environment variables:

Complete list of useful variables:

Context and Expressions

Using Contexts

Expressions and Functions

Status Check Functions

Service Containers

PostgreSQL:

Redis:

Multiple Services:

Matrix Strategy

With includes and excludes:

My real-world matrix:

Complete Real-World Example

Here's my complete CI workflow for a TypeScript microservice:

Key Takeaways

  1. YAML is whitespace-sensitive: Always use spaces, never tabs

  2. Triggers are flexible: Use push, pull_request, schedule, workflow_dispatch

  3. Jobs can depend on each other: Use needs to create pipelines

  4. Service containers are powerful: Test with real databases easily

  5. Matrix builds test multiple configurations: Test across different Node versions, OS, etc.

  6. Secrets keep sensitive data safe: Never hardcode credentials

  7. Expressions enable conditional logic: Run steps/jobs only when needed

In the next part, we'll dive deeper into building complete CI/CD pipelines specifically for TypeScript microservices.

Last updated