CI/CD – jak wykorzystać GitHub Actions do zbudowania pipelineów? – cz. 1

Autor Autor:
Zespół Innokrea
Data publikacji: 2025-01-22
Kategorie: Administracja Bezpieczeństwo Programowanie

Dzisiaj jako Innokrea opowiemy Wam o tym czym jest CI/CD oraz jak wykorzystać natywne rozwiązanie do CI/CD od GitHub – GitHub Actions. Jeśli jesteście ciekawi czym są pipeline’y i jak można je wykorzystać w celu automatyzacji wdrożenia Waszej aplikacji, to zapraszamy. W tematach DevOps oraz DevSecOps polecamy także nasze artykuły dotyczące Terrafroma, CI/CD oraz poprzedni wpis o SAST, DAST i SCA.

 

GIT i CI/CD

GIT jest oprogramowaniem wykorzystywanym przez zdecydowaną większość programistów do zarządzania swoim kodem. Umożliwia ono tworzenie gałęzi oprogramowania i organizację pracy programistów. Kod współdzielony jest na zdalnym repozytorium i mamy tutaj kilka firm oferujących takie usługi. Są to między innymi GitHub, GitLab czy BitBucket. Natomiast narzędzia CI/CD (ang. continuous integration continuous deployment) to oprogramowanie pozwalające na automatyzację zarządzania i wdrażania pisanego kodu do klienta. Występują zarówno narzędzia zewnętrzne jak np. Jenkins czy CircleCI, jak i zintegrowane natywnie ze zdalnym repozytorium jak np. GitLab CI czy GitHub Actions. Procesy, zautomatyzowane w ramach CI/CD nazywamy często workflows lub pipelines i są one zwykle definiowane w formacie YAML.

 

Kod pipelineu w Jenkinsie

Rysunek 1 – Kod pipelineu w Jenkinsie, gdzie używa się języka Groovy, źródło: javacodegeeks.com

 

GitHub Actions

Aby zrozumieć dokładnie GitHub Actions należy zacząć od wyjaśnienia paru pojęć związanych z tą technologią. Są to między innymi:

  • Runner – agent, serwer, maszyna wykonująca nasze workflow. Zwykle jest to serwer z systemem Linux, choć dostępne są także inne systemy. GitHub oferuje maszyny hostowane w ramach ich infrastruktury lub możliwość podłączenia własnej tzw. self-hosted runner.
  • Workflow – plik konfiguracyjny, w formacie YAML definiujący zestaw zadań (jobów) do wykonania. W przypadku GitHub Actions zapisywany w katalogu .github/workflows.
  • Job – pojedyncze zadanie wykonywane w ramach workflow. Składa się z kilku kroków (steps) i zwykle działa na pojedynczym runnerze.
  • Step – pojedynczy krok w ramach zadania (joba), zwykle zawiera blok ‘run’ do wykonania konkretnej komendy na runnerze.
  • Artefakt – rezultat działania danego workflow, który można pobrać np. skompilowany plik, raport testów.
  • Sekret – prywatne dane, sekrety jak np. klucz API używane w workflow. Przechowywane w ustawieniach danego repozytorium i dostępne z poziomu workflow.
  • Event – zdarzenie wyzwalające wrokflow jak np. pull_request czy push.
  • Matrix – mechanizm pozwalający na uruchamianie wielu wersji jobów z różnymi parametrami, aby nie dublować kodu.
  • Actions – moduł do wykonania konkretnego zadania w ramach pojedynczego kroku (step). Może to być np. actions/checkout pozwalające na pobranie kodu z naszego repozytorium lub aws-actions/configure-aws-credentials używany do uwierzytelniania podczas wdrożenia aplikacji na chmurę AWS.

Samą definicję pipeline w GitHub Actions piszemy z użyciem YAMLa i umieszczamy w folderze .github/workflows. Może to wyglądać tak jak na poniższym rysunku.

 

przykładowe repozytorium ze zdefiniowanym workflow

