GitHub Actions i Workflow — automatyzacja CI/CD, którą polubisz
code, javascript, data, computer, html, programmer, programming, encoding, software, java, css, hacker, php, intellectually, monitor, cyberspace, github, corona app, app, operating system, swift, corona, virus, tracking, team, javascript, javascript, javascript, javascript, javascript, php, php, github, github, swift

GitHub Actions i Workflow — automatyzacja CI/CD, którą polubisz

Kiedy projekt rośnie, ręczne uruchamianie testów, budowanie artefaktów i wdrażanie aplikacji zaczyna zajmować coraz więcej czasu. GitHub Actions to wbudowany system automatyzacji, który pozwala zdefiniować całe pipeline’y CI/CD bezpośrednio w repozytorium — bez zewnętrznych narzędzi, bez dodatkowych kont.

Czym jest GitHub Actions?

GitHub Actions to platforma do automatyzacji, która reaguje na zdarzenia w repozytorium — push, pull request, tworzenie tagu, harmonogram czasowy czy nawet ręczne wywołanie. Każda automatyzacja jest opisana w plikach YAML przechowywanych w katalogu .github/workflows/. Dzięki temu konfiguracja żyje razem z kodem i podlega tym samym regułom przeglądu co reszta projektu.

Kluczowe pojęcia

Zanim przejdziemy do przykładów, warto poznać kilka pojęć, którymi GitHub Actions operuje na co dzień.

Workflow to plik YAML opisujący cały proces automatyzacji. Jeden plik = jeden workflow. W repozytorium możesz mieć ich dowolnie wiele.

Job to zestaw kroków wykonywanych na jednej maszynie (runnerze). Joby domyślnie działają równolegle, ale można je uzależnić od siebie za pomocą needs.

Step to pojedynczy krok w obrębie joba — polecenie shell albo gotowa akcja pobrana z marketplace.

Action to wielokrotnie używalna jednostka logiki, którą można opublikować na GitHub Marketplace lub hostować we własnym repozytorium.

Runner to maszyna, na której wykonywane są joby. GitHub oferuje darmowe runnery z Ubuntu, Windows i macOS, ale możesz też podpiąć własne (self-hosted runners).

Anatomia pliku workflow

name: CI

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  build-and-test:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout kodu
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Instalacja zależności
        run: npm ci

      - name: Uruchomienie testów
        run: npm test

      - name: Budowanie projektu
        run: npm run build

Kilka rzeczy wartych uwagi w tym przykładzie:

  • on określa, jakie zdarzenia wyzwalają workflow. Można kombinować wiele triggerów.
  • uses: actions/checkout@v4 to oficjalna akcja, która klonuje repozytorium na runnerze — praktycznie każdy workflow zaczyna się od tego kroku.
  • cache: 'npm' w akcji setup-node automatycznie cachuje node_modules, co znacząco przyspiesza kolejne uruchomienia.
  • Poszczególne kroki mogą używać gotowych akcji (uses) lub bezpośrednich poleceń (run).

Triggerowanie workflow — więcej możliwości

on to jeden z najbardziej elastycznych elementów konfiguracji.

on:
  # Harmonogram (cron) — codziennie o 3:00 UTC
  schedule:
    - cron: '0 3 * * *'

  # Ręczne wywołanie z parametrami
  workflow_dispatch:
    inputs:
      environment:
        description: 'Środowisko docelowe'
        required: true
        default: 'staging'
        type: choice
        options: [staging, production]

  # Wyzwolenie przez inny workflow
  workflow_run:
    workflows: ['CI']
    types: [completed]

  # Zdarzenia na issue i PR
  issues:
    types: [opened, labeled]

workflow_dispatch jest szczególnie przydatne do jednorazowych deploymentiów, migracji baz danych czy generowania raportów na żądanie — bez konieczności tworzenia tymczasowych commitów.

Zarządzanie sekretami i zmiennymi środowiskowymi

Hasła, tokeny i klucze API nigdy nie powinny trafiać do kodu. GitHub Actions oferuje szyfrowane sekrety zarządzane przez interfejs repozytorium lub organizacji.

jobs:
  deploy:
    runs-on: ubuntu-latest
    env:
      NODE_ENV: production
    steps:
      - name: Deploy na serwer
        env:
          SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
          API_TOKEN: ${{ secrets.API_TOKEN }}
        run: |
          echo "$SSH_KEY" > /tmp/deploy_key
          chmod 600 /tmp/deploy_key
          ssh -i /tmp/deploy_key user@server 'cd /app && ./deploy.sh'

Sekrety są automatycznie maskowane w logach — jeśli jakiś krok przypadkowo wypisze token, GitHub zastąpi go gwiazdkami.

Równoległe joby i macierz testów

Jedną z największych zalet Actions jest łatwość skalowania testów. Strategia matrix pozwala uruchomić ten sam job na wielu kombinacjach parametrów jednocześnie.

jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        node: ['18', '20', '22']
      fail-fast: false  # nie przerywaj pozostałych przy pierwszym błędzie

    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node }}
      - run: npm ci && npm test

Ten przykład uruchamia testy na 9 kombinacjach (3 systemy × 3 wersje Node.js) równolegle. fail-fast: false sprawia, że niepowodzenie jednej kombinacji nie zatrzymuje pozostałych — przydatne, gdy chcesz zebrać pełen obraz kompatybilności.

Reużywalne workflow i złożone pipeline’y

Gdy kilka repozytoriów współdzieli te same kroki CI, warto wyciągnąć je do reużywalnego workflow.

# .github/workflows/reusable-test.yml
on:
  workflow_call:
    inputs:
      node-version:
        required: false
        type: string
        default: '20'
    secrets:
      NPM_TOKEN:
        required: true

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ inputs.node-version }}
      - run: npm ci && npm test
        env:
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

