You've already forked wp-bootstrap
The prebuild hook runs phpunit via composer exec, but Composer dependencies were not installed until after npm run build. Moved composer install (with dev) before the build step, then reinstall with --no-dev for the release package. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
297 lines
9.9 KiB
YAML
297 lines
9.9 KiB
YAML
name: Create Release Package
|
|
|
|
on:
|
|
push:
|
|
tags:
|
|
- 'v*'
|
|
|
|
jobs:
|
|
lint:
|
|
name: PHP Lint
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Setup PHP
|
|
uses: shivammathur/setup-php@v2
|
|
with:
|
|
php-version: '8.3'
|
|
extensions: mbstring, xml, zip
|
|
tools: composer:v2
|
|
|
|
- name: PHP Syntax Check
|
|
run: |
|
|
find . -name "*.php" -not -path "./vendor/*" -not -path "./node_modules/*" -print0 | xargs -0 -n1 php -l
|
|
|
|
test:
|
|
name: PHPUnit Tests
|
|
runs-on: ubuntu-latest
|
|
needs: [lint]
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Setup PHP
|
|
uses: shivammathur/setup-php@v2
|
|
with:
|
|
php-version: '8.3'
|
|
extensions: mbstring, xml, dom
|
|
tools: composer:v2
|
|
|
|
- name: Install Composer dependencies
|
|
run: composer install --no-interaction
|
|
|
|
- name: Run PHPUnit
|
|
run: composer exec -- phpunit
|
|
|
|
build-release:
|
|
name: Build Release
|
|
runs-on: ubuntu-latest
|
|
needs: [test]
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '22'
|
|
|
|
- name: Setup PHP
|
|
uses: shivammathur/setup-php@v2
|
|
with:
|
|
php-version: '8.3'
|
|
extensions: mbstring, xml, zip, intl, gettext
|
|
tools: composer:v2
|
|
|
|
- name: Get version from tag
|
|
id: version
|
|
run: |
|
|
VERSION=${GITHUB_REF_NAME#v}
|
|
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
echo "Building version: $VERSION"
|
|
|
|
- name: Install Node dependencies
|
|
run: npm install
|
|
|
|
- name: Validate composer.json
|
|
run: composer validate --no-check-lock --no-check-all
|
|
|
|
- name: Install Composer dependencies (with dev for prebuild tests)
|
|
run: |
|
|
composer config platform.php 8.3.0
|
|
composer install --no-interaction
|
|
|
|
- name: Build assets
|
|
run: npm run build
|
|
|
|
- name: Reinstall Composer dependencies (production only)
|
|
run: composer install --no-dev --optimize-autoloader --no-interaction
|
|
|
|
- name: Install gettext
|
|
run: apt-get update && apt-get install -y gettext
|
|
|
|
- name: Compile translations
|
|
run: |
|
|
for po in languages/*.po; do
|
|
if [ -f "$po" ]; then
|
|
mo="${po%.po}.mo"
|
|
echo "Compiling $po to $mo"
|
|
msgfmt -o "$mo" "$po"
|
|
fi
|
|
done
|
|
|
|
- name: Verify theme version matches tag
|
|
run: |
|
|
THEME_VERSION=$(grep -oP "Version:\s*\K[0-9]+\.[0-9]+\.[0-9]+" style.css | head -1)
|
|
TAG_VERSION=${{ steps.version.outputs.version }}
|
|
if [ "$THEME_VERSION" != "$TAG_VERSION" ]; then
|
|
echo "Error: Theme version ($THEME_VERSION) does not match tag version ($TAG_VERSION)"
|
|
exit 1
|
|
fi
|
|
echo "Version verified: $THEME_VERSION"
|
|
|
|
- name: Create release directory
|
|
run: mkdir -p releases
|
|
|
|
- name: Build release package
|
|
run: |
|
|
VERSION=${{ steps.version.outputs.version }}
|
|
THEME_NAME="wp-bootstrap"
|
|
RELEASE_FILE="releases/${THEME_NAME}-${VERSION}.zip"
|
|
|
|
cd ..
|
|
zip -r "${THEME_NAME}/${RELEASE_FILE}" "${THEME_NAME}" \
|
|
-x "${THEME_NAME}/.git/*" \
|
|
-x "${THEME_NAME}/.gitea/*" \
|
|
-x "${THEME_NAME}/.github/*" \
|
|
-x "${THEME_NAME}/.vscode/*" \
|
|
-x "${THEME_NAME}/.claude/*" \
|
|
-x "${THEME_NAME}/CLAUDE.md" \
|
|
-x "${THEME_NAME}/PLAN.md" \
|
|
-x "${THEME_NAME}/wp-core" \
|
|
-x "${THEME_NAME}/wp-core/*" \
|
|
-x "${THEME_NAME}/releases/*" \
|
|
-x "${THEME_NAME}/node_modules/*" \
|
|
-x "${THEME_NAME}/src/*" \
|
|
-x "${THEME_NAME}/package.json" \
|
|
-x "${THEME_NAME}/package-lock.json" \
|
|
-x "${THEME_NAME}/composer.json" \
|
|
-x "${THEME_NAME}/composer.lock" \
|
|
-x "${THEME_NAME}/.gitignore" \
|
|
-x "${THEME_NAME}/.editorconfig" \
|
|
-x "${THEME_NAME}/*.log" \
|
|
-x "${THEME_NAME}/*.po~" \
|
|
-x "${THEME_NAME}/*.bak" \
|
|
-x "${THEME_NAME}/tests/*" \
|
|
-x "${THEME_NAME}/phpunit.xml.dist" \
|
|
-x "${THEME_NAME}/.phpunit.cache/*" \
|
|
-x "${THEME_NAME}/views/.gitkeep" \
|
|
-x "${THEME_NAME}/assets/images/.gitkeep" \
|
|
-x "*.DS_Store"
|
|
|
|
cd "${THEME_NAME}"
|
|
echo "Created: ${RELEASE_FILE}"
|
|
ls -lh "${RELEASE_FILE}"
|
|
|
|
- name: Generate checksums
|
|
run: |
|
|
VERSION=${{ steps.version.outputs.version }}
|
|
THEME_NAME="wp-bootstrap"
|
|
|
|
cd releases
|
|
sha256sum "${THEME_NAME}-${VERSION}.zip" > "${THEME_NAME}-${VERSION}.zip.sha256"
|
|
echo "SHA256:"
|
|
cat "${THEME_NAME}-${VERSION}.zip.sha256"
|
|
|
|
- name: Verify package structure
|
|
run: |
|
|
set +o pipefail
|
|
VERSION=${{ steps.version.outputs.version }}
|
|
THEME_NAME="wp-bootstrap"
|
|
|
|
echo "Package contents (first 50 entries):"
|
|
unzip -l "releases/${THEME_NAME}-${VERSION}.zip" | head -50 || true
|
|
|
|
# Verify main style.css file exists
|
|
if unzip -l "releases/${THEME_NAME}-${VERSION}.zip" | grep -q "${THEME_NAME}/style.css"; then
|
|
echo "Main style.css file: OK"
|
|
else
|
|
echo "ERROR: Main style.css file not found!"
|
|
exit 1
|
|
fi
|
|
|
|
# Verify vendor directory included
|
|
if unzip -l "releases/${THEME_NAME}-${VERSION}.zip" | grep -q "${THEME_NAME}/vendor/"; then
|
|
echo "Vendor directory: OK"
|
|
else
|
|
echo "ERROR: Vendor directory not found!"
|
|
exit 1
|
|
fi
|
|
|
|
# Verify assets directory included
|
|
if unzip -l "releases/${THEME_NAME}-${VERSION}.zip" | grep -q "${THEME_NAME}/assets/"; then
|
|
echo "Assets directory: OK"
|
|
else
|
|
echo "ERROR: Assets directory not found!"
|
|
exit 1
|
|
fi
|
|
|
|
# Verify node_modules excluded
|
|
if unzip -l "releases/${THEME_NAME}-${VERSION}.zip" | grep -q "${THEME_NAME}/node_modules/"; then
|
|
echo "WARNING: node_modules/ directory should be excluded"
|
|
exit 1
|
|
else
|
|
echo "node_modules/ excluded: OK"
|
|
fi
|
|
|
|
# Verify src excluded
|
|
if unzip -l "releases/${THEME_NAME}-${VERSION}.zip" | grep -q "${THEME_NAME}/src/"; then
|
|
echo "WARNING: src/ directory should be excluded"
|
|
exit 1
|
|
else
|
|
echo "src/ excluded: OK"
|
|
fi
|
|
|
|
# Verify tests excluded
|
|
if unzip -l "releases/${THEME_NAME}-${VERSION}.zip" | grep -q "${THEME_NAME}/tests/"; then
|
|
echo "WARNING: tests/ directory should be excluded"
|
|
exit 1
|
|
else
|
|
echo "tests/ excluded: OK"
|
|
fi
|
|
|
|
- name: Extract changelog for release notes
|
|
id: changelog
|
|
run: |
|
|
VERSION=${{ steps.version.outputs.version }}
|
|
NOTES=$(sed -n "/^## \[${VERSION}\]/,/^## \[/p" CHANGELOG.md | sed '$ d' | tail -n +2)
|
|
if [ -z "$NOTES" ]; then
|
|
NOTES="Release version ${VERSION}"
|
|
fi
|
|
echo "$NOTES" > release_notes.txt
|
|
echo "Release notes extracted"
|
|
|
|
- name: Create Gitea Release
|
|
env:
|
|
GITEA_TOKEN: ${{ secrets.SRC_GITEA_TOKEN }}
|
|
run: |
|
|
VERSION=${{ steps.version.outputs.version }}
|
|
TAG_NAME=${{ github.ref_name }}
|
|
THEME_NAME="wp-bootstrap"
|
|
|
|
PRERELEASE="false"
|
|
if [[ "$TAG_NAME" == *-* ]] || [[ "$VERSION" == 0.* ]]; then
|
|
PRERELEASE="true"
|
|
fi
|
|
|
|
BODY=$(cat release_notes.txt)
|
|
|
|
# Check if release already exists and delete it
|
|
EXISTING_RELEASE=$(curl -s \
|
|
-H "Authorization: token ${GITEA_TOKEN}" \
|
|
"${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}/releases/tags/${TAG_NAME}")
|
|
|
|
EXISTING_ID=$(echo "$EXISTING_RELEASE" | jq -r '.id // empty')
|
|
if [ -n "$EXISTING_ID" ] && [ "$EXISTING_ID" != "null" ]; then
|
|
echo "Deleting existing release ID: $EXISTING_ID"
|
|
curl -s -X DELETE \
|
|
-H "Authorization: token ${GITEA_TOKEN}" \
|
|
"${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}/releases/${EXISTING_ID}"
|
|
echo "Existing release deleted"
|
|
fi
|
|
|
|
# Create release via Gitea API
|
|
RELEASE_RESPONSE=$(curl -s -X POST \
|
|
-H "Authorization: token ${GITEA_TOKEN}" \
|
|
-H "Content-Type: application/json" \
|
|
-d "{\"tag_name\": \"${TAG_NAME}\", \"name\": \"WP Bootstrap ${VERSION}\", \"body\": $(echo "$BODY" | jq -Rs .), \"draft\": false, \"prerelease\": ${PRERELEASE}}" \
|
|
"${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}/releases")
|
|
|
|
RELEASE_ID=$(echo "$RELEASE_RESPONSE" | jq -r '.id')
|
|
|
|
if [ "$RELEASE_ID" == "null" ] || [ -z "$RELEASE_ID" ]; then
|
|
echo "Failed to create release:"
|
|
echo "$RELEASE_RESPONSE"
|
|
exit 1
|
|
fi
|
|
|
|
echo "Created release ID: $RELEASE_ID"
|
|
|
|
# Upload release assets
|
|
for file in "releases/${THEME_NAME}-${VERSION}.zip" "releases/${THEME_NAME}-${VERSION}.zip.sha256"; do
|
|
if [ -f "$file" ]; then
|
|
FILENAME=$(basename "$file")
|
|
echo "Uploading $FILENAME..."
|
|
curl -s -X POST \
|
|
-H "Authorization: token ${GITEA_TOKEN}" \
|
|
-H "Content-Type: application/octet-stream" \
|
|
--data-binary "@$file" \
|
|
"${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}/releases/${RELEASE_ID}/assets?name=${FILENAME}"
|
|
echo "Uploaded $FILENAME"
|
|
fi
|
|
done
|
|
|
|
echo "Release created: ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/releases/tag/${TAG_NAME}"
|