Skip to content

WP Theme standard issue resolved #31

WP Theme standard issue resolved

WP Theme standard issue resolved #31

name: Build and Deploy WordPress Theme
on:
push:
tags:
- '*'
jobs:
build:
name: 'Build Theme'
runs-on: ubuntu-latest
outputs:
version: ${{ steps.meta.outputs.version }}
zip_name: ${{ steps.meta.outputs.zip_name }}
zip_path: ${{ steps.meta.outputs.zip_path }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Extract version from style.css
id: meta
shell: bash
run: |
RAW=$(grep -m1 -E '^[[:space:]]*\*?[[:space:]]*Version[[:space:]]*:' style.css \
| sed -E 's/.*Version[[:space:]]*:[[:space:]]*//' \
| tr -d '[:space:]')
if [[ -z "$RAW" ]]; then
echo "::error::Could not find 'Version:' in style.css"
exit 1
fi
ZIP_NAME="tutorstarter-${RAW}.zip"
ZIP_PATH="${GITHUB_WORKSPACE}/${ZIP_NAME}"
echo "version=${RAW}" >> "$GITHUB_OUTPUT"
echo "zip_name=${ZIP_NAME}" >> "$GITHUB_OUTPUT"
echo "zip_path=${ZIP_PATH}" >> "$GITHUB_OUTPUT"
- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.0'
tools: composer:v2
coverage: none
- name: Install WP-CLI
run: |
composer global require wp-cli/wp-cli-bundle
wp --version --allow-root
- name: Install dist-archive command
run: |
composer global require wp-cli/dist-archive-command:^3.0
echo "$HOME/.composer/vendor/bin" >> $GITHUB_PATH
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Setup minimal WordPress
run: |
mkdir -p /tmp/wp
cd /tmp/wp
wp core download --allow-root
wp config create \
--dbname=wp \
--dbuser=root \
--dbpass=root \
--dbhost=127.0.0.1 \
--skip-check \
--allow-root
- name: Build assets
run: |
npm run production
composer install --no-dev
wp i18n make-pot --exclude='node_modules,vendor' . languages/tutorstarter.pot \
--path=/tmp/wp \
--allow-root
env:
NODE_ENV: production
NODE_OPTIONS: --openssl-legacy-provider
- name: Build theme zip
run: |
wp dist-archive . "${{ steps.meta.outputs.zip_path }}" --allow-root
- name: Verify zip
run: |
if [[ ! -f "${{ steps.meta.outputs.zip_path }}" ]]; then
echo "::error::Zip not found"
exit 1
fi
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: theme-zip
path: ${{ steps.meta.outputs.zip_path }}
retention-days: 1
deploy-wporg:
name: 'Deploy to WordPress.org'
runs-on: ubuntu-latest
needs: build
if: ${{ true }}
env:
THEME_SLUG: tutorstarter
THEME_VERSION: ${{ needs.build.outputs.version }}
ZIP_NAME: ${{ needs.build.outputs.zip_name }}
SVN_BASE: https://themes.svn.wordpress.org
SVN_USERNAME: ${{ secrets.SVN_USERNAME }}
SVN_PASSWORD: ${{ secrets.SVN_PASSWORD }}
steps:
- name: Install Subversion
run: |
sudo apt-get update -q
sudo apt-get install -y subversion
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: theme-zip
path: /tmp/build
# Theme SVN has NO trunk/tags. Layout is /<slug>/<version>/ only,
# so we deploy by committing a brand-new version directory.
- name: Ensure version does not already exist in SVN
run: |
set -euo pipefail
if svn ls "${SVN_BASE}/${THEME_SLUG}/${THEME_VERSION}/" \
--username "${SVN_USERNAME}" --password "${SVN_PASSWORD}" \
--no-auth-cache --non-interactive > /dev/null 2>&1; then
echo "::error::Version ${THEME_VERSION} already exists in SVN. Bump the version in style.css and re-tag."
exit 1
fi
- name: Checkout SVN repository root (empty)
run: |
set -euo pipefail
svn checkout --depth empty \
--username "${SVN_USERNAME}" \
--password "${SVN_PASSWORD}" \
--no-auth-cache --non-interactive \
"${SVN_BASE}/${THEME_SLUG}" /tmp/svn
- name: Unzip and validate theme
run: |
set -euo pipefail
mkdir -p /tmp/theme-files
unzip -q "/tmp/build/${ZIP_NAME}" -d /tmp/theme-files
# dist-archive zips contain a single top-level folder; resolve it
if [[ -f /tmp/theme-files/style.css ]]; then
SRC=/tmp/theme-files
else
SRC=$(find /tmp/theme-files -mindepth 1 -maxdepth 1 -type d | head -n1)
fi
if [[ -z "${SRC}" || ! -f "${SRC}/style.css" ]]; then
echo "::error::style.css not found in the built zip; refusing to deploy."
exit 1
fi
ZIP_VERSION=$(grep -m1 -E '^[[:space:]]*\*?[[:space:]]*Version[[:space:]]*:' "${SRC}/style.css" \
| sed -E 's/.*Version[[:space:]]*:[[:space:]]*//' | tr -d '[:space:]')
if [[ "${ZIP_VERSION}" != "${THEME_VERSION}" ]]; then
echo "::error::Version mismatch: zip has '${ZIP_VERSION}' but expected '${THEME_VERSION}'."
exit 1
fi
echo "SRC=${SRC}" >> "$GITHUB_ENV"
- name: Stage new version directory
run: |
set -euo pipefail
VERSION_DIR="/tmp/svn/${THEME_VERSION}"
mkdir "${VERSION_DIR}"
cp -R "${SRC}/." "${VERSION_DIR}/"
svn add "${VERSION_DIR}"
svn status /tmp/svn
- name: Commit new version to SVN
run: |
set -euo pipefail
svn commit /tmp/svn \
--username "${SVN_USERNAME}" \
--password "${SVN_PASSWORD}" \
--no-auth-cache --non-interactive \
-m "Release ${THEME_SLUG} ${THEME_VERSION}"
release:
name: 'Create GitHub Release'
runs-on: ubuntu-latest
needs: build
if: always() && needs.build.result == 'success'
env:
VERSION: ${{ needs.build.outputs.version }}
ZIP_NAME: ${{ needs.build.outputs.zip_name }}
steps:
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: theme-zip
path: /tmp/release
- name: Create GitHub Release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
TAG="${VERSION}"
gh release create "$TAG" \
--repo "${GITHUB_REPOSITORY}" \
--title "TutorStarter ${VERSION}" \
"/tmp/release/${ZIP_NAME}" \
|| gh release upload "$TAG" "/tmp/release/${ZIP_NAME}" --repo "${GITHUB_REPOSITORY}" --clobber