Wywołanie z innego workflow:

jobs:
  run-tests:
    uses: my-org/shared-workflows/.github/workflows/reusable-test.yml@main
    with:
      node-version: '22'
    secrets:
      NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

Buforowanie zależności

Cache to jeden z najłatwiejszych sposobów na skrócenie czasu pipeline’u.

- name: Cache zależności pip
  uses: actions/cache@v4
  with:
    path: ~/.cache/pip
    key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
    restore-keys: |
      ${{ runner.os }}-pip-

- name: Instalacja zależności
  run: pip install -r requirements.txt

Klucz cache jest generowany na podstawie hasha pliku requirements.txt — zmiana zależności automatycznie unieważnia cache i instaluje od nowa.

Środowiska i zatwierdzenia deploymentów

Dla środowisk produkcyjnych możesz wymagać ręcznego zatwierdzenia przez wyznaczonych recenzentów.

jobs:
  deploy-production:
    runs-on: ubuntu-latest
    environment:
      name: production
      url: https://myapp.com
    steps:
      - name: Deploy
        run: ./scripts/deploy.sh production

W ustawieniach repozytorium możesz skonfigurować środowisko production tak, by wymagało zatwierdzenia przez jedną lub więcej osób zanim job ruszy. Workflow zatrzyma się i czeka — recenzenci dostają powiadomienie e-mail.

Tworzenie własnych akcji

Jeśli standardowe akcje nie wystarczają, możesz napisać własną. Najprostszy sposób to akcja oparta na skrypcie JavaScript lub Dockerfile.

# action.yml (w osobnym repozytorium lub .github/actions/)
name: 'Moja akcja'
description: 'Robi coś użytecznego'
inputs:
  api-url:
    description: 'URL API'
    required: true
outputs:
  result:
    description: 'Wynik operacji'
runs:
  using: 'node20'
  main: 'dist/index.js'

Dobrą praktyką jest publikowanie akcji z pinowanymi wersjami tagów (np. v1.2.3) zamiast bezpośrednio z gałęzi main, co chroni przed nieoczekiwanymi zmianami.

Bezpieczeństwo workflow

Kilka zasad, o których warto pamiętać:

Pinuj wersje akcji po hashu commita. Zamiast uses: actions/checkout@v4 użyj uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 — to gwarantuje, że nawet jeśli ktoś przejmie konto autora i podmieni tag, twój workflow użyje zweryfikowanego kodu.

Ogranicz uprawnienia GITHUB_TOKEN. Domyślnie token ma szerokie uprawnienia. Zawęź je do minimum:

permissions:
  contents: read
  pull-requests: write

Uważaj na pull_request_target. Ten trigger uruchamia się w kontekście bazowego repozytorium (z dostępem do sekretów) nawet dla PR z forków. Łatwo tu o lukę bezpieczeństwa — nie używaj go z dynamicznym kodem z PR bez odpowiedniej walidacji.

Nie ufaj danym wejściowym. Jeśli workflow korzysta z tytułu PR, nazwy brancha czy treści komentarza w komendzie shell, możliwe jest wstrzyknięcie kodu. Używaj zmiennych środowiskowych zamiast interpolacji w run.

Praktyczny przykład: pełny pipeline dla aplikacji Node.js

name: Full CI/CD Pipeline

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

permissions:
  contents: read
  packages: write

jobs:
  lint-and-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
      - run: npm ci
      - run: npm run lint
      - run: npm test -- --coverage
      - uses: codecov/codecov-action@v4
        with:
          token: ${{ secrets.CODECOV_TOKEN }}

  build-docker:
    needs: lint-and-test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    steps:
      - uses: actions/checkout@v4
      - uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - uses: docker/build-push-action@v5
        with:
          push: true
          tags: ghcr.io/${{ github.repository }}:${{ github.sha }}

  deploy-staging:
    needs: build-docker
    runs-on: ubuntu-latest
    environment: staging
    steps:
      - name: Deploy do stagingu
        run: |
          curl -X POST ${{ secrets.DEPLOY_WEBHOOK }} \
            -H "Authorization: Bearer ${{ secrets.DEPLOY_TOKEN }}" \
            -d '{"image": "ghcr.io/${{ github.repository }}:${{ github.sha }}"}'

Pipeline buduje się etapami: najpierw lint i testy, potem obraz Docker, a na końcu deployment. Każdy etap może się uruchomić tylko jeśli poprzedni zakończył się sukcesem.

Podsumowanie

GitHub Actions eliminuje potrzebę utrzymywania zewnętrznych systemów CI/CD dla większości projektów. Konfiguracja żyje w repozytorium, jest wersjonowana razem z kodem i korzysta z ogromnego ekosystemu gotowych akcji. Kilka minut inwestycji w plik YAML potrafi zaoszczędzić godziny ręcznej pracy tygodniowo.

Dobrym punktem startowym jest prosty workflow uruchamiający testy przy każdym push. Z czasem można go rozbudowywać o cache, macierze testów, budowanie obrazów Docker czy automatyczne deploymenty — każdy krok przynosi mierzalne korzyści.

Udostępnij:
GitHub Actions i Workflow — automatyzacja CI/CD, którą polubisz
Napisane przez
Michał Wrochna
Co myślisz o tym artykule?
0 reakcji
love
0
like
0
so-so
0
weakly
0
0 komentarzy
Najnowsze komentarze
  • Najnowsze komentarze
  • Najlepsze komentarze
Zaloguj się, aby dodać komentarz.
Prawa zastrzeżone Pi Corp sp. z o.o. copyright 2020-2022