Compare commits

...
12 Commits
Author SHA1 Message Date
magdevandClaude Opus 4.5 a4b84f7e41 Fix: Exclude CLAUDE.md from vendor symlink path
Create Release Package / build-release (push) Successful in 1m4s
Zip follows symlinks, so vendor/magdev/wc-licensed-product-client/CLAUDE.md
was being included. Added exclusions for both lib/ and vendor/magdev/ paths.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 20:33:28 +01:00
magdevandClaude Opus 4.5 2e9c948a07 Remove version field from composer.json
Create Release Package / build-release (push) Failing after 58s
The version field causes composer validate --strict to fail with a warning.
Version is determined by git tags instead.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 19:18:34 +01:00
magdevandClaude Opus 4.5 dd4333bd11 Update documentation for lib/ submodule location
Create Release Package / build-release (push) Failing after 4m44s
- Update file structure in README.md and CLAUDE.md
- Document lib/ directory for git submodules
- Update submodule instructions with relative URL
- Add key learnings about vendor/ vs lib/ conflict

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 19:10:53 +01:00
magdevandClaude Opus 4.5 b909221ae2 Fix CI/CD: Move submodule to lib/ directory like wp-fedistream
- Move submodule from vendor/magdev/ to lib/ to avoid Composer conflicts
- Use relative submodule URL (../wc-licensed-product-client.git)
- Pin submodule to v0.2.2 tag
- Update composer.json with ^0.2 version constraint
- Simplify .gitignore (no vendor exceptions needed)
- Update workflow to exclude lib/.git instead of vendor/.git

Based on working wp-fedistream implementation.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 19:09:45 +01:00
magdevandClaude Opus 4.5 d80c9d90f9 Update documentation for v1.4.0 CI/CD release process
Create Release Package / build-release (push) Failing after 4m36s
- README: Update automated releases section with submodule info
- README: Update file structure with .gitea/workflows and submodule
- README: Add v1.4.0 changelog entry
- CLAUDE.md: Update version to 1.4.0, roadmap to 1.4.1
- CLAUDE.md: Rewrite release process for CI/CD workflow
- CLAUDE.md: Add git submodule documentation
- CLAUDE.md: Add v1.4.0 session history

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 19:03:54 +01:00
magdevandClaude Opus 4.5 2bf0cd82fe Add wc-licensed-product-client as git submodule
Create Release Package / build-release (push) Failing after 4m36s
- Bundle magdev/wc-licensed-product-client as git submodule
- Update composer.json to use path repository instead of VCS
- Update .gitignore to allow submodule in vendor directory
- Update CI workflow to checkout submodules recursively
- Remove private repository authentication step (no longer needed)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 18:58:01 +01:00
magdevandClaude Opus 4.5 9451cc1965 Version 1.4.0 - Add Gitea CI/CD release pipeline
Create Release Package / build-release (push) Failing after 1m2s
- Automated release workflow triggered on version tags (v*)
- Validates plugin version matches tag
- Installs production Composer dependencies
- Compiles translation files
- Creates release package with proper exclusions
- Generates SHA256 checksum
- Publishes release to Gitea with changelog notes

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 18:53:39 +01:00
magdevandClaude Opus 4.5 02b0308058 Add Gitea CI/CD release pipeline
- 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>
2026-01-29 18:49:29 +01:00
magdevandClaude Opus 4.5 38e9506d4e Update v1.3.1 session learnings with release package fixes
- Document vendor .git exclusion requirement for release packages
- Update package size to 775KB (650 files) after proper exclusions
- Add correct zip parent directory path for release creation
- Document .claude/settings.json addition to .gitignore

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 19:36:56 +01:00
magdevandClaude Opus 4.5 74cc56005e Add .claude/settings.json to gitignore
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 19:33:15 +01:00
magdevandClaude Opus 4.5 136eed2bdd Document v1.3.1 session learnings in CLAUDE.md
- Update version to 1.3.1 and date to 2026-01-27
- Replace completed v1.3.1 roadmap with v1.3.2 placeholder
- Update license client dependency to dev-main
- Add v1.3.1 session history documenting SecureLicenseClient switch

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 19:31:06 +01:00
magdevandClaude Opus 4.5 178f86f3e6 Update README for v1.3.1 release
- Added license management feature to admin features list
- Updated PHP requirement from 7.4 to 8.3
- Updated file structure version comment to v1.3.1
- Added v1.3.0 and v1.3.1 changelog entries

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 19:27:01 +01:00
9 changed files with 510 additions and 140 deletions

