You've already forked wc-tier-and-package-prices
- Create automated release workflow triggered on version tags (v*) - Validates plugin version matches tag version - Installs production dependencies via Composer - Compiles translation files (.po to .mo) - Builds release package with proper exclusions - Generates SHA256 checksum - Publishes release to Gitea with changelog notes - Document automated release process in README Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
219 lines
7.9 KiB
YAML
219 lines
7.9 KiB
YAML
name: Create Release Package
|
|
|
|
on:
|
|
push:
|
|
tags:
|
|
- 'v*'
|
|
|
|
jobs:
|
|
build-release:
|
|
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, 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: Validate composer.json
|
|
run: composer validate --strict
|
|
|
|
- name: Configure Composer for private repository
|
|
env:
|
|
GITEA_TOKEN: ${{ secrets.SRC_GITEA_TOKEN }}
|
|
run: |
|
|
composer config --global http-basic.src.bundespruefstelle.ch token "${GITEA_TOKEN}"
|
|
|
|
- name: Install Composer dependencies (production)
|
|
run: |
|
|
composer config platform.php 8.3.0
|
|
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 plugin version matches tag
|
|
run: |
|
|
PLUGIN_VERSION=$(grep -oP "Version:\s*\K[0-9]+\.[0-9]+\.[0-9]+" wc-tier-and-package-prices.php | head -1)
|
|
TAG_VERSION=${{ steps.version.outputs.version }}
|
|
if [ "$PLUGIN_VERSION" != "$TAG_VERSION" ]; then
|
|
echo "Error: Plugin version ($PLUGIN_VERSION) does not match tag version ($TAG_VERSION)"
|
|
exit 1
|
|
fi
|
|
echo "Version verified: $PLUGIN_VERSION"
|
|
|
|
- name: Create release directory
|
|
run: mkdir -p releases
|
|
|
|
- name: Build release package
|
|
run: |
|
|
VERSION=${{ steps.version.outputs.version }}
|
|
PLUGIN_NAME="wc-tier-and-package-prices"
|
|
RELEASE_FILE="releases/${PLUGIN_NAME}-${VERSION}.zip"
|
|
|
|
cd ..
|
|
zip -r "${PLUGIN_NAME}/${RELEASE_FILE}" "${PLUGIN_NAME}" \
|
|
-x "${PLUGIN_NAME}/.git/*" \
|
|
-x "${PLUGIN_NAME}/.gitea/*" \
|
|
-x "${PLUGIN_NAME}/.github/*" \
|
|
-x "${PLUGIN_NAME}/.vscode/*" \
|
|
-x "${PLUGIN_NAME}/.idea/*" \
|
|
-x "${PLUGIN_NAME}/.claude/*" \
|
|
-x "${PLUGIN_NAME}/CLAUDE.md" \
|
|
-x "${PLUGIN_NAME}/wordpress" \
|
|
-x "${PLUGIN_NAME}/wordpress/*" \
|
|
-x "${PLUGIN_NAME}/core" \
|
|
-x "${PLUGIN_NAME}/core/*" \
|
|
-x "${PLUGIN_NAME}/wp-core" \
|
|
-x "${PLUGIN_NAME}/wp-core/*" \
|
|
-x "${PLUGIN_NAME}/releases/*" \
|
|
-x "${PLUGIN_NAME}/composer.lock" \
|
|
-x "${PLUGIN_NAME}/*.log" \
|
|
-x "${PLUGIN_NAME}/logs/*" \
|
|
-x "${PLUGIN_NAME}/.gitignore" \
|
|
-x "${PLUGIN_NAME}/.editorconfig" \
|
|
-x "${PLUGIN_NAME}/phpcs.xml*" \
|
|
-x "${PLUGIN_NAME}/phpunit.xml*" \
|
|
-x "${PLUGIN_NAME}/tests/*" \
|
|
-x "${PLUGIN_NAME}/templates/cache/*" \
|
|
-x "${PLUGIN_NAME}/notes.*" \
|
|
-x "${PLUGIN_NAME}/*.po~" \
|
|
-x "${PLUGIN_NAME}/*.bak" \
|
|
-x "${PLUGIN_NAME}/vendor/*/.git/*" \
|
|
-x "${PLUGIN_NAME}/vendor/*/CLAUDE.md" \
|
|
-x "*.DS_Store" \
|
|
-x "*Thumbs.db"
|
|
|
|
cd "${PLUGIN_NAME}"
|
|
echo "Created: ${RELEASE_FILE}"
|
|
ls -lh "${RELEASE_FILE}"
|
|
|
|
- name: Generate checksums
|
|
run: |
|
|
VERSION=${{ steps.version.outputs.version }}
|
|
PLUGIN_NAME="wc-tier-and-package-prices"
|
|
RELEASE_FILE="releases/${PLUGIN_NAME}-${VERSION}.zip"
|
|
|
|
cd releases
|
|
sha256sum "${PLUGIN_NAME}-${VERSION}.zip" > "${PLUGIN_NAME}-${VERSION}.zip.sha256"
|
|
echo "SHA256:"
|
|
cat "${PLUGIN_NAME}-${VERSION}.zip.sha256"
|
|
|
|
- name: Verify package structure
|
|
run: |
|
|
set +o pipefail
|
|
VERSION=${{ steps.version.outputs.version }}
|
|
PLUGIN_NAME="wc-tier-and-package-prices"
|
|
|
|
echo "Package contents (first 50 entries):"
|
|
unzip -l "releases/${PLUGIN_NAME}-${VERSION}.zip" | head -50 || true
|
|
|
|
# Verify main plugin file exists
|
|
if unzip -l "releases/${PLUGIN_NAME}-${VERSION}.zip" | grep -q "${PLUGIN_NAME}/${PLUGIN_NAME}.php"; then
|
|
echo "✓ Main plugin file at correct location"
|
|
else
|
|
echo "✗ Error: Main plugin file not found at ${PLUGIN_NAME}/${PLUGIN_NAME}.php"
|
|
exit 1
|
|
fi
|
|
|
|
# Verify vendor directory included
|
|
if unzip -l "releases/${PLUGIN_NAME}-${VERSION}.zip" | grep -q "${PLUGIN_NAME}/vendor/"; then
|
|
echo "✓ Vendor directory included"
|
|
else
|
|
echo "✗ Error: Vendor directory not found"
|
|
exit 1
|
|
fi
|
|
|
|
# Verify excluded files are not present
|
|
if unzip -l "releases/${PLUGIN_NAME}-${VERSION}.zip" | grep -qE "CLAUDE\.md|\.claude/|\.git/|wordpress/"; then
|
|
echo "✗ Error: Excluded files found in package"
|
|
unzip -l "releases/${PLUGIN_NAME}-${VERSION}.zip" | grep -E "CLAUDE\.md|\.claude/|\.git/|wordpress/"
|
|
exit 1
|
|
else
|
|
echo "✓ No excluded files in package"
|
|
fi
|
|
|
|
- name: Extract changelog for release notes
|
|
id: changelog
|
|
run: |
|
|
VERSION=${{ steps.version.outputs.version }}
|
|
|
|
# Extract release notes from CHANGELOG.md
|
|
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 }}
|
|
PLUGIN_NAME="wc-tier-and-package-prices"
|
|
|
|
# Check if this is a prerelease (contains hyphen like v1.0.0-beta)
|
|
PRERELEASE="false"
|
|
if [[ "$TAG_NAME" == *-* ]]; then
|
|
PRERELEASE="true"
|
|
fi
|
|
|
|
BODY=$(cat release_notes.txt)
|
|
|
|
# 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\": \"Release ${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/${PLUGIN_NAME}-${VERSION}.zip" "releases/${PLUGIN_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 successfully: ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/releases/tag/${TAG_NAME}"
|