diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 327b9a9..cf776ba 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -101,3 +101,35 @@ jobs: echo "Debug code found in src/ — please remove before merging." exit 1 fi + + build: + name: Build Plugin Zip + runs-on: ubuntu-latest + # Only build a shippable artifact once changes land on main, and only + # after the quality gates pass. + needs: [lint, static-analysis, test, no-debug] + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + steps: + - uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.3' + tools: composer:v2 + + - name: Build plugin zip + run: composer build + + - name: Read plugin version + id: meta + run: | + version="$(sed -nE 's/^[[:space:]]*\*?[[:space:]]*Version:[[:space:]]*([^[:space:]]+).*/\1/p' unsupervised-schedular.php | head -1)" + echo "version=${version}" >> "$GITHUB_OUTPUT" + + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: unsupervised-schedular-${{ steps.meta.outputs.version }} + path: dist/*.zip + if-no-files-found: error diff --git a/.gitignore b/.gitignore index c254820..5ab3fcf 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ composer.lock coverage/ .phpunit.result.cache *.log +build/ +dist/ diff --git a/bin/build-zip.sh b/bin/build-zip.sh new file mode 100755 index 0000000..d718845 --- /dev/null +++ b/bin/build-zip.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash +# +# Build a distributable WordPress plugin zip. +# +# Produces dist/-.zip containing a single top-level / +# folder, ready to upload via wp-admin → Plugins → Add New → Upload Plugin. +# +# The package ships only runtime files plus an optimised, production +# (no-dev) Composer autoloader — tests, tooling configs, docs, and dev +# dependencies are excluded. + +set -euo pipefail + +SLUG="unsupervised-schedular" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +MAIN="$ROOT/$SLUG.php" +BUILD_DIR="$ROOT/build" +STAGE="$BUILD_DIR/$SLUG" +DIST_DIR="$ROOT/dist" + +# Runtime files/directories to ship (relative to repo root). +INCLUDE=( + "$SLUG.php" + "uninstall.php" + "composer.json" + "src" + "templates" + "assets" + "languages" +) + +command -v composer >/dev/null 2>&1 || { echo "composer is required" >&2; exit 1; } +command -v zip >/dev/null 2>&1 || { echo "zip is required" >&2; exit 1; } + +# Read the version from the plugin header so the zip is named per release. +VERSION="$(sed -nE 's/^[[:space:]]*\*?[[:space:]]*Version:[[:space:]]*([^[:space:]]+).*/\1/p' "$MAIN" | head -1)" +VERSION="${VERSION:-0.0.0}" + +echo "Building $SLUG $VERSION..." + +rm -rf "$BUILD_DIR" +mkdir -p "$STAGE" "$DIST_DIR" + +for item in "${INCLUDE[@]}"; do + if [ -e "$ROOT/$item" ]; then + cp -R "$ROOT/$item" "$STAGE/" + fi +done + +# Generate a production autoloader inside the staged copy. +( cd "$STAGE" && composer install --no-dev --optimize-autoloader --no-interaction --no-progress --quiet ) + +# Composer metadata is not needed in the shipped plugin. +rm -f "$STAGE/composer.json" "$STAGE/composer.lock" + +ZIP="$DIST_DIR/$SLUG-$VERSION.zip" +rm -f "$ZIP" +( cd "$BUILD_DIR" && zip -rq "$ZIP" "$SLUG" -x '*.DS_Store' ) + +echo "Built $ZIP" diff --git a/composer.json b/composer.json index 15db79b..9ab98c2 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,8 @@ "test:coverage": "phpunit --configuration phpunit.xml --coverage-html coverage/", "lint": "phpstan analyse src/ --level=6 --configuration phpstan.neon", "cs": "phpcs --standard=phpcs.xml.dist", - "cs:fix": "phpcbf --standard=phpcs.xml.dist" + "cs:fix": "phpcbf --standard=phpcs.xml.dist", + "build": "bash bin/build-zip.sh" }, "config": { "allow-plugins": {