Moderní tvorba webových aplikací

O webu

Jak zrychlit GitHub Actions

Praktické tipy pro optimalisaci GitHub Actions pomocí paralelisace, composite actions a gh CLI

5 minut

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

Novinky e-mailem

Když budu mít něco opravdu zajímavého, můžu vám to poslat e-mailem

Přidej se k 500+ čtenářům
Jen kvalitní obsah
Žádný spam

Web jecas.cz píše Bohumil Jahoda, kontakt
Seznam všech článků
2013–2026