Przejdź do treści
DevOps

CI/CD z GitHub Actions dla Next.js i .NET - Kompletny przewodnik

Opublikowano:
·4 min czytania·Autor: MDS Software Solutions Group

CI/CD GitHub Actions

devops

CI/CD z GitHub Actions dla Next.js i .NET

Automatyzacja procesu budowania, testowania i wdrażania aplikacji to fundament nowoczesnego wytwarzania oprogramowania. GitHub Actions, wbudowane bezpośrednio w platformę GitHub, umożliwia tworzenie zaawansowanych pipeline'ów CI/CD bez konieczności konfigurowania zewnętrznych narzędzi. W tym przewodniku pokażemy, jak skonfigurować kompletne workflow dla projektów Next.js i .NET — od pierwszego commita po wdrożenie produkcyjne.

Czym jest CI/CD?#

Continuous Integration (CI) to praktyka polegająca na częstym łączeniu zmian kodu do głównej gałęzi repozytorium. Każda zmiana jest automatycznie weryfikowana przez zautomatyzowane testy i procesy budowania, co pozwala na wczesne wykrycie błędów.

Continuous Delivery / Continuous Deployment (CD) to rozszerzenie CI o automatyczne wdrażanie aplikacji. Continuous Delivery oznacza, że każda zmiana, która przejdzie testy, jest gotowa do wdrożenia (ale wymaga ręcznego zatwierdzenia). Continuous Deployment idzie o krok dalej — automatycznie wdraża każdą zmianę, która przejdzie pipeline.

Korzyści z wdrożenia CI/CD:

  • Szybsze wykrywanie błędów — problemy są identyfikowane natychmiast po commicie
  • Krótszy czas dostarczania — od commita do produkcji w minutach
  • Wyższa jakość kodu — automatyczne testy i linting przy każdej zmianie
  • Powtarzalność — każde wdrożenie przebiega identycznie
  • Mniejsze ryzyko — małe, częste zmiany zamiast dużych, ryzykownych wdrożeń

GitHub Actions — przegląd platformy#

GitHub Actions to platforma CI/CD zintegrowana z GitHub. Oferuje:

  • Darmowe minuty dla repozytoriów publicznych (nielimitowane) i prywatnych (2000 min/mies. w planie Free)
  • Hosted runners — maszyny wirtualne z Linux, Windows i macOS
  • Self-hosted runners — możliwość uruchomienia na własnej infrastrukturze
  • Marketplace — tysiące gotowych akcji stworzonych przez społeczność
  • Integracja z GitHub — natywne wsparcie dla pull requestów, issues i deploymentów

Składnia workflow — anatomia pliku YAML#

Każdy workflow GitHub Actions to plik YAML umieszczony w katalogu .github/workflows/. Oto kluczowe elementy składni:

# .github/workflows/ci.yml
name: CI Pipeline                    # Nazwa workflow

on:                                   # Triggery (wyzwalacze)
  push:
    branches: [main, develop]        # Uruchom przy push do main/develop
  pull_request:
    branches: [main]                 # Uruchom przy PR do main
  workflow_dispatch:                 # Pozwól na ręczne uruchomienie

env:                                  # Zmienne środowiskowe (globalne)
  NODE_VERSION: "20"
  DOTNET_VERSION: "8.0.x"

jobs:                                 # Definicje zadań
  build:                             # Nazwa zadania
    runs-on: ubuntu-latest           # Runner
    timeout-minutes: 15              # Timeout

    steps:                           # Kroki zadania
      - name: Checkout code
        uses: actions/checkout@v4    # Użyj gotowej akcji

      - name: Run custom script
        run: echo "Hello CI/CD!"     # Uruchom komendę shell

Triggery (wyzwalacze)#

GitHub Actions obsługuje wiele typów triggerów:

on:
  push:
    branches: [main, develop]
    paths:
      - "src/**"                     # Tylko gdy zmienią się pliki w src/
      - "!docs/**"                   # Ignoruj zmiany w docs/
    tags:
      - "v*"                         # Uruchom przy tagach v1.0, v2.1 itd.

  pull_request:
    types: [opened, synchronize, reopened]
    branches: [main]

  schedule:
    - cron: "0 6 * * 1"             # Co poniedziałek o 6:00 UTC

  workflow_dispatch:                 # Ręczne uruchomienie
    inputs:
      environment:
        description: "Target environment"
        required: true
        default: "staging"
        type: choice
        options:
          - staging
          - production

Jobs i Steps#

Zadania (jobs) działają domyślnie równolegle. Możesz definiować zależności między nimi:

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm run lint

  test:
    runs-on: ubuntu-latest
    needs: lint                      # Uruchom po zakończeniu lint
    steps:
      - uses: actions/checkout@v4
      - run: npm test

  deploy:
    runs-on: ubuntu-latest
    needs: [lint, test]              # Uruchom po lint AND test
    if: github.ref == 'refs/heads/main'  # Tylko na branchu main
    steps:
      - run: echo "Deploying..."

Workflow CI/CD dla Next.js#

Poniższy workflow obejmuje pełny pipeline dla aplikacji Next.js — od lintingu po wdrożenie na Vercel:

# .github/workflows/nextjs-ci-cd.yml
name: Next.js CI/CD

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

env:
  NODE_VERSION: "20"

jobs:
  # ─── Etap 1: Lint ───────────────────────────
  lint:
    name: Lint & Format Check
    runs-on: ubuntu-latest
    timeout-minutes: 10

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

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: "npm"

      - name: Install dependencies
        run: npm ci

      - name: Run ESLint
        run: npm run lint

      - name: Check Prettier formatting
        run: npx prettier --check "src/**/*.{ts,tsx,js,jsx}"

      - name: TypeScript type check
        run: npx tsc --noEmit

  # ─── Etap 2: Testy ──────────────────────────
  test:
    name: Unit & Integration Tests
    runs-on: ubuntu-latest
    needs: lint
    timeout-minutes: 15

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

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: "npm"

      - name: Install dependencies
        run: npm ci

      - name: Run tests with coverage
        run: npm run test -- --coverage --ci
        env:
          CI: true

      - name: Upload coverage report
        uses: actions/upload-artifact@v4
        with:
          name: coverage-report
          path: coverage/
          retention-days: 7

  # ─── Etap 3: Build ──────────────────────────
  build:
    name: Build Application
    runs-on: ubuntu-latest
    needs: test
    timeout-minutes: 15

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

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: "npm"

      - name: Install dependencies
        run: npm ci

      - name: Build Next.js application
        run: npm run build
        env:
          NEXT_PUBLIC_API_URL: ${{ secrets.NEXT_PUBLIC_API_URL }}
          NEXT_PUBLIC_SITE_URL: ${{ secrets.NEXT_PUBLIC_SITE_URL }}

      - name: Upload build artifacts
        uses: actions/upload-artifact@v4
        with:
          name: nextjs-build
          path: .next/
          retention-days: 1

  # ─── Etap 4: Deploy na Vercel ───────────────
  deploy-staging:
    name: Deploy to Staging
    runs-on: ubuntu-latest
    needs: build
    if: github.ref == 'refs/heads/develop'
    environment:
      name: staging
      url: ${{ steps.deploy.outputs.url }}

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

      - name: Deploy to Vercel (Preview)
        id: deploy
        uses: amondnet/vercel-action@v25
        with:
          vercel-token: ${{ secrets.VERCEL_TOKEN }}
          vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
          vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
          scope: ${{ secrets.VERCEL_ORG_ID }}

  deploy-production:
    name: Deploy to Production
    runs-on: ubuntu-latest
    needs: build
    if: github.ref == 'refs/heads/main'
    environment:
      name: production
      url: ${{ steps.deploy.outputs.url }}

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

      - name: Deploy to Vercel (Production)
        id: deploy
        uses: amondnet/vercel-action@v25
        with:
          vercel-token: ${{ secrets.VERCEL_TOKEN }}
          vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
          vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
          vercel-args: "--prod"
          scope: ${{ secrets.VERCEL_ORG_ID }}

Workflow CI/CD dla .NET#

Oto kompletny pipeline dla aplikacji .NET, obejmujący budowanie, testowanie i publikację:

# .github/workflows/dotnet-ci-cd.yml
name: .NET CI/CD

on:
  push:
    branches: [main, develop]
    paths:
      - "src/**"
      - "tests/**"
      - "*.sln"
      - "*.csproj"
  pull_request:
    branches: [main]

env:
  DOTNET_VERSION: "8.0.x"
  DOTNET_NOLOGO: true
  DOTNET_CLI_TELEMETRY_OPTOUT: true
  SOLUTION_PATH: "./MyApp.sln"

jobs:
  # ─── Etap 1: Build i Test ───────────────────
  build-and-test:
    name: Build & Test
    runs-on: ubuntu-latest
    timeout-minutes: 15

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

      - name: Setup .NET SDK
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: ${{ env.DOTNET_VERSION }}

      - name: Restore NuGet packages
        run: dotnet restore ${{ env.SOLUTION_PATH }}

      - name: Build solution
        run: dotnet build ${{ env.SOLUTION_PATH }} --configuration Release --no-restore

      - name: Run unit tests
        run: |
          dotnet test ${{ env.SOLUTION_PATH }} \
            --configuration Release \
            --no-build \
            --verbosity normal \
            --collect:"XPlat Code Coverage" \
            --results-directory ./test-results

      - name: Upload test results
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: test-results
          path: ./test-results/
          retention-days: 7

  # ─── Etap 2: Analiza kodu ───────────────────
  code-analysis:
    name: Code Analysis
    runs-on: ubuntu-latest
    needs: build-and-test
    timeout-minutes: 10

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

      - name: Setup .NET SDK
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: ${{ env.DOTNET_VERSION }}

      - name: Run dotnet format check
        run: dotnet format ${{ env.SOLUTION_PATH }} --verify-no-changes --verbosity diagnostic

  # ─── Etap 3: Publish ────────────────────────
  publish:
    name: Publish Application
    runs-on: ubuntu-latest
    needs: [build-and-test, code-analysis]
    if: github.ref == 'refs/heads/main'
    timeout-minutes: 10

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

      - name: Setup .NET SDK
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: ${{ env.DOTNET_VERSION }}

      - name: Publish application
        run: |
          dotnet publish src/MyApp.Api/MyApp.Api.csproj \
            --configuration Release \
            --output ./publish \
            --self-contained false \
            --runtime linux-x64

      - name: Upload published artifacts
        uses: actions/upload-artifact@v4
        with:
          name: dotnet-publish
          path: ./publish/
          retention-days: 5

Docker Build and Push#

Budowanie i publikowanie obrazów Docker to kluczowy element pipeline'u CD. Oto workflow, który buduje obraz i wypycha go do GitHub Container Registry (GHCR):

# .github/workflows/docker-build.yml
name: Docker Build & Push

on:
  push:
    branches: [main]
    tags: ["v*.*.*"]
  pull_request:
    branches: [main]

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  docker:
    name: Build & Push Docker Image
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write

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

      - name: Setup Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to GitHub Container Registry
        if: github.event_name != 'pull_request'
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract metadata (tags, labels)
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          tags: |
            type=ref,event=branch
            type=ref,event=pr
            type=semver,pattern={{version}}
            type=semver,pattern={{major}}.{{minor}}
            type=sha,prefix=

      - name: Build and push Docker image
        uses: docker/build-push-action@v5
        with:
          context: .
          push: ${{ github.event_name != 'pull_request' }}
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max
          build-args: |
            BUILD_VERSION=${{ github.sha }}

Cachowanie zależności#

Prawidłowe cachowanie może skrócić czas wykonania pipeline'u nawet o 70%. Oto strategie dla różnych technologii:

Cache dla Node.js / Next.js#

- name: Setup Node.js with cache
  uses: actions/setup-node@v4
  with:
    node-version: "20"
    cache: "npm"                    # Automatyczny cache node_modules

# Lub ręczne cachowanie dla większej kontroli:
- name: Cache Node modules
  uses: actions/cache@v4
  id: npm-cache
  with:
    path: |
      ~/.npm
      .next/cache
    key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/*.ts', '**/*.tsx') }}
    restore-keys: |
      ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-
      ${{ runner.os }}-nextjs-

Cache dla .NET#

- name: Cache NuGet packages
  uses: actions/cache@v4
  with:
    path: ~/.nuget/packages
    key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
    restore-keys: |
      ${{ runner.os }}-nuget-

Cache dla Docker#

- name: Build with GitHub Actions cache
  uses: docker/build-push-action@v5
  with:
    context: .
    cache-from: type=gha
    cache-to: type=gha,mode=max

Zmienne środowiskowe i sekrety#

GitHub Actions oferuje kilka poziomów zarządzania zmiennymi i sekretami:

Poziomy konfiguracji#

# Poziom workflow (dostępne we wszystkich jobsach)
env:
  APP_NAME: "my-application"

jobs:
  deploy:
    # Poziom joba
    env:
      DEPLOY_ENV: "staging"

    steps:
      - name: Build
        # Poziom stepu
        env:
          API_KEY: ${{ secrets.API_KEY }}
        run: echo "Building for $APP_NAME in $DEPLOY_ENV"

Environments (środowiska)#

Environments w GitHub pozwalają na definiowanie sekretów i reguł ochrony per środowisko:

jobs:
  deploy-staging:
    runs-on: ubuntu-latest
    environment:
      name: staging
      url: https://staging.example.com
    steps:
      - name: Deploy
        env:
          DATABASE_URL: ${{ secrets.DATABASE_URL }}     # Sekret ze środowiska staging
          API_KEY: ${{ secrets.API_KEY }}
        run: ./deploy.sh

  deploy-production:
    runs-on: ubuntu-latest
    environment:
      name: production
      url: https://example.com
    needs: deploy-staging
    steps:
      - name: Deploy
        env:
          DATABASE_URL: ${{ secrets.DATABASE_URL }}     # Sekret ze środowiska production
        run: ./deploy.sh

Strategie wdrożeń — staging i produkcja#

Dobrze zaprojektowany pipeline powinien obsługiwać wiele środowisk z odpowiednimi bramkami bezpieczeństwa:

# .github/workflows/deploy.yml
name: Deploy Pipeline

on:
  push:
    branches: [main, develop]

jobs:
  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm run build

  deploy-staging:
    name: Deploy to Staging
    needs: build
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/develop'
    environment:
      name: staging
      url: https://staging.myapp.com
    steps:
      - uses: actions/checkout@v4
      - name: Deploy to staging server
        run: |
          echo "Deploying to staging..."
          # Komenda wdrożenia na staging
        env:
          DEPLOY_TOKEN: ${{ secrets.STAGING_DEPLOY_TOKEN }}

  deploy-production:
    name: Deploy to Production
    needs: build
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    environment:
      name: production                # Wymaga ręcznego zatwierdzenia (konfiguracja w repo settings)
      url: https://myapp.com
    steps:
      - uses: actions/checkout@v4
      - name: Deploy to production
        run: |
          echo "Deploying to production..."
          # Komenda wdrożenia na produkcję
        env:
          DEPLOY_TOKEN: ${{ secrets.PROD_DEPLOY_TOKEN }}

      - name: Notify on success
        if: success()
        run: |
          curl -X POST "${{ secrets.SLACK_WEBHOOK }}" \
            -H "Content-Type: application/json" \
            -d '{"text":"Deployment to production successful! Commit: ${{ github.sha }}"}'

Branch Protection Rules i Status Checks#

Ochrona gałęzi to krytyczny element bezpieczeństwa pipeline'u. Konfiguracja w ustawieniach repozytorium (Settings > Branches):

Zalecane reguły dla gałęzi main:

  • Require pull request reviews — wymagaj przynajmniej 1-2 recenzentów
  • Require status checks to pass — zaznacz workflow CI jako wymagany
  • Require branches to be up to date — wymuszaj rebase/merge z main przed mergem
  • Require signed commits — opcjonalnie, dla dodatkowego bezpieczeństwa
  • Do not allow bypassing — nawet administratorzy muszą przestrzegać reguł

Status checks integrują się bezpośrednio z pull requestami:

# Ten job pojawi się jako wymagany status check
jobs:
  ci:
    name: "CI / Build & Test"        # Ta nazwa pojawi się w PR
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm run lint
      - run: npm test
      - run: npm run build

Reusable Workflows — wielokrotne użycie#

Zamiast kopiować konfigurację między repozytoriami, twórz reusable workflows:

# .github/workflows/reusable-nextjs-ci.yml
name: Reusable Next.js CI

on:
  workflow_call:                     # Pozwól na wywołanie z innych workflow
    inputs:
      node-version:
        description: "Node.js version"
        required: false
        default: "20"
        type: string
      run-e2e:
        description: "Run E2E tests"
        required: false
        default: false
        type: boolean
    secrets:
      VERCEL_TOKEN:
        required: false
      SONAR_TOKEN:
        required: false

jobs:
  ci:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: ${{ inputs.node-version }}
          cache: "npm"

      - run: npm ci
      - run: npm run lint
      - run: npm test -- --ci

      - name: E2E Tests
        if: inputs.run-e2e
        run: npx playwright test

Wywołanie reusable workflow:

# .github/workflows/ci.yml
name: CI
on:
  pull_request:
    branches: [main]

jobs:
  nextjs-ci:
    uses: ./.github/workflows/reusable-nextjs-ci.yml
    with:
      node-version: "20"
      run-e2e: true
    secrets:
      VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}

Matrix Builds — testowanie na wielu konfiguracjach#

Strategia matrix pozwala uruchamiać ten sam job na wielu konfiguracjach jednocześnie:

jobs:
  test:
    name: Test on Node ${{ matrix.node-version }} / ${{ matrix.os }}
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false               # Nie przerywaj innych jobów po porażce jednego
      matrix:
        node-version: [18, 20, 22]
        os: [ubuntu-latest, windows-latest]
        exclude:
          - os: windows-latest
            node-version: 18         # Pomiń tę kombinację

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

  test-dotnet:
    name: .NET Test on ${{ matrix.dotnet-version }}
    runs-on: ubuntu-latest
    strategy:
      matrix:
        dotnet-version: ["7.0.x", "8.0.x"]

    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-dotnet@v4
        with:
          dotnet-version: ${{ matrix.dotnet-version }}
      - run: dotnet test --configuration Release