No files matched your search

+217
View File
@@ -0,0 +1,217 @@
name: Create Release Package
on:
push:
tags:
- 'v*'
jobs:
build-release:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
- 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: 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}/.gitmodules" \
-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}/lib/*/.git/*" \
-x "${PLUGIN_NAME}/lib/*/CLAUDE.md" \
-x "${PLUGIN_NAME}/vendor/magdev/*/.git/*" \
-x "${PLUGIN_NAME}/vendor/magdev/*/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}"
+3
View File
@@ -37,3 +37,6 @@ wp-core
# Releases (not tracked in git) # Releases (not tracked in git)
/releases/ /releases/
# Claude Code local settings
.claude/settings.json
+3
View File
@@ -0,0 +1,3 @@
[submodule "lib/wc-licensed-product-client"]
path = lib/wc-licensed-product-client
url = ../wc-licensed-product-client.git
+14
View File
@@ -5,6 +5,20 @@ All notable changes to WooCommerce Tier and Package Prices will be documented in
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.4.0] - 2026-01-29
### Added
- **Gitea CI/CD Release Pipeline**: Automated release workflow triggered on version tags
- Validates plugin version matches tag version
- Installs production Composer dependencies
- Compiles translation files (.po to .mo)
- Creates release package with proper exclusions
- Generates SHA256 checksum
- Publishes release to Gitea with changelog notes
---
## [1.3.1] - 2026-01-27 ## [1.3.1] - 2026-01-27
### Changed ### Changed
+205 -111
View File
@@ -1,7 +1,7 @@
# WooCommerce Tier and Package Prices - AI Context Document # WooCommerce Tier and Package Prices - AI Context Document
**Last Updated:** 2026-01-25 **Last Updated:** 2026-01-29
**Current Version:** 1.3.0 **Current Version:** 1.4.0
**Author:** Marco Graetsch **Author:** Marco Graetsch
**Project Status:** Production-ready WordPress plugin **Project Status:** Production-ready WordPress plugin
@@ -20,9 +20,9 @@ This project is proudly **"vibe-coded"** using Claude.AI - the entire codebase w
**Note for AI Assistants:** Clean this section after the specific features are done or new releases are made. Effective changes are tracked in `CHANGELOG.md`. Do not add completed versions here - document them in the Session History section at the end of this file. Always keep the `Known Bugs` section and create a section with the next bugfix and minor version after a release. **Note for AI Assistants:** Clean this section after the specific features are done or new releases are made. Effective changes are tracked in `CHANGELOG.md`. Do not add completed versions here - document them in the Session History section at the end of this file. Always keep the `Known Bugs` section and create a section with the next bugfix and minor version after a release.
### Version 1.3.1 ### Version 1.4.1
- TBD - No planned changes yet
## Technical Stack ## Technical Stack
@@ -40,7 +40,7 @@ This project is proudly **"vibe-coded"** using Claude.AI - the entire codebase w
```json ```json
{ {
"twig/twig": "^3.0", "twig/twig": "^3.0",
"magdev/wc-licensed-product-client": "^0.1", "magdev/wc-licensed-product-client": "dev-main",
"symfony/http-client": "^7.0", "symfony/http-client": "^7.0",
"psr/log": "^3.0", "psr/log": "^3.0",
"psr/cache": "^3.0", "psr/cache": "^3.0",
@@ -55,6 +55,8 @@ This project is proudly **"vibe-coded"** using Claude.AI - the entire codebase w
```txt ```txt
wc-tier-and-package-prices/ wc-tier-and-package-prices/
├── wc-tier-and-package-prices.php # Main plugin file (entry point) ├── wc-tier-and-package-prices.php # Main plugin file (entry point)
├── .gitea/workflows/
│ └── release.yml # CI/CD release pipeline
├── includes/ # PHP classes ├── includes/ # PHP classes
│ ├── class-wc-tpp-admin.php # Admin settings integration │ ├── class-wc-tpp-admin.php # Admin settings integration
│ ├── class-wc-tpp-settings.php # WooCommerce settings page │ ├── class-wc-tpp-settings.php # WooCommerce settings page
@@ -81,7 +83,9 @@ wc-tier-and-package-prices/
│ ├── *.pot # Translation template │ ├── *.pot # Translation template
│ ├── *.po # Translation sources │ ├── *.po # Translation sources
│ └── *.mo # Compiled translations │ └── *.mo # Compiled translations
├── vendor/ # Composer dependencies (included in releases) ├── lib/ # Bundled libraries (git submodules)
│ └── wc-licensed-product-client/ # License client library (v0.2.x)
├── vendor/ # Composer dependencies (generated)
├── releases/ # Release packages (not in git) ├── releases/ # Release packages (not in git)
└── *.md # Documentation files └── *.md # Documentation files
@@ -353,136 +357,133 @@ Symptom: Help icon appearing far from label text at container edge
## Release Process ## Release Process
### Version Bumping ### Automated CI/CD Pipeline (Recommended)
Update version in 3 places: Since v1.4.0, releases are automated via Gitea CI/CD. The pipeline is triggered when a version tag is pushed.
1. `wc-tier-and-package-prices.php` - Plugin header comment (line 7) **Workflow:**
2. `wc-tier-and-package-prices.php` - `WC_TPP_VERSION` constant (line 26)
3. `composer.json` - version field (optional, not critical)
### Creating Release Package
**CRITICAL:** The zip command must be run from the **parent directory** of the plugin folder to create proper archive structure.
```bash ```bash
# From parent directory (/home/magdev/workspaces/php) # 1. Update version in 3 places
cd /home/magdev/workspaces/php # - wc-tier-and-package-prices.php (header comment, line 7)
# - wc-tier-and-package-prices.php (WC_TPP_VERSION constant)
# - composer.json (version field)
# Create zip excluding dev files - note the correct path structure # 2. Update CHANGELOG.md with release notes
zip -r wc-tier-and-package-prices/releases/wc-tier-and-package-prices-X.X.X.zip wc-tier-and-package-prices/ \
-x 'wc-tier-and-package-prices/.git*' \
'wc-tier-and-package-prices/*.log' \
'wc-tier-and-package-prices/.claude/*' \
'wc-tier-and-package-prices/CLAUDE.md' \
'wc-tier-and-package-prices/releases/*' \
'wc-tier-and-package-prices/node_modules/*' \
'wc-tier-and-package-prices/.DS_Store' \
'wc-tier-and-package-prices/Thumbs.db' \
'wc-tier-and-package-prices/.vscode/*' \
'wc-tier-and-package-prices/.idea/*' \
'wc-tier-and-package-prices/*.sublime-*' \
'wc-tier-and-package-prices/notes.*' \
'wc-tier-and-package-prices/logs/*' \
'wc-tier-and-package-prices/templates/cache/*' \
'wc-tier-and-package-prices/composer.lock'
# Return to project directory # 3. Commit and push to dev
cd wc-tier-and-package-prices git add -A && git commit -m "Version X.X.X - [description]
# Generate SHA256 checksum Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>"
cd releases
sha256sum wc-tier-and-package-prices-X.X.X.zip > wc-tier-and-package-prices-X.X.X.zip.sha256
cd ..
```
**IMPORTANT NOTES:**
- The `vendor/` directory MUST be included in releases (Twig dependency required for runtime)
- Running zip from wrong directory creates empty or malformed archives
- Exclusion patterns must match the relative path structure used in zip command
- Always verify the package with `unzip -l` and test extraction before committing
### Verification Steps
After creating the release package, always verify:
```bash
# Check package size (should be ~400-450KB, NOT 8MB+ or near 0)
ls -lh releases/wc-tier-and-package-prices-X.X.X.zip
# Verify exclusions worked
unzip -l releases/wc-tier-and-package-prices-X.X.X.zip | grep -E "CLAUDE\.md|\.claude/|\.git" && echo "ERROR: Excluded files found!" || echo "OK: No excluded files"
# Test extraction
cd /tmp && rm -rf test-extract && unzip -q /path/to/releases/wc-tier-and-package-prices-X.X.X.zip -d test-extract && ls -la test-extract/wc-tier-and-package-prices/
# Verify version in extracted package
head -30 /tmp/test-extract/wc-tier-and-package-prices/wc-tier-and-package-prices.php | grep -E "Version:|WC_TPP_VERSION"
# Verify template changes (if applicable)
grep 'class="regular"' /tmp/test-extract/wc-tier-and-package-prices/templates/admin/*.twig
```
### Git Workflow for Releases
**Standard workflow:** Work on `dev` branch → merge to `main` → tag → push
```bash
# 1. Ensure you're on dev branch with all changes committed
git checkout dev
git add [files]
git commit -m "Release version X.X.X - [description]
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>"
# 2. Merge dev to main
git checkout main
git merge dev --no-edit # Should be fast-forward
# 3. Create annotated tag
git tag -a vX.X.X -m "Release version X.X.X - [description]"
# 4. Push everything
git push origin main
git push origin vX.X.X
# 5. Update dev and push
git checkout dev
git rebase main # Should be up-to-date already
git push origin dev git push origin dev
# 6. If you have uncommitted local changes (like .claude/settings.local.json) # 4. Merge to main and push
git stash push -m "Local development settings" git checkout main && git merge dev --no-edit && git push origin main
# ... do git operations ...
git stash pop # 5. Create and push tag (triggers CI/CD)
git tag -a vX.X.X -m "Release version X.X.X - [description]"
git push origin vX.X.X
# 6. Switch back to dev
git checkout dev
``` ```
**Important Git Notes:** **What the CI/CD Pipeline Does:**
- Always commit from `dev` branch first 1. Checks out code with git submodules (`submodules: recursive`)
- Tags should use format `vX.X.X` (e.g., `v1.1.22`) 2. Sets up PHP 8.3 with required extensions
- Use annotated tags (`-a`) not lightweight tags 3. Validates `composer.json`
- Commit messages should follow the established format with Claude Code attribution 4. Installs production Composer dependencies (`--no-dev`)
- `.claude/settings.local.json` changes are typically local-only (stash before rebasing) 5. Compiles translation files (.po → .mo)
6. Validates plugin version matches tag version
7. Creates release package with proper exclusions
8. Generates SHA256 checksum
9. Verifies package structure
10. Extracts changelog notes for release description
11. Creates Gitea release with assets
**Pipeline Location:** `.gitea/workflows/release.yml`
**Required Secret:** `SRC_GITEA_TOKEN` - Gitea API token for creating releases
### Git Submodule: wc-licensed-product-client
The `magdev/wc-licensed-product-client` library is bundled as a git submodule in `lib/` to avoid private repository authentication during CI/CD and to prevent conflicts with Composer's `vendor/` directory.
**Location:** `lib/wc-licensed-product-client/`
**Submodule URL:** Relative path `../wc-licensed-product-client.git` (works with Gitea CI/CD)
**Updating the submodule:**
```bash
# Update to a specific tag
cd lib/wc-licensed-product-client
git fetch --tags
git checkout v0.2.3 # or desired version
cd ../..
git add lib/wc-licensed-product-client
git commit -m "Update wc-licensed-product-client to v0.2.3"
```
**Composer Configuration:**
```json
{
"repositories": [
{
"type": "path",
"url": "lib/wc-licensed-product-client"
}
],
"require": {
"magdev/wc-licensed-product-client": "^0.2"
}
}
```
Composer creates a symlink in `vendor/magdev/wc-licensed-product-client` pointing to `lib/wc-licensed-product-client`.
### Manual Release (Legacy)
For manual releases without CI/CD, run from the **parent directory**:
```bash
cd /home/magdev/workspaces/php/wordpress/wp-content/plugins
zip -r wc-tier-and-package-prices/releases/wc-tier-and-package-prices-X.X.X.zip wc-tier-and-package-prices/ \
-x 'wc-tier-and-package-prices/.git/*' \
-x 'wc-tier-and-package-prices/.gitea/*' \
-x 'wc-tier-and-package-prices/.claude/*' \
-x 'wc-tier-and-package-prices/CLAUDE.md' \
-x 'wc-tier-and-package-prices/releases/*' \
-x 'wc-tier-and-package-prices/composer.lock' \
-x 'wc-tier-and-package-prices/*.log' \
-x 'wc-tier-and-package-prices/.gitignore' \
-x 'wc-tier-and-package-prices/.gitmodules' \
-x 'wc-tier-and-package-prices/vendor/*/.git/*' \
-x '*.DS_Store'
cd wc-tier-and-package-prices/releases
sha256sum wc-tier-and-package-prices-X.X.X.zip > wc-tier-and-package-prices-X.X.X.zip.sha256
```
### What Gets Released ### What Gets Released
- All plugin source files - All plugin source files
- Compiled vendor dependencies - Compiled vendor dependencies (including submodule)
- Translation files (.mo compiled from .po) - Translation files (.mo compiled from .po)
- Assets (CSS, JS) - Assets (CSS, JS)
- Documentation (README, CHANGELOG, etc.) - Documentation (README, CHANGELOG, etc.)
### What's Excluded ### What's Excluded
- Git metadata (`.git/`) - Git metadata (`.git/`, `.gitmodules`)
- CI/CD workflows (`.gitea/`)
- Development files (`.vscode/`, `.claude/`, `CLAUDE.md`) - Development files (`.vscode/`, `.claude/`, `CLAUDE.md`)
- Logs and cache files - Logs and cache files
- Previous releases - Previous releases
- `composer.lock` (but `vendor/` is included) - `composer.lock`
## Testing Checklist ## Testing Checklist
@@ -1176,6 +1177,99 @@ The plugin architecture is solid and well-tested. Most bugs arise from:
- Package version was `^0.1` not `^1.0` - always check available versions before setting constraint - Package version was `^0.1` not `^1.0` - always check available versions before setting constraint
- Release package size increased from ~430KB to ~737KB due to new Composer dependencies - Release package size increased from ~430KB to ~737KB due to new Composer dependencies
### v1.3.1 Release Session (2026-01-27)
**Accomplished:**
1. Reviewed server-implementation.md from license client library
2. Upgraded from `LicenseClient` to `SecureLicenseClient`:
- Added "Server Secret" configuration field in License settings tab
- Updated `get_license_client()` to use `SecureLicenseClient` with HMAC-SHA256 signature verification
- Updated JavaScript to pass `server_secret` in AJAX requests
3. Added comprehensive exception handling:
- `RateLimitExceededException` - Shows retry time to user
- `SignatureException` - Reports signature verification failures
- `InvalidArgumentException` - SSRF protection for private IP blocking
4. Updated Composer dependencies:
- Changed `magdev/wc-licensed-product-client` from `^0.1` to `dev-main`
- Library includes new security features (SSRF protection, response signatures)
5. Updated translations:
- Added 7 new translation strings for v1.3.1
- All 7 language files updated and compiled
6. Created release package:
- Package size: 775KB (after proper exclusions)
- 650 files included
- SHA256 checksum generated
7. Updated README.md:
- Documented license management feature
- Updated PHP requirement to 8.3
- Added v1.3.0 and v1.3.1 changelog entries
8. Re-released v1.3.1:
- Fixed release package exclusions (vendor .git dirs were included)
- Added `.claude/settings.json` to .gitignore
**Key Learnings:**
- `SecureLicenseClient` requires `serverSecret` parameter for HMAC verification
- The library's exception classes are in `Magdev\WcLicensedProductClient\Exception\` and `Magdev\WcLicensedProductClient\Security\` namespaces
- `RateLimitExceededException` has a `retryAfter` property (int seconds)
- Always check library documentation in `docs/server-implementation.md` for implementation requirements
**Release Package Learnings (CRITICAL):**
- Vendor directories installed via Composer (dev-main) contain their own `.git/` folders
- Release exclusion patterns must include `'wc-tier-and-package-prices/vendor/*/.git/*'` and `'wc-tier-and-package-prices/vendor/*/CLAUDE.md'`
- Run zip from `/home/magdev/workspaces/php/wordpress/wp-content/plugins/` (NOT `/home/magdev/workspaces/php/`)
- Always verify exclusions with: `unzip -l package.zip | grep -E "\.git/|CLAUDE\.md"`
### v1.4.0 Release Session (2026-01-29)
**Accomplished:**
1. Created Gitea CI/CD release pipeline:
- `.gitea/workflows/release.yml` - Automated release workflow
- Triggers on version tags (`v*`)
- Validates plugin version matches tag
- Installs production Composer dependencies
- Compiles translations (.po → .mo)
- Creates release package with proper exclusions
- Generates SHA256 checksum
- Publishes release to Gitea with changelog notes
2. Added git submodule for license client:
- Initially placed in `vendor/magdev/` - **FAILED** (Composer conflicts)
- Fixed: Moved to `lib/wc-licensed-product-client/` like wp-fedistream
- Uses relative URL `../wc-licensed-product-client.git`
- Pinned to v0.2.2 tag
- Avoids private repository authentication during CI/CD
3. Updated documentation:
- README.md - Added CI/CD section, updated file structure
- CLAUDE.md - Updated release process, added submodule docs
**Key Learnings:**
- **CRITICAL:** Git submodules should be in `lib/` NOT `vendor/` to avoid Composer conflicts
- Composer manages `vendor/` directory - don't put submodules there
- Use relative submodule URL (`../repo.git`) for Gitea CI/CD compatibility
- Use version constraint `^0.2` instead of `@dev` for stability
- Git submodules require `submodules: recursive` in checkout action
- Composer creates symlink from `vendor/` to `lib/` automatically
**CI/CD Pipeline Notes:**
- Pipeline file: `.gitea/workflows/release.yml`
- Required secret: `SRC_GITEA_TOKEN` for Gitea API access
- Uses `shivammathur/setup-php@v2` for PHP setup
- Uses `actions/checkout@v4` with `submodules: recursive`
- Modeled after working wp-fedistream implementation
--- ---
Always refer to this document when starting work on this project. Good luck! Always refer to this document when starting work on this project. Good luck!
+54 -23
View File
@@ -20,10 +20,11 @@ A powerful WooCommerce plugin that adds tier pricing and package pricing functio
### Admin Features ### Admin Features
- Easy-to-use product meta boxes for adding tiers and packages - Easy-to-use product meta boxes for adding tiers and packages
- Global settings page under WooCommerce menu - Global settings page under WooCommerce menu with sub-tabs
- Configure display position (before/after add to cart, after price) - Configure display position (before/after add to cart, after price)
- Enable/disable tier or package pricing independently - Enable/disable tier or package pricing independently
- Sortable pricing rules - Sortable pricing rules
- License management with secure HMAC signature verification
### Frontend Features ### Frontend Features
- Beautiful pricing tables on product pages - Beautiful pricing tables on product pages
@@ -39,6 +40,20 @@ A powerful WooCommerce plugin that adds tier pricing and package pricing functio
2. Activate the plugin through the 'Plugins' menu in WordPress 2. Activate the plugin through the 'Plugins' menu in WordPress
3. Make sure WooCommerce is installed and activated 3. Make sure WooCommerce is installed and activated
### Automated Releases
This project uses a Gitea CI/CD pipeline for automated releases. When a version tag (e.g., `v1.4.0`) is pushed:
1. Code is checked out with git submodules (dependencies bundled)
2. The pipeline validates the plugin version matches the tag
3. Composer dependencies are installed (production only)
4. Translation files are compiled (.po → .mo)
5. A release package is created with proper exclusions
6. SHA256 checksum is generated
7. Release is published to Gitea with changelog notes extracted from CHANGELOG.md
The `magdev/wc-licensed-product-client` library is bundled as a git submodule to avoid private repository authentication during CI/CD.
## Configuration ## Configuration
### Global Settings ### Global Settings
@@ -110,7 +125,9 @@ When editing a product, scroll to the **Product data** panel:
``` ```
wc-tier-and-package-prices/ wc-tier-and-package-prices/
├── wc-tier-and-package-prices.php # Main plugin file (v1.1.20) ├── wc-tier-and-package-prices.php # Main plugin file (v1.4.0)
├── .gitea/workflows/
│ └── release.yml # CI/CD release pipeline
├── includes/ ├── includes/
│ ├── class-wc-tpp-admin.php # Admin settings integration │ ├── class-wc-tpp-admin.php # Admin settings integration
│ ├── class-wc-tpp-settings.php # WooCommerce settings page │ ├── class-wc-tpp-settings.php # WooCommerce settings page
@@ -137,7 +154,9 @@ wc-tier-and-package-prices/
│ ├── wc-tier-package-prices.pot # Translation template │ ├── wc-tier-package-prices.pot # Translation template
│ ├── wc-tier-package-prices-*.po # Translation sources │ ├── wc-tier-package-prices-*.po # Translation sources
│ └── wc-tier-package-prices-*.mo # Compiled translations │ └── wc-tier-package-prices-*.mo # Compiled translations
├── vendor/ # Composer dependencies (Twig) ├── lib/ # Bundled libraries (git submodules)
│ └── wc-licensed-product-client/ # License client library
├── vendor/ # Composer dependencies (generated)
├── CHANGELOG.md # Complete version history ├── CHANGELOG.md # Complete version history
├── INSTALLATION.md # Installation guide ├── INSTALLATION.md # Installation guide
├── QUICKSTART.md # Quick start guide ├── QUICKSTART.md # Quick start guide
@@ -149,7 +168,7 @@ wc-tier-and-package-prices/
- WordPress 6.0 or higher (tested up to 6.9.x) - WordPress 6.0 or higher (tested up to 6.9.x)
- WooCommerce 8.0 or higher (tested up to 10.x) - WooCommerce 8.0 or higher (tested up to 10.x)
- PHP 7.4 or higher - PHP 8.3 or higher (required since v1.3.0)
### Compatibility ### Compatibility
@@ -183,9 +202,39 @@ This plugin is licensed under the GPL v2 or later.
## Changelog ## Changelog
### Version 1.4.0 - 2026-01-29
__Current Release__ - CI/CD Release Pipeline
- __New__: Gitea CI/CD release pipeline for automated builds and releases
- __New__: Git submodule for `magdev/wc-licensed-product-client` library
- __Changed__: Composer now uses path repository for bundled license client
- __DevOps__: Automated version validation, translation compilation, and release publishing
See [CHANGELOG.md](CHANGELOG.md) for complete details.
### Version 1.3.1 - 2026-01-27
Secure License Client
- __Changed__: Switched to `SecureLicenseClient` with HMAC-SHA256 response signature verification
- __New__: Server Secret configuration field for secure communication with license server
- __Security__: Response signatures verified using HMAC-SHA256 with license-specific derived keys
### Version 1.3.0 - 2026-01-25
__Breaking Changes__ - PHP 8.3+ Required
- __Breaking__: Minimum PHP version increased from 7.4 to 8.3
- __New__: License management via `magdev/wc-licensed-product-client` library
- __New__: Settings page split into "General" and "License" sub-tabs
- __New__: AJAX-based license validation and activation with visual feedback
- __New__: License status caching with daily auto-refresh
- __New__: PHP version check with admin notice for incompatible servers
### Version 1.2.0 - 2025-12-29 ### Version 1.2.0 - 2025-12-29
__Current Release__ - Variable Product Support Variable Product Support
- __New__: Full support for WooCommerce variable products with variation-level pricing - __New__: Full support for WooCommerce variable products with variation-level pricing
- __New__: Each variation can have independent tier and package pricing configuration - __New__: Each variation can have independent tier and package pricing configuration
@@ -194,24 +243,6 @@ __Current Release__ - Variable Product Support
- __Fixed__: Quantity restrictions now work correctly per-variation - __Fixed__: Quantity restrictions now work correctly per-variation
- 100% backward compatible - no breaking changes - 100% backward compatible - no breaking changes
See [CHANGELOG.md](CHANGELOG.md) for complete details.
### Version 1.1.22 - 2025-12-23
- Increased width of label input fields in admin interface
#### Fixed
- **CRITICAL:** WooCommerce Blocks fatal error in mini-cart and cart blocks
- Fixed `woocommerce_store_api_product_quantity_editable` filter signature mismatch
- Filter now correctly accepts `WC_Product` object instead of cart item array
- Resolves "Cannot use object of type WC_Product_Simple as array" fatal error
#### Technical Details
- Updated `block_quantity_editable()` method signature to accept product object
- Changed parameter from `$cart_item` array to `WC_Product $product`
- Uses `$product->get_id()` instead of array access for product ID
- Full compatibility with WooCommerce Store API and block-based cart/checkout
### Recent Major Updates ### Recent Major Updates
#### Version 1.1.7 - Enhanced Tier Pricing #### Version 1.1.7 - Enhanced Tier Pricing
+11 -4
View File
@@ -1,7 +1,6 @@
{ {
"name": "magdev/wc-tier-package-prices", "name": "magdev/wc-tier-package-prices",
"description": "WooCommerce plugin for tier pricing and package prices with Twig templates", "description": "WooCommerce plugin for tier pricing and package prices with Twig templates",
"version": "1.3.1",
"type": "wordpress-plugin", "type": "wordpress-plugin",
"license": "GPL-2.0-or-later", "license": "GPL-2.0-or-later",
"authors": [ "authors": [
@@ -12,18 +11,26 @@
], ],
"repositories": [ "repositories": [
{ {
"type": "vcs", "type": "path",
"url": "https://src.bundespruefstelle.ch/magdev/wc-licensed-product-client.git" "url": "lib/wc-licensed-product-client"
} }
], ],
"require": { "require": {
"php": ">=8.3", "php": ">=8.3",
"twig/twig": "^3.0", "twig/twig": "^3.0",
"magdev/wc-licensed-product-client": "dev-main" "magdev/wc-licensed-product-client": "^0.2"
}, },
"autoload": { "autoload": {
"classmap": [ "classmap": [
"includes/" "includes/"
] ]
},
"config": {
"optimize-autoloader": true,
"platform": {
"php": "8.3.0"
} }
},
"minimum-stability": "stable",
"prefer-stable": true
} }
+2 -2
View File
@@ -4,7 +4,7 @@
* Plugin Name: WooCommerce Tier and Package Prices * Plugin Name: WooCommerce Tier and Package Prices
* Plugin URI: https://src.bundespruefstelle.ch/magdev/wc-tier-package-prices * Plugin URI: https://src.bundespruefstelle.ch/magdev/wc-tier-package-prices
* Description: Add tier pricing and package prices to WooCommerce products with configurable quantities at fixed prices * Description: Add tier pricing and package prices to WooCommerce products with configurable quantities at fixed prices
* Version: 1.3.1 * Version: 1.4.0
* Author: Marco Graetsch * Author: Marco Graetsch
* Author URI: https://src.bundespruefstelle.ch/magdev * Author URI: https://src.bundespruefstelle.ch/magdev
* Text Domain: wc-tier-package-prices * Text Domain: wc-tier-package-prices
@@ -46,7 +46,7 @@ if (!function_exists('wc_tpp_php_version_notice')) {
// Define plugin constants // Define plugin constants
if (!defined('WC_TPP_VERSION')) { if (!defined('WC_TPP_VERSION')) {
define('WC_TPP_VERSION', '1.3.1'); define('WC_TPP_VERSION', '1.4.0');
} }
if (!defined('WC_TPP_PLUGIN_DIR')) { if (!defined('WC_TPP_PLUGIN_DIR')) {
define('WC_TPP_PLUGIN_DIR', plugin_dir_path(__FILE__)); define('WC_TPP_PLUGIN_DIR', plugin_dir_path(__FILE__));