GitHub Actions: Workflows for tests and deployment
In short: GitHub Actions automatically runs workflows on events such as push or pull request: tests, linting, builds and deployments, defined in YAML files in the repository.
In more detail: With GitHub Actions you set up CI/CD right at the code. A workflow (file under .github/workflows/) is triggered by events and runs jobs on runners (virtual machines, GitHub-hosted or self-hosted). Each job consists of steps.
In Depth
An example
name: CI
on:
push:
branches: [main]
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- run: npm run lint
- run: npm testuses: includes ready-made actions (marketplace), run: runs commands. The result appears in the pull request as a green tick or red cross.
Important concepts
- Triggers:
push,pull_request,schedule(cron),workflow_dispatch(manual),release. - Matrix: tests on several versions/systems (
strategy.matrix). - Caching and artifacts speed up and store results.
- Secrets (
${{ secrets.NAME }}) for credentials, variables and environments with approval (approval for production). - Dependencies between jobs (
needs:), conditions (if:). - Reusable workflows and composite actions.
Security
- Minimal permissions: set
permissions:on the workflow (contents: read), do not over-privilege the token. - Pin actions (to a commit SHA instead of a movable tag), use trustworthy sources: supply-chain attacks are real.
- Never output secrets in logs; for pull requests from forks workflows by default get no secrets (rightly so).
pull_request_targetonly with great caution.- Dependabot can keep action versions current.
- Do not insert inputs (branch names, titles) unchecked into shell commands (injection).
Costs and limits
For public repositories minutes are free, for private ones there is a quota and then fees; a payment problem or exhausted limit can lead to jobs not starting at all. Plan fast workflows, use caches, limit matrix and runtime, and keep locally reproducible commands ready (npm test) so that CI only runs the same as you do locally. Alternatives: GitLab CI, CircleCI, Jenkins, Forgejo/Gitea Actions.
See also: CI/CD pipeline, GitHub, Git hooks, Software supply chain