You've already forked wc-tier-and-package-prices
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a4b84f7e41 | |||
| 2e9c948a07 | |||
| dd4333bd11 | |||
| b909221ae2 | |||
| d80c9d90f9 | |||
| 2bf0cd82fe | |||
| 9451cc1965 | |||
| 02b0308058 | |||
| 38e9506d4e |
217
.gitea/workflows/release.yml
Normal file
217
.gitea/workflows/release.yml
Normal 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
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "lib/wc-licensed-product-client"]
|
||||||
|
path = lib/wc-licensed-product-client
|
||||||
|
url = ../wc-licensed-product-client.git
|
||||||
14
CHANGELOG.md
14
CHANGELOG.md
@@ -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
|
||||||
|
|||||||
276
CLAUDE.md
276
CLAUDE.md
@@ -1,7 +1,7 @@
|
|||||||
# WooCommerce Tier and Package Prices - AI Context Document
|
# WooCommerce Tier and Package Prices - AI Context Document
|
||||||
|
|
||||||
**Last Updated:** 2026-01-27
|
**Last Updated:** 2026-01-29
|
||||||
**Current Version:** 1.3.1
|
**Current Version:** 1.4.0
|
||||||
**Author:** Marco Graetsch
|
**Author:** Marco Graetsch
|
||||||
**Project Status:** Production-ready WordPress plugin
|
**Project Status:** Production-ready WordPress plugin
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ 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.2
|
### Version 1.4.1
|
||||||
|
|
||||||
- No planned changes yet
|
- No planned changes yet
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -1200,8 +1201,8 @@ The plugin architecture is solid and well-tested. Most bugs arise from:
|
|||||||
- All 7 language files updated and compiled
|
- All 7 language files updated and compiled
|
||||||
|
|
||||||
6. Created release package:
|
6. Created release package:
|
||||||
- Package size: 745KB
|
- Package size: 775KB (after proper exclusions)
|
||||||
- 642 files included
|
- 650 files included
|
||||||
- SHA256 checksum generated
|
- SHA256 checksum generated
|
||||||
|
|
||||||
7. Updated README.md:
|
7. Updated README.md:
|
||||||
@@ -1209,6 +1210,10 @@ The plugin architecture is solid and well-tested. Most bugs arise from:
|
|||||||
- Updated PHP requirement to 8.3
|
- Updated PHP requirement to 8.3
|
||||||
- Added v1.3.0 and v1.3.1 changelog entries
|
- 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:**
|
**Key Learnings:**
|
||||||
|
|
||||||
- `SecureLicenseClient` requires `serverSecret` parameter for HMAC verification
|
- `SecureLicenseClient` requires `serverSecret` parameter for HMAC verification
|
||||||
@@ -1216,6 +1221,55 @@ The plugin architecture is solid and well-tested. Most bugs arise from:
|
|||||||
- `RateLimitExceededException` has a `retryAfter` property (int seconds)
|
- `RateLimitExceededException` has a `retryAfter` property (int seconds)
|
||||||
- Always check library documentation in `docs/server-implementation.md` for implementation requirements
|
- 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!
|
||||||
|
|||||||
39
README.md
39
README.md
@@ -40,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
|
||||||
@@ -111,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.3.1)
|
├── 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
|
||||||
@@ -138,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
|
||||||
@@ -184,18 +202,25 @@ 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
|
### Version 1.3.1 - 2026-01-27
|
||||||
|
|
||||||
__Current Release__ - Secure License Client
|
Secure License Client
|
||||||
|
|
||||||
- __Changed__: Switched to `SecureLicenseClient` with HMAC-SHA256 response signature verification
|
- __Changed__: Switched to `SecureLicenseClient` with HMAC-SHA256 response signature verification
|
||||||
- __New__: Server Secret configuration field for secure communication with license server
|
- __New__: Server Secret configuration field for secure communication with license server
|
||||||
- __New__: Rate limit exception handling with retry time display
|
|
||||||
- __New__: Signature verification and URL validation error handling
|
|
||||||
- __Security__: Response signatures verified using HMAC-SHA256 with license-specific derived keys
|
- __Security__: Response signatures verified using HMAC-SHA256 with license-specific derived keys
|
||||||
|
|
||||||
See [CHANGELOG.md](CHANGELOG.md) for complete details.
|
|
||||||
|
|
||||||
### Version 1.3.0 - 2026-01-25
|
### Version 1.3.0 - 2026-01-25
|
||||||
|
|
||||||
__Breaking Changes__ - PHP 8.3+ Required
|
__Breaking Changes__ - PHP 8.3+ Required
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
1
lib/wc-licensed-product-client
Submodule
1
lib/wc-licensed-product-client
Submodule
Submodule lib/wc-licensed-product-client added at 56abe8a97c
@@ -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__));
|
||||||
|
|||||||
Reference in New Issue
Block a user