GitHub Actions makes automating tasks within your repositories simple, but understanding how to properly configure workflows is key to making them efficient, secure, and reliable.
By learning how to configure workflow files (.github/workflows/*.yml), you can: ✅ Control when workflows run (push, pull request, scheduled runs) ✅ Define jobs that run on different environments (Linux, macOS, Windows) ✅ Store sensitive data securely using secrets ✅ Improve pipeline performance with caching and artifact management
In this guide, we'll break down GitHub Actions workflow configurations, explain best practices, and provide real-world examples to help you optimize your automation workflows.
Breaking Down a GitHub Actions Workflow File
GitHub Actions workflows are stored as YAML files inside your repository under the .github/workflows/ directory. A basic workflow file looks like this:
name: CI Pipeline # Workflow name
on: push # Triggers workflow when code is pushed
jobs: build: runs-on: ubuntu-latest # OS environment for the job steps: - name: Checkout code uses: actions/checkout@v3
- name: Install dependencies run: npm install
- name: Run tests run: npm testKey Sections in a Workflow File
Section | Description |
|---|---|
name: | The name of the workflow (appears in GitHub's Actions tab). |
on: | Defines when the workflow runs (push, pull request, schedule, manual, etc.). |
jobs: | A list of jobs to execute in the workflow. |
runs-on: | Specifies the OS environment for the job (Ubuntu, macOS, Windows). |
steps: | The individual commands and actions that run inside the job. |
uses: | Calls a pre-built GitHub Action (e.g., actions/checkout to clone the repo). |
run: | Executes a command inside the workflow environment. |
Customizing Workflow Execution
Triggering Workflows (on: Events)
You can define how a workflow runs using the on: keyword. Here are some common triggers:
Run on every push:
on: pushRun only when a pull request is opened:
on: pull_requestRun at a scheduled time (every day at midnight UTC):
on: schedule: - cron: "0 0 * * *"Run manually via GitHub UI or API:
on: workflow_dispatchRunning Jobs on Different Operating Systems
By default, GitHub Actions runs on Ubuntu, but you can specify Windows or macOS as well:
jobs: test: runs-on: windows-latest # Runs on WindowsYou can also test across multiple OS environments using a matrix strategy:
jobs: test: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.os }} steps: - name: Checkout code uses: actions/checkout@v3 - name: Run tests run: npm testManaging Secrets and Environment Variables
Using Environment Variables (env:)
Environment variables help store reusable values across steps:
env: NODE_ENV: production
jobs: example: runs-on: ubuntu-latest steps: - name: Print environment variable run: echo "Running in $NODE_ENV mode"Using Secrets (secrets:) for Sensitive Data
GitHub provides secrets for storing sensitive credentials securely. These are defined in Settings → Secrets and variables → Actions.
To use a secret in a workflow:
env: API_KEY: ${{ secrets.MY_SECRET_KEY }}
jobs: deploy: runs-on: ubuntu-latest steps: - name: Deploy app run: ./deploy.sh --key $API_KEY🚨 Best Practice: Never hardcode credentials inside workflows. Always use GitHub Secrets to manage sensitive data securely.
Using Workflow Conditions (if: Statements)
You can control when jobs and steps run using the if: condition.
Run a Job Only on the main Branch
jobs: deploy: runs-on: ubuntu-latest if: github.ref == 'refs/heads/main' steps: - name: Deploy to production run: ./deploy.shRun a Step Only If the Previous Step Succeeds
steps: - name: Run tests run: npm test
- name: Deploy if tests pass if: success() run: ./deploy.shCaching and Artifacts for Performance
Speeding Up Builds with Caching
GitHub Actions allows caching dependencies to improve workflow speed.
Example: Cache npm dependencies to avoid reinstalling them on every run:
- name: Cache dependencies uses: actions/cache@v3 with: path: ~/.npm key: npm-${{ runner.os }}-${{ hashFiles('package-lock.json') }} restore-keys: npm-${{ runner.os }}-Saving and Retrieving Artifacts
Artifacts allow you to store build outputs and share them between jobs.
Save an artifact:
- name: Upload Build Artifact uses: actions/upload-artifact@v3 with: name: build-output path: ./distDownload the artifact in another job:
- name: Download Artifact uses: actions/download-artifact@v3 with: name: build-output path: ./distBest Practices for Configuring Workflows
✅ Keep Workflows Modular: Break large workflows into smaller, reusable files for better maintainability. ✅ Use Caching Efficiently: Cache dependencies and intermediate results to speed up builds. ✅ Avoid Unnecessary Triggers: Prevent workflows from running too often to reduce cost and execution time. ✅ Secure Secrets: Store API keys and credentials in GitHub Secrets, never in your YAML files. ✅ Use **if: Conditions Wisely:** Avoid running jobs unnecessarily by adding branch-based conditions.