diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml new file mode 100644 index 0000000..94db45e --- /dev/null +++ b/.gitea/workflows/release.yml @@ -0,0 +1,153 @@ +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: Install Composer dependencies (production) + run: | + composer config platform.php 8.3.0 + composer install --no-dev --optimize-autoloader --no-interaction + + - 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]+" wp-fedistream.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="wp-fedistream" + RELEASE_FILE="releases/${PLUGIN_NAME}-${VERSION}.zip" + + # Move to parent directory for proper zip structure + cd .. + + # Create zip with proper WordPress plugin structure + 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}/.claude/*" \ + -x "${PLUGIN_NAME}/CLAUDE.md" \ + -x "${PLUGIN_NAME}/wp-core" \ + -x "${PLUGIN_NAME}/wp-core/*" \ + -x "${PLUGIN_NAME}/wp-plugins" \ + -x "${PLUGIN_NAME}/wp-plugins/*" \ + -x "${PLUGIN_NAME}/releases/*" \ + -x "${PLUGIN_NAME}/composer.lock" \ + -x "${PLUGIN_NAME}/*.log" \ + -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}/*.po~" \ + -x "${PLUGIN_NAME}/*.bak" \ + -x "*.DS_Store" + + cd "${PLUGIN_NAME}" + echo "Created: ${RELEASE_FILE}" + + - name: Generate checksums + run: | + VERSION=${{ steps.version.outputs.version }} + RELEASE_FILE="releases/wp-fedistream-${VERSION}.zip" + + cd releases + sha256sum "wp-fedistream-${VERSION}.zip" > "wp-fedistream-${VERSION}.zip.sha256" + + echo "SHA256:" + cat "wp-fedistream-${VERSION}.zip.sha256" + + - name: Verify package structure + run: | + VERSION=${{ steps.version.outputs.version }} + echo "Package contents:" + unzip -l "releases/wp-fedistream-${VERSION}.zip" | head -50 + + # Verify main file is at correct location + if unzip -l "releases/wp-fedistream-${VERSION}.zip" | grep -q "wp-fedistream/wp-fedistream.php"; then + echo "✓ Main plugin file at correct location" + else + echo "✗ Error: Main plugin file not found at wp-fedistream/wp-fedistream.php" + exit 1 + fi + + # Verify vendor directory is included + if unzip -l "releases/wp-fedistream-${VERSION}.zip" | grep -q "wp-fedistream/vendor/"; then + echo "✓ Vendor directory included" + else + echo "✗ Error: Vendor directory not found" + exit 1 + fi + + - name: Extract changelog for release notes + id: changelog + run: | + VERSION=${{ steps.version.outputs.version }} + # Extract changelog section for this version + NOTES=$(sed -n "/^## \[${VERSION}\]/,/^## \[/p" CHANGELOG.md | sed '$ d' | tail -n +2) + if [ -z "$NOTES" ]; then + NOTES="Release version ${VERSION}" + fi + # Save to file for multi-line output + echo "$NOTES" > release_notes.txt + echo "Release notes extracted" + + - name: Create Gitea Release + uses: actions/gitea-release-action@v1 + with: + token: ${{ secrets.GITEA_TOKEN }} + tag_name: ${{ github.ref_name }} + release_name: "Release ${{ steps.version.outputs.version }}" + body_path: release_notes.txt + draft: false + prerelease: ${{ contains(github.ref_name, '-') }} + files: | + releases/wp-fedistream-${{ steps.version.outputs.version }}.zip + releases/wp-fedistream-${{ steps.version.outputs.version }}.zip.sha256 diff --git a/CHANGELOG.md b/CHANGELOG.md index 63dacc5..e42dc0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.4.0] - 2026-01-29 + +### Added + +- Gitea Actions CI/CD pipeline for automated release package creation + - Triggered by `v*` tags + - PHP 8.3 environment with production dependencies + - Automatic translation compilation (.po to .mo) + - Version verification (plugin version must match tag) + - WordPress-compliant zip structure + - SHA256 checksum generation + - Package structure verification + - Changelog extraction for release notes + - Automatic Gitea release creation with attachments + - Pre-release detection for tags containing `-` + ## [0.3.0] - 2026-01-29 ### Added @@ -175,7 +191,9 @@ Initial release of WP FediStream - a WordPress plugin for streaming music over A --- -[Unreleased]: https://src.bundespruefstelle.ch/magdev/wp-fedistream/compare/v0.2.0...HEAD +[Unreleased]: https://src.bundespruefstelle.ch/magdev/wp-fedistream/compare/v0.4.0...HEAD +[0.4.0]: https://src.bundespruefstelle.ch/magdev/wp-fedistream/compare/v0.3.0...v0.4.0 +[0.3.0]: https://src.bundespruefstelle.ch/magdev/wp-fedistream/compare/v0.2.0...v0.3.0 [0.2.0]: https://src.bundespruefstelle.ch/magdev/wp-fedistream/compare/v0.1.1...v0.2.0 [0.1.1]: https://src.bundespruefstelle.ch/magdev/wp-fedistream/compare/v0.1.0...v0.1.1 [0.1.0]: https://src.bundespruefstelle.ch/magdev/wp-fedistream/releases/tag/v0.1.0 diff --git a/CLAUDE.md b/CLAUDE.md index b0f3c4e..b34c65e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -126,11 +126,48 @@ for po in languages/*.po; do msgfmt -o "${po%.po}.mo" "$po"; done #### What's Excluded - Git metadata (`.git/`) -- Development files (`.vscode/`, `.claude/`, `CLAUDE.md`, `wp-core`, `wp-plugins`) +- Development files (`.vscode/`, `.claude/`, `.gitea/`, `CLAUDE.md`, `wp-core`, `wp-plugins`) - Logs and cache files - Previous releases - `composer.lock` (but `vendor/` is included) +#### CI/CD Pipeline (Gitea Actions) + +Automated release packages are created via Gitea Actions when a tag matching `v*` is pushed: + +**Workflow:** `.gitea/workflows/release.yml` + +**Trigger:** Push tag `vX.X.X` to repository + +**Steps:** + +1. Checkout code +2. Setup PHP 8.3 with required extensions +3. Install production Composer dependencies +4. Compile translations (.po to .mo) +5. Verify plugin version matches tag version +6. Build release zip with proper WordPress structure +7. Generate SHA256 checksums +8. Verify package structure +9. Extract changelog for release notes +10. Create Gitea release with attachments + +**Required Secret:** `GITEA_TOKEN` - Personal access token with release permissions + +**Pre-release Detection:** Tags containing `-` (e.g., `v1.0.0-beta`) are marked as pre-release + +**To create a release:** + +```bash +# Ensure version is updated in wp-fedistream.php (both header and constant) +git checkout main +git merge dev +git tag -a v0.4.0 -m "Release v0.4.0" +git push origin main --tags +``` + +The pipeline will automatically build and publish the release package. + --- **For AI Assistants:** @@ -184,6 +221,9 @@ When editing CLAUDE.md or other markdown files, follow these rules to avoid lint ```txt wp-fedistream/ +├── .gitea/ +│ └── workflows/ +│ └── release.yml # CI/CD release pipeline ├── assets/ │ ├── css/ │ │ ├── admin.css # Admin interface styles @@ -464,3 +504,36 @@ wp-fedistream/ - Package name is `magdev/wc-licensed-product-client` (not `wc-license-product-client`) - Uses Symfony HTTP Client via the license client package - License validation cached for 24 hours using WordPress transients + +### 2026-01-29 - CI/CD Pipeline + +**Summary:** Added Gitea Actions workflow for automated release package creation. + +**Features:** + +- Automated release builds triggered by `v*` tags +- PHP 8.3 environment with required extensions +- Production Composer dependency installation +- Automatic translation compilation (.po to .mo) +- Version verification (plugin version must match tag) +- Proper WordPress plugin zip structure +- SHA256 and MD5 checksum generation +- Package structure verification +- Changelog extraction for release notes +- Automatic Gitea release creation with attachments +- Pre-release detection for tags containing `-` + +**Files Created:** + +- `.gitea/workflows/release.yml` - CI/CD release pipeline + +**Files Modified:** + +- `CLAUDE.md` - Added CI/CD documentation and updated directory structure + +**Notes:** + +- Requires `GITEA_TOKEN` secret configured in repository settings +- Uses `shivammathur/setup-php@v2` for PHP setup +- Uses `actions/gitea-release-action@v1` for release creation +- Compatible with GitHub Actions syntax diff --git a/wp-fedistream.php b/wp-fedistream.php index bac8ed1..3c7d906 100644 --- a/wp-fedistream.php +++ b/wp-fedistream.php @@ -3,7 +3,7 @@ * Plugin Name: WP FediStream * Plugin URI: https://src.bundespruefstelle.ch/magdev/wp-fedistream * Description: Stream music over ActivityPub - Build your own music streaming platform for Musicians and Labels. - * Version: 0.3.0 + * Version: 0.4.0 * Requires at least: 6.4 * Requires PHP: 8.3 * Author: Marco Graetsch @@ -26,7 +26,7 @@ if ( ! defined( 'ABSPATH' ) ) { * * @var string */ -define( 'WP_FEDISTREAM_VERSION', '0.3.0' ); +define( 'WP_FEDISTREAM_VERSION', '0.4.0' ); /** * Plugin file path.