
Jak zrychlit GitHub Actions
Praktické tipy pro optimalisaci GitHub Actions pomocí paralelisace, composite actions a gh CLI
GitHub Actions jsou mocný nástroj pro CI/CD, ale bez optimalisace mohou workflows trvat zbytečně dlouho. Zde jsou praktické tipy, jak je zrychlit.
Paralelní joby
Joby bez needs běží paralelně. Pokud jeden job nepotřebuje výstup druhého, odstraňte závislost.
jobs:
lint:
runs-on: ubuntu-latest
steps:
- run: pnpm run lint
check:
runs-on: ubuntu-latest
steps:
- run: pnpm run check
build:
runs-on: ubuntu-latest
# needs: [lint, check]
steps:
- run: pnpm run build
Celková doba CI = doba nejpomalejšího jobu, ne součet všech.
Má build čekat na lint a check?
Záleží na situaci:
- Bez
needs– build běží paralelně, CI je rychlejší. Pokud lint selže, build proběhne zbytečně, ale ušetříte čas když vše projde. - S
needs: [lint, check]– build čeká. Šetří CI minuty při selhání, ale zpomaluje úspěšné běhy.
Pro malé projekty s rychlým buildem se vyplatí paralelisace. Pro dlouhé buildy (10+ minut) může být lepší čekat.
Composite actions pro DRY
Opakující se kroky (checkout, setup Node.js, instalace závislostí) extrahujte do composite action.
.github/actions/setup/action.yml
name: 'Setup Node.js with pnpm'
description: 'Setup pnpm, Node.js, and install dependencies'
inputs:
setup-env:
description: 'Copy .env.example to .env'
required: false
default: 'false'
runs:
using: 'composite'
steps:
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 'lts/*'
cache: 'pnpm'
- name: Install dependencies
shell: bash
run: pnpm install --frozen-lockfile
- name: Setup environment
if: inputs.setup-env == 'true'
shell: bash
run: cp .env.example .env
Použití v workflow
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup
with:
setup-env: 'true'
- run: pnpm run build
Změna verse Node.js nebo package manageru se dělá na jednom místě.
Paths filter
Spouštějte workflow jen pro relevantní změny:
on:
pull_request:
paths:
- 'src/**'
- 'package.json'
Paths filter funguje pouze na úrovni workflow, ne jednotlivých jobů. Pro job-level filtrování potřebujete action jako dorny/paths-filter nebo vlastní logiku.
GitHub CLI místo checkout
Pokud potřebujete jen data z GitHub API (seznam změněných souborů, komentáře), použijte gh CLI. Je předinstalované na runners a nevyžaduje checkout.
jobs:
comment:
runs-on: ubuntu-latest
permissions:
pull-requests: write
env:
GH_TOKEN: ${{ github.token }}
steps:
- name: Get changed files and comment
run: |
# Seznam změněných souborů z PR
FILES=$(gh pr view ${{ github.event.pull_request.number }} \
--json files --jq '.files[].path')
# Přidání komentáře
gh pr comment ${{ github.event.pull_request.number }} \
--body "Changed: $FILES"
Tím ušetříte 10–15 sekund na checkout a případný setup Node.js pro actions.
Cachování závislostí
Setup-node s parametrem cache automaticky cachuje závislosti:
- uses: actions/setup-node@v4
with:
node-version: 'lts/*'
cache: 'pnpm' # nebo npm, yarn
První běh stáhne závislosti, další je načtou z cache.
Bezpečnostní poznámky
Script injection
Doporučuje se neinterpolovat uživatelsky kontrolované hodnoty přímo do shell příkazů:
# Přímá interpolace
run: echo "Branch: ${{ github.head_ref }}"
# Přes environment variable
env:
BRANCH: ${{ github.head_ref }}
run: echo "Branch: $BRANCH"
V kontextu GitHub Actions je risiko minimální – GitHub striktně omezuje povolené znaky v názvech větví, takže shell injection přes github.head_ref prakticky není možný. Použití environment variables je spíše konvence a best practice než reálné bezpečnostní opatření.
Pinning actions
Pro maximální bezpečnost pinnujte actions na konkrétní SHA:
# Tag - lze přepsat na jiný commit
- uses: actions/checkout@v4
# SHA - neměnné
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
Git tagy (jako v4) může vlastník repozitáře kdykoli přesunout na jiný commit. Pokud by byl účet kompromitován, útočník může tag přepsat na škodlivý kód. SHA commit hash je neměnný – vždy ukazuje na stejný kód. Pro oficiální actions od GitHubu je risiko minimální, ale pro third-party actions z neznámých zdrojů je pinning na SHA rozumná pojistka.
Checklist optimalisace
- Joby bez závislostí běží paralelně (bez
needs) - Opakující se kroky v composite action
- Paths filter pro selektivní spouštění
- GitHub CLI místo checkout, kde to jde
- Cachování závislostí zapnuto
- Node.js verse jako
lts/*– pohodlnější než manuální aktualisace, ale s risikem, že nová verse rozbije build