Skip to main content

Using Advanced Workflow Features

1. Creating Workflow Templates

Example: Basic workflow template structure

name: "Template Example"
on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "20"
      - run: npm ci
      - run: npm test
Field Description Notes
name Workflow name Used in UI and logs
on Triggers for the workflow Can include events like push, pull_request, schedule
jobs Workflow jobs to run Each job runs in a separate runner
Note: Templates can be stored in a .github/workflows directory and reused across repositories.

Template Best Practices

  • Use inputs to make templates configurable
  • Store templates in a central repository or organization
  • Use defaults to set common settings across jobs

2. Implementing Workflow Dispatch Inputs

Input Type Description Default Value
workflow_dispatch object Triggers workflow on manual dispatch null

Example: Workflow Dispatch with Inputs

name: "Manual Workflow"
on:
  workflow_dispatch:
    inputs:
      environment:
        description: "Target environment"
        required: true
        default: "staging"
      debug:
        description: "Enable debug mode"
        required: false
        default: "false"

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Deploy to ${{ github.event.inputs.environment }}
        run: |
          echo "Deploying to ${{ github.event.inputs.environment }}"
          if [[ "${{ github.event.inputs.debug }}" == "true" ]]; then
            echo "Debug mode enabled"
          fi
Note: Inputs defined in workflow_dispatch are available as github.event.inputs.<input_name> in the workflow context.

3. Using Repository Dispatch

repository_dispatch is a GitHub Actions event that allows you to trigger workflows in one repository from another repository. It's useful for cross-repository automation and integration.

Field Description Example
type The type of the event (e.g., repository_dispatch) repository_dispatch
types Array of event types to trigger on ["custom_event"]
repository The repository to send the event to owner/repo

Example: Triggering a Workflow via Repository Dispatch

on:
  repository_dispatch:
    types: [custom_event]

jobs:
  trigger-workflow:
    runs-on: ubuntu-latest
    steps:
      - name: Log event
        run: |
          echo "Triggered by repository dispatch"
Note: The repository_dispatch event can be triggered using the GitHub API or via the GitHub UI in the repository's Actions tab.

Example: Sending a Repository Dispatch Event via API

curl -X POST \
  -H "Accept: application/vnd.github+json" \
  -H "Authorization: Bearer <token>" \
  https://api.github.com/repos/<owner>/<repo>/dispatches \
  -d '{"event_type": "custom_event", "client_payload": {"key": "value"}}'

4. Integrating with GitHub Apps

App Description Permissions Usage
GitHub App Name Third-party application that integrates with GitHub Read/Write access to repositories, issues, pull requests Can be installed on organization or user accounts
App ID Unique identifier for the GitHub App Used to authenticate and authorize API requests Required for webhook delivery and API access
Webhook URL Endpoint that receives events from GitHub Configured in the app settings Used to trigger workflows or update external systems

Example: Using GitHub App for CI/CD

name: CI/CD with GitHub App
on:
  push:
    branches: [ main ]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      - name: Run build
        run: |
          npm install
          npm run build
Note: GitHub Apps provide more granular permissions than personal access tokens.
Warning: Ensure the app has appropriate permissions to access required resources.

Key Points

  • GitHub Apps are more secure than personal access tokens.
  • They can be installed on organizations or user accounts.
  • Apps can listen to events and trigger workflows automatically.

5. Using Workflow Run API

Property Description Values
workflow_run.id Unique identifier for the workflow run 123456789
workflow_run.name Name of the workflow run Build and Test
workflow_run.status Status of the workflow run success, failure, pending, running
workflow_run.conclusion Conclusion of the workflow run success, failure, neutral, canceled
workflow_run.created_at Timestamp when the workflow run was created 2025-04-01T12:00:00Z
workflow_run.updated_at Timestamp when the workflow run was last updated 2025-04-01T13:00:00Z

Example: Fetching Workflow Run Details

const { GitHub } = require("@actions/github");

async function getWorkflowRunDetails() {
  const github = new GitHub(process.env.GITHUB_TOKEN);
  const runId = process.env.GITHUB_RUN_ID;

  const response = await github.rest.actions.getWorkflowRun({
    owner: "owner",
    repo: "repo",
    run_id: runId
  });

  console.log("Workflow Run ID:", response.data.id);
  console.log("Status:", response.data.status);
  console.log("Conclusion:", response.data.conclusion);
}

getWorkflowRunDetails();

Example: Triggering a Workflow Run

const { GitHub } = require("@actions/github");

async function triggerWorkflowRun() {
  const github = new GitHub(process.env.GITHUB_TOKEN);

  const response = await github.rest.actions.createWorkflowDispatch({
    owner: "owner",
    repo: "repo",
    workflow_id: "workflow.yml",
    inputs: {
      environment: "production"
    }
  });

  console.log("Workflow triggered with ID:", response.data.id);
}

triggerWorkflowRun();
Note: The workflow_run context is available in all workflows and can be used to access details about the current or previous workflow run.

6. Monitoring Workflow Quotas

Quota Type Limit Notes
Minutes of compute time 3000 minutes/month Free tier for public repositories; paid plans offer more
Storage 500 MB Per workflow run; artifacts and caches count toward this limit
Artifacts 1 GB Maximum size of artifacts stored per workflow run
Caches 5 GB Total cache size across all workflows in a repository
Concurrent runs 20 Maximum concurrent workflow runs per repository

Example: Checking Workflow Quotas via API

