Skip to content

GitHub Actions Workflow Syntax: YAML, Triggers & Jobs

DodaTech Updated 2026-06-21 2 min read

GitHub Actions workflow files use YAML syntax with specific keywords for triggers, jobs, steps, and conditions, giving you fine-grained control over every part of the pipeline.

What You'll Learn

In this tutorial, you'll learn the complete workflow YAML syntax -- event filters, job configuration, conditional execution with if, environment variables, and output passing between jobs.

Why It Matters

A workflow file with incorrect syntax silently fails to run. Understanding every keyword -- on, jobs, steps, with, env, if, continue-on-error -- means your pipelines run reliably and you can Express complex automation logic without trial and error.

Real-World Use

Durga Antivirus Pro's release workflow uses conditional execution to run different steps for release candidates versus stable releases, passes build artifacts between jobs, and uses environment variables to inject version numbers without hardcoding.

Event Triggers in Detail

Workflows can trigger on many events:

on:
  push:
    branches:
      - main
      - "release/**"
tags:
      - "v*"
    paths:
      - "src/**"
      - "!docs/**"
  pull_request:
    types: [opened, synchronize, reopened]
  schedule:
    - cron: "0 6 * * 1-5"
  workflow_dispatch:
    inputs:
      environment:
        description: "Target environment"
        required: true
        default: staging

Job Configuration

Jobs support extensive configuration:

jobs:
  test:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    strategy:
      matrix:
        node-version: [18, 20, 22]
    env:
      NODE_ENV: test
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
      - run: npm ci
      - run: npm test

Conditional Execution

Use if for conditional steps:

jobs:
  deploy:
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main' && success()
    steps:
      - run: echo "Deploying to production"

  notify:
    runs-on: ubuntu-latest
    if: failure()
    steps:
      - run: echo "Workflow failed"

Passing Outputs Between Jobs

jobs:
  version:
    runs-on: ubuntu-latest
    outputs:
      version: ${{ steps.get-version.outputs.version }}
    steps:
      - id: get-version
        run: echo "version=1.2.3" >> $GITHUB_OUTPUT

  build:
    needs: version
    runs-on: ubuntu-latest
    steps:
      - run: echo "Building version ${{ needs.version.outputs.version }}"

Practice Questions

1. How do you trigger a workflow only for specific file paths? Use paths filter under on.push or on.pull_request to include or exclude patterns.

2. What does continue-on-error: true do? It allows a step to fail without failing the entire job.

3. How do you pass a value from one job to another? Set the job output using $GITHUB_OUTPUT and reference it with needs.job_id.outputs.output_name.

4. What is the difference between if: success() and if: always()? success() runs only if all previous steps succeeded. always() runs regardless of previous step results.

5. Challenge: Write a workflow with two jobs. The first job generates a version number. The second job uses that version to create a build artifact.

Mini Project: Multi-Environment Release Workflow

Create a workflow that runs tests, then builds and deploys to staging when merging to main, and deploys to production when a tag starting with v is pushed. Use conditional execution, environment variables, and job outputs. Add a manual trigger option with an environment selector.

Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro