Skip to content

Automatyczne wersjonowanie motywu WordPress z Semantic Release

Published: at 11:36

Każdy, kto pracuje z motywami WordPress, zna ten ból: ręczne edytowanie wersji w style.css, pisanie changelogów, pamiętanie o wszystkich plikach przy mergowaniu. A co jeśli powiem Ci, że możesz to wszystko zautomatyzować w 15 minut?

Spis treści

Rozwiń spis treści

Problem z wersjonowaniem w WordPress

WordPress trzyma wersję motywu w komentarzu w pliku style.css, a nie w package.json jak większość nowoczesnych projektów. To sprawia, że standardowe narzędzia do automatycznego wersjonowania nie działają out-of-the-box.

Rozwiązaniem jest Semantic Release z odpowiednią konfiguracją.

Krok 1: Instalacja zależności

Najpierw upewnij się, że w katalogu projektu istnieje plik package.json. Jeśli go nie ma, zainicjalizuj projekt npm:

npm init -y

Następnie instalujemy wszystkie potrzebne paczki:

npm i -D semantic-release @semantic-release/changelog @semantic-release/git @semantic-release/exec @semantic-release/commit-analyzer @semantic-release/release-notes-generator @semantic-release/github

Uwaga: package.json oraz package-lock.json są wersjonowane w repozytorium – dzięki temu npm ci w CI działa szybko i deterministycznie.

Krok 2: Konfiguracja .releaserc.json

To serce naszej automatyzacji. Tworzymy plik .releaserc.json w głównym katalogu projektu. Największym wyzwaniem w WordPress jest to, że wersja nie siedzi w JSON‑ie, tylko w komentarzu w style.css. Użyjemy do tego pluginu @semantic-release/exec i komendy sed.

{
  "branches": ["master"],
  "plugins": [
    "@semantic-release/commit-analyzer",
    "@semantic-release/release-notes-generator",
    ["@semantic-release/changelog", { "changelogFile": "CHANGELOG.md" }],
    [
      "@semantic-release/exec",
      {
        "prepareCmd": "sed -i '' 's/^Version: .*/Version: ${nextRelease.version}/' style.css || sed -i 's/^Version: .*/Version: ${nextRelease.version}/' style.css"
      }
    ],
    [
      "@semantic-release/git",
      {
        "assets": [
          "CHANGELOG.md",
          "style.css",
          "package.json",
          "package-lock.json"
        ],
        "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
      }
    ],
    "@semantic-release/github"
  ]
}

Dlaczego tak?

Co robi każdy plugin?

Krok 3: GitHub Actions Workflow

Tworzymy plik .github/workflows/release.yml. Ten workflow uruchomi się tylko wtedy, gdy kod trafi na gałąź master.

name: Release

on:
  push:
    branches:
      - master

permissions:
  contents: write
  issues: write
  pull-requests: write

jobs:
  release:
    name: Release
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0 # Pobieramy całą historię dla poprawnej analizy
          persist-credentials: false

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "lts/*"
          cache: npm # przyspiesza instalację zależności

      - name: Install dependencies
        run: npm ci # wymaga, aby package-lock.json był w repozytorium

      # Opcjonalny krok – lint i audyt bezpieczeństwa przed release
      - name: Lint & Security Audit
        run: |
          npm run lint || echo "Brak skryptu lint"
          npm audit --audit-level=high || echo "Audyt zakończony sukcesem"

      - name: Run Semantic Release
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: npx semantic-release

Dodatkowe uwagi

Jak pracować z tym na co dzień?

Najlepszą praktyką jest strategia Squash & Merge:

  1. Deweloper pracuje na swoim branchu (np. feat/nowy-design). Może robić tam “brudne” commity (wip, poprawka, fix).
  2. Tworzy Pull Request
  3. Kluczowy moment: Tytuł PR musi być zgodny z konwencją, np. feat: odświeżenie wyglądu strony głównej
  4. Podczas mergowania wybieramy opcję “Squash and merge”
  5. GitHub spłaszcza historię do jednego commita z tytułem PR
  6. Automat widzi feat: ..., podbija wersję w style.css, aktualizuje CHANGELOG.md i tworzy Release

Konwencja Conventional Commits

PrefixZnaczenieZmiana wersji
feat:Nowa funkcjonalnośćminor (1.x.0)
fix:Poprawka błędupatch (1.0.x)
docs:Tylko dokumentacjabrak
style:Formatowanie kodubrak
refactor:Refaktoryzacjabrak
perf:Optymalizacja wydajnościpatch
chore:Zadania pomocniczebrak
BREAKING CHANGE:Łamiąca zmianamajor (x.0.0)

Pro‑tip: Jak wymusić poprawne nazwy PR?

Ludzie zapominają o konwencjach. Warto dodać bota, który “krzyczy”, gdy nazwa PR jest niepoprawna. Stwórz plik .github/workflows/pr-lint.yml:

name: "Lint PR"

on:
  pull_request:
    types: [opened, edited, synchronize]
    branches: [master]

jobs:
  main:
    runs-on: ubuntu-latest
    steps:
      - uses: amannn/action-semantic-pull-request@v5
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          requireScope: false

Teraz przycisk Merge będzie zablokowany, dopóki autor nie poprawi tytułu na np. fix: literówka w footerze.

Przykładowy flow

sequenceDiagram
    participant Dev as Deweloper
    participant Branch as Feature Branch
    participant PR as Pull Request
    participant Master as Master
    participant GHA as GitHub Actions
    participant Release as Release

    Dev->>Branch: git checkout -b feat/nowy-header
    Dev->>Branch: Commity robocze (wip, fix, etc.)
    Dev->>PR: Tworzy PR z tytułem "feat: nowy header"
    PR->>PR: Lint sprawdza tytuł ✓
    PR->>Master: Squash & Merge
    Master->>GHA: Trigger workflow
    GHA->>GHA: Analiza commitów
    GHA->>GHA: Bump wersji w style.css
    GHA->>GHA: Update CHANGELOG.md
    GHA->>Release: Publikacja v1.2.0

Podsumowanie

Wdrożenie tego procesu zajmuje około 15 minut, a oszczędza godziny frustracji przy każdym wdrożeniu:

Twój zespół może skupić się na kodowaniu, a roboty zajmą się biurokracją.

Przydatne linki

Masz pytania lub sugestie? Zostaw komentarz poniżej.

Mateusz Zadorożny
Mateusz Zadorożny

Od 2012 roku moja praca przeplata się z WordPressem. Od 2017 pracuję z WooCommerce, bardzo dużo czasu poświęcając na testowanie różnych konfiguracji i rozwiązań. Łączę development z digital marketingiem tak, aby w e-commerce osiągnąć maksymalną skuteczność.

O mnie →
Zmień ustawienia prywatności Built with Astro