curl -H "Authorization: Bearer <token>" \
  https://api.github.com/repos/<owner>/<repo>/actions/workflows
Note: Quotas are reset monthly and can vary based on repository visibility and plan type.
Warning: Exceeding compute time limits may cause workflows to be canceled or delayed.

7. Using Workflow Visualization

Example: Viewing Workflow Graph

name: Workflow Visualization Example
on:
  push:
    branches: [ main ]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Setup Node
        uses: actions/setup-node@v4
        with:
          node-version: '20'
      - name: Install Dependencies
        run: npm ci
      - name: Run Tests
        run: npm test
Feature Description Availability
Workflow Graph Visual representation of job dependencies and execution order NEW GitHub Actions 2024
Job Dependencies Shows which jobs depend on others using arrows Standard
Execution Status Color-coded job status indicators (success, failure, skipped) Standard
Note: Workflow graphs are available in the GitHub UI under the "Actions" tab for any workflow run.

Key Features

  • Visualize job execution order
  • Identify dependencies between jobs
  • Quickly identify failed or skipped jobs

8. Creating Rerun Logic

Example: Basic rerun logic with manual trigger

name: Rerun Workflow
on:
  workflow_dispatch:
    inputs:
      job_id:
        description: 'Job ID to rerun'
        required: true
        type: string

jobs:
  rerun-job:
    runs-on: ubuntu-latest
    steps:
      - name: Rerun specific job
        run: |
          echo "Rerunning job with ID: ${{ github.event.inputs.job_id }}"
Property Description Values
workflow_dispatch Triggers workflow manually inputs
inputs.job_id Identifier for job to rerun string
Note: The workflow_dispatch event allows manual triggering of workflows with custom inputs.

Example: Conditional rerun based on job status

name: Conditional Rerun
on:
  schedule:
    - cron: '0 0 * * *'  # Daily at midnight

jobs:
  check-status:
    runs-on: ubuntu-latest
    outputs:
      should_rerun: ${{ steps.check.outputs.should_rerun }}
    steps:
      - id: check
        run: |
          # Logic to determine if job should rerun
          echo "should_rerun=true" >> $GITHUB_OUTPUT

  conditional-rerun:
    needs: check-status
    if: ${{ needs.check-status.outputs.should_rerun == 'true' }}
    runs-on: ubuntu-latest
    steps:
      - name: Rerun job logic
        run: |
          echo "Rerunning failed job"

Key Concepts for Rerun Logic

  • Manual Triggers: Use workflow_dispatch for manual rerun capability.
  • Conditional Execution: Use if conditions to rerun only when needed.
  • Status Checks: Evaluate job status before rerunning.

9. Implementing Approval Gates

Approval gates in GitHub Actions allow you to require manual approval before a workflow runs or continues. This is useful for production deployments or other sensitive operations.

Property Description Example
needs Specifies that a job depends on another job or jobs. needs: [deploy]
if Conditionally runs a job based on the result of an expression. if: ${{ github.ref == 'refs/heads/main' }}
environment Specifies the environment that the job runs against. environment: production

Example: Manual Approval for Production Deployment

name: Production Deployment
on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

  deploy:
    needs: build
    runs-on: ubuntu-latest
    environment: production
    steps:
      - name: Deploy to Production
        run: echo "Deploying to production..."
Note: When an environment is specified, GitHub will wait for approval before running the job. You can configure environment protection rules to require specific people or teams to approve.

Key Points

  • Use the environment property to define environments that require approval.
  • Approvals can be configured in the repository settings under Settings > Environments.
  • Approvals can be restricted to specific users or teams.

10. Using Required Workflows

Required workflows in GitHub Actions allow you to enforce that specific workflows must run before a workflow can complete. This ensures consistency and compliance across repositories or organizations.

Property Description Example
required-workflows Defines the workflows that must run before this workflow can proceed. required-workflows: ['build.yml', 'test.yml']

Example: Requiring Workflows in a GitHub Action

name: Enforce Required Workflows
on:
  push:
    branches: [ main ]
jobs:
  enforce-required:
    runs-on: ubuntu-latest
    steps:
      - name: Check Required Workflows
        uses: actions/required-workflows@v1
        with:
          required-workflows: ['build.yml', 'test.yml']
Note: The required-workflows feature is currently in BETA and may change in future releases.

11. Handling Workflow Timeouts

Property Values Description
timeout-minutes 60 Maximum runtime in minutes before job times out. Default is 360 minutes (6 hours).
soft-timeout false When true, job is marked as failed but continues running until completion.

Example: Setting a Custom Timeout

jobs:
  build:
    runs-on: ubuntu-latest
    timeout-minutes: 120
    steps:
      - name: Run long task
        run: |
          echo "Starting long-running process..."
          sleep 3600
Note: GitHub Actions enforces a maximum job timeout of 360 minutes (6 hours) per job.

12. Implementing Retry Mechanisms

Option Values Notes
retry 3 Number of retry attempts for a job
strategy fail-fast Strategy for handling job failures

Example: Retry Configuration

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Run test with retry
        uses: actions/github-script@v6
        with:
          script: |
            const { execSync } = require('child_process');
            try {
              execSync('npm test', { stdio: 'inherit' });
            } catch (error) {
              console.log('Test failed, retrying...');
              execSync('npm test', { stdio: 'inherit' });
            }
Note: The retry mechanism can be implemented using a combination of if conditions and shell scripting to handle failures gracefully.

Was this article helpful?