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.jsonorazpackage-lock.jsonsą wersjonowane w repozytorium – dzięki temunpm ciw 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?
branches: ["master"]– w naszym projekcie pracujemy na gałęzimaster. Jeśli w przyszłości przejdziesz namain, wystarczy zmienić tę wartość.prepareCmd– używamy składnised -i '' …(macOS) orazsed -i …(Linux) w jednej komendzie, aby działało na obu platformach. Dzięki temu nie musisz martwić się o różnice systemowe.assets– wymieniamy wszystkie pliki, które muszą zostać zatwierdzone w commicie release.package.jsonjest wersjonowany, więc pozostaje w liście.
Co robi każdy plugin?
- commit-analyzer – analizuje commity według Conventional Commits i decyduje o typie wersji (patch/minor/major)
- release-notes-generator – automatycznie generuje notatki do release’a
- changelog – aktualizuje plik
CHANGELOG.md - exec – uruchamia
sed, które podmienia wersję wstyle.css - git – commituje zmiany i tworzy tag
- github – publikuje release na GitHubie
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
- Cache npm – dzięki
cache: npmwsetup-nodeprzyspieszamy kolejny build. - Krok lint/audit – nie jest obowiązkowy, ale warto go mieć, aby przed wypuszczeniem nowej wersji sprawdzić jakość kodu i bezpieczeństwo zależności.
npm ci– działa szybciej niżnpm install, ale wymaga, abypackage-lock.jsonbył w repozytorium (co w naszym projekcie już jest).style.css– upewnij się, że nagłówek motywu zawiera jedną linięVersion:w formacieVersion: x.y.z.sedpodmieni właśnie tę linię.- Synchronizacja wersji w
package.json– jeżeli chcesz, aby wersja wpackage.jsonbyła zawsze zgodna z wersją wstyle.css, możesz dodać dodatkowy krok wprepareCmd, np.npm version ${nextRelease.version} --no-git-tag-version.
Jak pracować z tym na co dzień?
Najlepszą praktyką jest strategia Squash & Merge:
- Deweloper pracuje na swoim branchu (np.
feat/nowy-design). Może robić tam “brudne” commity (wip,poprawka,fix). - Tworzy Pull Request
- Kluczowy moment: Tytuł PR musi być zgodny z konwencją, np.
feat: odświeżenie wyglądu strony głównej - Podczas mergowania wybieramy opcję “Squash and merge”
- GitHub spłaszcza historię do jednego commita z tytułem PR
- Automat widzi
feat: ..., podbija wersję wstyle.css, aktualizujeCHANGELOG.mdi tworzy Release
Konwencja Conventional Commits
| Prefix | Znaczenie | Zmiana wersji |
|---|---|---|
feat: | Nowa funkcjonalność | minor (1.x.0) |
fix: | Poprawka błędu | patch (1.0.x) |
docs: | Tylko dokumentacja | brak |
style: | Formatowanie kodu | brak |
refactor: | Refaktoryzacja | brak |
perf: | Optymalizacja wydajności | patch |
chore: | Zadania pomocnicze | brak |
BREAKING CHANGE: | Łamiąca zmiana | major (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:
- ✅ Koniec z konfliktami w
style.css - ✅ Koniec z ręcznym pisaniem changelogów
- ✅ Automatyczne tagi i release’y
- ✅ Wymuszona konwencja nazewnictwa
Twój zespół może skupić się na kodowaniu, a roboty zajmą się biurokracją.
Przydatne linki
- Semantic Release - dokumentacja
- Conventional Commits - specyfikacja
- action-semantic-pull-request
- GitHub Actions - dokumentacja
Masz pytania lub sugestie? Zostaw komentarz poniżej.