commit 13396847e8cdccdcefb37431f34a371f428a2d4e Author: Mohamed Youssef Date: Sun Aug 2 08:06:18 2026 +0300 Initial commit diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml new file mode 100644 index 0000000..33dc835 --- /dev/null +++ b/.gitea/workflows/release.yml @@ -0,0 +1,121 @@ +name: WP Plugin Version & Release + +on: + push: + branches: + - main + +jobs: + release: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Locate main plugin file + id: locate + run: | + FILE=$(grep -rlE "^[[:space:]]*(\*|/\*\*)?[[:space:]]*Plugin Name:" \ + --include="*.php" . \ + | grep -v -e '/vendor/' -e '/node_modules/' -e '/build/' \ + | head -n1) + + if [ -z "$FILE" ]; then + echo "::error::Could not find a PHP file with a 'Plugin Name:' header." + exit 1 + fi + + echo "Found main plugin file: $FILE" + echo "file=${FILE}" >> "$GITHUB_OUTPUT" + + - name: Extract plugin name & version from header + id: meta + run: | + FILE="${{ steps.locate.outputs.file }}" + HEADER=$(sed -n '1,40p' "$FILE") + + PLUGIN_NAME=$(echo "$HEADER" | grep -im1 'Plugin Name:' \ + | sed -E 's/^[[:space:]]*(\*|\/\*\*)?[[:space:]]*Plugin Name:[[:space:]]*//' \ + | sed -E 's/[[:space:]]*\*\/?[[:space:]]*$//') + + VERSION=$(echo "$HEADER" | grep -im1 'Version:' \ + | sed -E 's/^[[:space:]]*(\*|\/\*\*)?[[:space:]]*Version:[[:space:]]*//' \ + | sed -E 's/[[:space:]]*\*\/?[[:space:]]*$//') + + if [ -z "$PLUGIN_NAME" ] || [ -z "$VERSION" ]; then + echo "::error::Could not parse Plugin Name or Version from $FILE header." + exit 1 + fi + + SLUG=$(echo "$PLUGIN_NAME" | tr '[:upper:]' '[:lower:]' \ + | sed -E 's/[^a-z0-9]+/-/g; s/^-+//; s/-+$//') + + echo "Plugin: $PLUGIN_NAME" + echo "Slug: $SLUG" + echo "Version: $VERSION" + + echo "name=${PLUGIN_NAME}" >> "$GITHUB_OUTPUT" + echo "slug=${SLUG}" >> "$GITHUB_OUTPUT" + echo "version=${VERSION}" >> "$GITHUB_OUTPUT" + + - name: Check if this version already has a release + id: check + run: | + TAG="v${{ steps.meta.outputs.version }}" + git fetch --tags --quiet + if git rev-parse "$TAG" >/dev/null 2>&1; then + echo "Tag $TAG already exists — skipping release." + echo "should_release=false" >> "$GITHUB_OUTPUT" + else + echo "Tag $TAG is new — will release." + echo "should_release=true" >> "$GITHUB_OUTPUT" + fi + echo "tag=${TAG}" >> "$GITHUB_OUTPUT" + + - name: Update Stable tag in readme.txt + if: steps.check.outputs.should_release == 'true' && hashFiles('readme.txt') != '' + run: | + sed -i -E "s/^(Stable tag:[[:space:]]*).*/\1${{ steps.meta.outputs.version }}/" readme.txt + if ! git diff --quiet -- readme.txt; then + git config user.name "gitea-actions" + git config user.email "actions@noreply.gitea" + git add readme.txt + git commit -m "chore: sync readme.txt stable tag to ${{ steps.meta.outputs.version }} [skip ci]" + git push origin HEAD:refs/heads/main + fi + + - name: Tag release + if: steps.check.outputs.should_release == 'true' + run: | + git config user.name "gitea-actions" + git config user.email "actions@noreply.gitea" + git tag "${{ steps.check.outputs.tag }}" + git push origin "${{ steps.check.outputs.tag }}" + + - name: Build plugin zip + if: steps.check.outputs.should_release == 'true' + run: | + SLUG="${{ steps.meta.outputs.slug }}" + mkdir -p build/"${SLUG}" + rsync -a \ + --exclude='.git' \ + --exclude='.gitea' \ + --exclude='.github' \ + --exclude='node_modules' \ + --exclude='build' \ + --exclude='*.zip' \ + ./ build/"${SLUG}"/ + cd build + zip -r "../${SLUG}-${{ steps.meta.outputs.version }}.zip" "${SLUG}" + + - name: Create Gitea Release + if: steps.check.outputs.should_release == 'true' + uses: https://gitea.com/actions/release-action@main + with: + files: |- + ${{ steps.meta.outputs.slug }}-${{ steps.meta.outputs.version }}.zip + api_key: "${{ secrets.RELEASE_TOKEN }}" + title: "${{ steps.meta.outputs.name }} ${{ steps.meta.outputs.version }}" + tag_name: "${{ steps.check.outputs.tag }}" diff --git a/README.md b/README.md new file mode 100644 index 0000000..ed7fee9 --- /dev/null +++ b/README.md @@ -0,0 +1,95 @@ +# WP Plugin Auto-Release (Gitea Actions) + +Automatically versions and releases this WordPress plugin whenever the +plugin's `Version:` header changes on `main`. No manual tagging, no +hardcoded plugin name/slug — everything is read straight from the plugin's +own file header. + +## What it does + +On every push to `main`, the workflow at +[`.gitea/workflows/wp-plugin-release.yml`](.gitea/workflows/wp-plugin-release.yml) runs: + +1. **Locate the main plugin file** — scans all `*.php` files for one + containing a `Plugin Name:` header (skips `vendor/`, `node_modules/`, + `build/`). +2. **Extract metadata** — reads `Plugin Name:` and `Version:` from that + file's header comment, then derives a slug from the plugin name + (e.g. `My Cool Plugin` → `my-cool-plugin`). +3. **Check for a new version** — looks for a git tag `vX.Y.Z` matching the + version found in step 2. + - **Tag already exists** → workflow stops here. Pushing commits without + bumping the version does nothing. + - **Tag doesn't exist** → it's a new release, continue. +4. **Sync `readme.txt`** — updates the `Stable tag:` line to match, if the + file exists, and commits that change back to `main`. +5. **Tag** the commit as `vX.Y.Z` and push the tag. +6. **Build a zip** of the plugin (excluding `.git`, `.gitea`, `.github`, + `node_modules`, `build`), named `-.zip`. +7. **Publish a Gitea Release** for the new tag with the zip attached as a + downloadable asset. + +## Requirements + +- A **Gitea Actions runner** (`act_runner`) registered on your instance. +- The runner image needs `rsync`, `zip`, and `git` available (standard on + `ubuntu-latest`-style runner images). +- A **repo secret** named `RELEASE_TOKEN` — a Gitea access token with + repo write / release permissions. Add it under + **Repo → Settings → Secrets**. + +## Usage + +1. Bump the version in your plugin's main file header: + + ```php + /** + * Plugin Name: My Cool Plugin + * Version: 1.3.0 + */ + ``` + +2. Commit and push to `main`: + + ```bash + git add . + git commit -m "Release 1.3.0" + git push origin main + ``` + +3. The workflow detects the new version, tags `v1.3.0`, builds + `my-cool-plugin-1.3.0.zip`, and publishes it as a Gitea release — + nothing else to do. + +## Plugin file requirements + +Your main plugin file must use the standard WordPress header format, +with `Plugin Name:` and `Version:` inside the top `/** ... */` comment +block: + +```php +