Rysunek 2 – Przykładowe repozytorium ze zdefiniowanym workflow

 

Przykład – projekt express.js i pierwsze workflow

Spróbujmy stworzyć prosty projekt aplikacji webowej z użyciem express.js. Będziemy używać menadżera pakietów npm oraz GitHub Actions w celu prezentacji możliwości GitHub Actions. Aplikacja będzie odpowiadać na żądanie HTTP na głównym endpoint’cie i będzie miała możliwość skorzystania ze zmiennych środowiskowych, które dostarczymy z wykorzystaniem workflow. Wszystkie pliki dostępne są do pobrania na naszym publicznym repozytorium.

const express = require('express');
const app = express();

app.get('/', (req, res) => {
  res.send(process.env.RESPONSE_MESSAGE || 'Hello, World!');
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});

 

Pipeline odpowiadający za instalację paczek (i późniejszy deploy) mógłby wyglądać następująco:

name: CI 1 Build

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Set up Node.js
        uses: actions/setup-node@v3
        with:
          node-version: 18

      - name: Install dependencies
        run: npm install

 

Przypatrzmy się kolejnym komendom, które występują w powyższym pliku:

  • name – to nazwa workflow, którą będziemy mogli zobaczyć w GitHub -> repozytorium -> Actions;
  • on – tutaj definiujemy wszystkie zdarzenia (events) na które ma reagować nasze workflow. Oznacza to, że jeśli dane zdarzenie wystąpi np. push na główny branch lub pull request do głównego brancha nasze workflow zostanie uruchomione na runnerze;
  • jobs – kolejne zadania (jobs), które workflow będzie wykonywać. Domyślnie, wiele jobów wykonuje się współbieżnie (jednocześnie). Żeby jeden job poczekał na wynik poprzedniego należy użyć słówka kluczowego needs;
  • runs-on – definiuje runner, w tym przypadku hostowany przez GitHub używający systemu Linux Ubuntu;
  • steps – definiuje kolejne kroki wykonywane w ramach zadania, w tym przypadku pobranie repozytorium z użyciem checkout, użycie actions do zainstalowania node.js oraz instalacja paczek zdefiniowanych w package json. Kroki wykonują się sekwencyjnie tzn. jeden po drugim.

 

Podsumowanie

Dzisiaj udało nam się wprowadzić Was do tematu GitHub Actions. Jeśli jesteście ciekawi tego, jakie jeszcze bardziej zaawansowane operacje z użyciem Actions można wykonywać, to zapraszamy za tydzień! Do usłyszenia!

 

Kod do pobrania na naszym gitlabie!

 

Źródła:

https://www.javacodegeeks.com/wp-content/uploads/2021/04/Screenshot-2021-02-13-at-9.07.04-AM.png

https://docs.github.com/en/actions

Zobacz więcej na naszym blogu:

DevSecOps – czyli jak zadbać o bezpieczeństwo aplikacji w ramach procesu DevOps

DevSecOps – czyli jak zadbać o bezpieczeństwo aplikacji w ramach procesu DevOps

Jak dbać o bezpieczeństwo produktu w ramach procesu DevOps? Czym są SASTy, DASTy i SCA i jak to wszystko może wpłynąć na poprawę bezpieczeństwa?

AdministracjaBezpieczeństwo

Zarządzanie tożsamością i dostępem użytkownika, czyli o co chodzi z IDP?

Zarządzanie tożsamością i dostępem użytkownika, czyli o co chodzi z IDP?

Czym jest tożsamość użytkownika? Z czego wynika potrzeba zarządzania dostępem w firmie? Jak działa tzw. IDP? Odpowiedź na te pytania znajdziesz w artykule.

Bezpieczeństwo

Wzorce projektowe – część 2

Wzorce projektowe – część 2

Hej, hej... Programisto, to kolejny artykuł dla Ciebie! Druga część artykułu na temat wzorców projektowych. Poznaj Adapter oraz Memento.

Programowanie