Kompletny pipeline — Next.js + .NET w jednym repozytorium#

Jeśli Twój projekt to fullstack z Next.js (frontend) i .NET (backend API), oto połączony workflow:

# .github/workflows/fullstack-ci-cd.yml
name: Fullstack CI/CD

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

jobs:
  # ─── Frontend (Next.js) ─────────────────────
  frontend-ci:
    name: Frontend CI
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: ./frontend

    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: "20"
          cache: "npm"
          cache-dependency-path: frontend/package-lock.json

      - run: npm ci
      - run: npm run lint
      - run: npm test -- --ci
      - run: npm run build

  # ─── Backend (.NET) ─────────────────────────
  backend-ci:
    name: Backend CI
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: ./backend

    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-dotnet@v4
        with:
          dotnet-version: "8.0.x"

      - run: dotnet restore
      - run: dotnet build --configuration Release --no-restore
      - run: dotnet test --configuration Release --no-build

  # ─── Docker Build ───────────────────────────
  docker-build:
    name: Docker Build
    needs: [frontend-ci, backend-ci]
    runs-on: ubuntu-latest
    if: github.event_name == 'push'
    strategy:
      matrix:
        include:
          - context: ./frontend
            image: frontend
            dockerfile: ./frontend/Dockerfile
          - context: ./backend
            image: backend
            dockerfile: ./backend/Dockerfile

    steps:
      - uses: actions/checkout@v4
      - uses: docker/setup-buildx-action@v3
      - uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - uses: docker/build-push-action@v5
        with:
          context: ${{ matrix.context }}
          file: ${{ matrix.dockerfile }}
          push: true
          tags: ghcr.io/${{ github.repository }}/${{ matrix.image }}:${{ github.sha }}
          cache-from: type=gha,scope=${{ matrix.image }}
          cache-to: type=gha,scope=${{ matrix.image }},mode=max

  # ─── Deploy ─────────────────────────────────
  deploy:
    name: Deploy
    needs: docker-build
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    environment: production

    steps:
      - name: Deploy to production
        run: |
          echo "Deploying frontend and backend..."
          # kubectl set image deployment/frontend ...
          # kubectl set image deployment/backend ...

Najlepsze praktyki#

  1. Używaj konkretnych wersji akcjiactions/checkout@v4 zamiast actions/checkout@main
  2. Ogranicz uprawnienia — ustawiaj permissions na minimalny wymagany poziom
  3. Cachuj zależnościactions/cache lub wbudowane cachowanie w setup-node/setup-dotnet
  4. Ustawiaj timeoutytimeout-minutes zapobiegnie zawieszonym jobom
  5. Filtruj paths — uruchamiaj workflow tylko gdy zmienią się relevantne pliki
  6. Używaj environments — oddzielne sekrety dla staging i production
  7. Monitoruj czas wykonania — optymalizuj pipeline, gdy przekracza 10 minut
  8. Wersjonuj workflow — traktuj pliki YAML jak kod produkcyjny

Podsumowanie#

GitHub Actions to potężna platforma CI/CD, która w połączeniu z Next.js i .NET pozwala na stworzenie kompletnego, zautomatyzowanego pipeline'u od commita po wdrożenie produkcyjne. Kluczowe elementy to odpowiednie cachowanie, strategie wdrożeń z podziałem na środowiska, ochrona gałęzi i reusable workflows.

Wdrożenie dobrze zaprojektowanego pipeline'u CI/CD to inwestycja, która zwraca się wielokrotnie — w postaci szybszych wdrożeń, wyższej jakości kodu i spokojniejszego snu zespołu deweloperskiego.


Potrzebujesz profesjonalnej konfiguracji CI/CD dla swojego projektu? W MDS Software Solutions Group projektujemy i wdrażamy zaawansowane pipeline'y CI/CD dla aplikacji Next.js, .NET i nie tylko. Od prostych konfiguracji po złożone, wielośrodowiskowe wdrożenia z Docker i Kubernetes — pomożemy Ci zautomatyzować cały proces dostarczania oprogramowania. Skontaktuj się z nami, aby omówić swoje potrzeby DevOps.

Autor
MDS Software Solutions Group

Zespół ekspertów programistycznych specjalizujących się w nowoczesnych technologiach webowych.

CI/CD z GitHub Actions dla Next.js i .NET - Kompletny przewodnik | MDS Software Solutions Group | MDS Software Solutions Group