openskills.info
GitHub Actions logo

GitHub Actions

itDevOps and software delivery

GitHub Actions

GitHub Actions is a continuous integration and continuous delivery (CI/CD) platform built into GitHub. It lets you automate build, test, and deployment pipelines directly from the repository that holds your code: you can build and test every pull request, or deploy merged changes to production. It also goes beyond CI/CD — a workflow can react to almost anything that happens in a repository, such as automatically labeling a newly opened issue.

The key structural difference from a standalone automation server is that there is no server. GitHub hosts the scheduling, the user interface, the logs, and — unless you opt out — the machines your automation runs on. You bring YAML files and, where needed, your own runners; GitHub operates the rest.

The mental model

Everything starts with an event: a push, an opened pull request, a new issue, a schedule, or a manual trigger. An event triggers a workflow, a configurable automated process defined in a YAML file stored in the .github/workflows directory of the repository. A repository can have many workflows, each responding to different events.

A workflow contains one or more jobs. Each job runs on its own runner — a server that executes one job at a time — and consists of steps executed in order on that same runner, so steps within a job can share files and results. A step either runs a shell script you define or runs an action: a reusable unit of code that packages a common task, such as checking out your repository or configuring cloud authentication. You can write your own actions or pull them from the GitHub Marketplace. Jobs run in parallel by default; declaring a dependency makes a job wait for another to complete, and a matrix runs the same job across combinations of variables like operating systems or language versions.

A minimal workflow looks like this:

name: CI
on:
  push:
    branches: [main]
  pull_request:

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - name: Run tests
        run: ./test.sh

on declares the triggering events, runs-on selects the runner, uses invokes an action, and run executes a shell command. This example is intentionally small; a production workflow also involves decisions about permissions, secrets, concurrency, caching, and deployment approvals.

Where the work runs

GitHub provides hosted runners with Ubuntu Linux, Windows, and macOS. Every workflow run executes in a fresh, newly provisioned virtual machine, which is also a security property: there is nothing left over from the previous job to compromise. If you need different hardware, a specific operating system, or access to a private network, you can register self-hosted runners on your own infrastructure — with the important caveat that self-hosted runners have no guarantee of a clean, ephemeral environment and can be persistently compromised by untrusted workflow code. The official guidance is that self-hosted runners should almost never be used for public repositories.

Why teams use GitHub Actions

If your code already lives on GitHub, Actions removes an entire category of infrastructure: no automation server to install, patch, back up, or scale. The event model covers far more than "run tests on push" — anything that happens in the repository can drive automation. The Marketplace supplies prebuilt actions for common tasks, and usage is free for standard GitHub-hosted runners in public repositories and for self-hosted runners; private repositories receive a plan-dependent quota of free minutes and storage, with usage beyond that billed.

That convenience comes with its own responsibilities. Every third-party action you uses: is code that runs with access to the secrets configured for your workflow and, potentially, a token that can write to your repository — a compromised action is a supply-chain incident, which is why the official guidance is to pin third-party actions to a full-length commit SHA and audit their source. Secrets are encrypted and redacted from logs, but redaction is not guaranteed, and any user with write access to a repository has read access to all its secrets. Automation that defines its own permissions in YAML needs code review just as much as application code does.

A useful first journey

  1. Create .github/workflows/ in a repository you control and commit a small workflow triggered on: push, following the official quickstart.
  2. Watch the run in the repository's Actions tab and read the per-step logs.
  3. Split the workflow into two jobs and make one depend on the other.
  4. Add a secret to the repository and consume it in a step through the secrets context rather than hardcoding it.
  5. Restrict the workflow's GITHUB_TOKEN permissions to the minimum the jobs need.
  6. Read the secure-use reference before letting workflows touch anything production-shaped.

Where GitHub Actions is not automatically the answer

GitHub Actions assumes your automation gravitates around GitHub repositories; if your source of truth is elsewhere, its event model loses most of its value. GitHub-hosted runners cap a job at 6 hours of execution time, and heavy private-repository usage is metered by the minute, which changes the economics for very compute-hungry pipelines. And if you need full control over the execution environment, self-hosted runners give it back to you — but then you have re-inherited the fleet-operation and security-isolation work that a managed service was supposed to remove. Choose Actions because repository-native automation, managed runners, and the actions ecosystem solve a real constraint, not merely because the tab is already there.

Relevant careers