From a27347851b62587dfb85c888ddf370eeb8c810c6 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Wed, 6 May 2026 14:58:43 +0200 Subject: [PATCH 1/7] Exclude non-version tags from release detection --- .github/workflows/build-and-distribute.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-and-distribute.yml b/.github/workflows/build-and-distribute.yml index 4550d057..a0661ea2 100644 --- a/.github/workflows/build-and-distribute.yml +++ b/.github/workflows/build-and-distribute.yml @@ -139,7 +139,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_USER_SSH_KEY }} run: | # Fetch latest public release - LATEST_RELEASE=$(git for-each-ref --sort=-creatordate --count=1 --format='%(refname:short)' refs/tags || echo "") + LATEST_RELEASE=$(git for-each-ref --sort=-creatordate --count=1 --format='%(refname:short)' 'refs/tags/[0-9]*' || echo "") if [ -z "$LATEST_RELEASE" ]; then echo "No releases found, using default version 0.0.0." From 8bee3257ab56a19659804b28ca41f9174fd92bb5 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Wed, 6 May 2026 16:16:23 +0200 Subject: [PATCH 2/7] Extract version tags with optional "v" prefix New logic extracts the first tag that does not have a "/" in it and starts with a digit, or the letter "v" followed by a digit --- .github/workflows/build-and-distribute.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-and-distribute.yml b/.github/workflows/build-and-distribute.yml index a0661ea2..3b41080e 100644 --- a/.github/workflows/build-and-distribute.yml +++ b/.github/workflows/build-and-distribute.yml @@ -139,7 +139,10 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_USER_SSH_KEY }} run: | # Fetch latest public release - LATEST_RELEASE=$(git for-each-ref --sort=-creatordate --count=1 --format='%(refname:short)' 'refs/tags/[0-9]*' || echo "") + LATEST_RELEASE=$(git for-each-ref --sort=-creatordate --format='%(refname:short)' refs/tags \ + | grep -E '^v?[0-9]' \ + | grep -v '/' \ + | head -1 || echo "") if [ -z "$LATEST_RELEASE" ]; then echo "No releases found, using default version 0.0.0." From df04f73e23381b0b5dca7cce017dd07cb3d9bc17 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Wed, 6 May 2026 16:20:12 +0200 Subject: [PATCH 3/7] Prefer GH release API for latest release Keep the existing tag based logic as fallback if the release API fails for some reason --- .github/workflows/build-and-distribute.yml | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-and-distribute.yml b/.github/workflows/build-and-distribute.yml index 3b41080e..b3b613ba 100644 --- a/.github/workflows/build-and-distribute.yml +++ b/.github/workflows/build-and-distribute.yml @@ -139,10 +139,15 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_USER_SSH_KEY }} run: | # Fetch latest public release - LATEST_RELEASE=$(git for-each-ref --sort=-creatordate --format='%(refname:short)' refs/tags \ - | grep -E '^v?[0-9]' \ - | grep -v '/' \ - | head -1 || echo "") + LATEST_RELEASE=$(gh release list --limit 1 --json tagName --jq '.[0].tagName' || echo "") + + # Fallback: Fetch latest version tag (supports 1.2.3 and v1.2.3, ignores tags with slashes) + if [[ -z $LATEST_RELEASE ]]; then + LATEST_RELEASE=$(git for-each-ref --sort=-creatordate --format='%(refname:short)' refs/tags \ + | grep -E '^v?[0-9]' \ + | grep -v '/' \ + | head -1 || echo "") + fi if [ -z "$LATEST_RELEASE" ]; then echo "No releases found, using default version 0.0.0." From 37fbc05c85d592af4f24088a301a9ab8c7647b00 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Wed, 13 May 2026 17:54:30 +0200 Subject: [PATCH 4/7] Remove fallback logic for LATEST_RELEASE lookup --- .github/workflows/build-and-distribute.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.github/workflows/build-and-distribute.yml b/.github/workflows/build-and-distribute.yml index b3b613ba..84c35813 100644 --- a/.github/workflows/build-and-distribute.yml +++ b/.github/workflows/build-and-distribute.yml @@ -141,14 +141,6 @@ jobs: # Fetch latest public release LATEST_RELEASE=$(gh release list --limit 1 --json tagName --jq '.[0].tagName' || echo "") - # Fallback: Fetch latest version tag (supports 1.2.3 and v1.2.3, ignores tags with slashes) - if [[ -z $LATEST_RELEASE ]]; then - LATEST_RELEASE=$(git for-each-ref --sort=-creatordate --format='%(refname:short)' refs/tags \ - | grep -E '^v?[0-9]' \ - | grep -v '/' \ - | head -1 || echo "") - fi - if [ -z "$LATEST_RELEASE" ]; then echo "No releases found, using default version 0.0.0." LATEST_RELEASE="0.0.0" From 1304d5cb4673ffa2b5cc397adee91b50d13d8651 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Thu, 21 May 2026 12:56:19 +0200 Subject: [PATCH 5/7] Document change in LATEST_RELEASE detection --- docs/build-and-distribute.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/build-and-distribute.md b/docs/build-and-distribute.md index c1284cab..cc40679b 100644 --- a/docs/build-and-distribute.md +++ b/docs/build-and-distribute.md @@ -29,10 +29,10 @@ This approach keeps source code separate from build artifacts while maintaining If no `PACKAGE_VERSION` is provided, the workflow automatically: -1. Fetches the latest tag from the repository +1. Fetches the latest GitHub Release from the repository 2. Strips the `dev/` prefix from the branch name and normalizes it to be semver-compatible 3. Creates a pre-release version like `1.2.3-main` or `2.0.0-abc-123` -4. Falls back to `0.0.0-{branch}` if no tags exist +4. Falls back to `0.0.0-{branch}` if no published release exists **Examples:** @@ -121,7 +121,7 @@ jobs: | `PHP_TOOLS` | `''` | PHP tools supported by shivammathur/setup-php to be installed | | `COMPOSER_ARGS` | `'--no-dev --prefer-dist --optimize-autoloader'` | Set of arguments passed to Composer when gathering production dependencies | | `PACKAGE_NAME` | `''` | The name of the package (falls back to the repository name) | -| `PACKAGE_VERSION` | `''` | The new package version. If not provided, will use latest tag version with branch name as pre-release identifier | +| `PACKAGE_VERSION` | `''` | The new package version. If not provided, will use the latest GitHub Release version with branch name as pre-release identifier | | `PRE_SCRIPT` | `''` | Run custom shell code before creating the release archive | | `BUILT_BRANCH_NAME` | `''` | Override the automatic build branch naming (defaults to stripping `dev/` prefix from origin branch) | From 057b338af9795ce822bd83aea2a624e997921f2f Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Thu, 21 May 2026 13:01:19 +0200 Subject: [PATCH 6/7] Document semver requirement and format samples --- docs/build-and-distribute.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/docs/build-and-distribute.md b/docs/build-and-distribute.md index cc40679b..c6799a2a 100644 --- a/docs/build-and-distribute.md +++ b/docs/build-and-distribute.md @@ -42,6 +42,34 @@ If no `PACKAGE_VERSION` is provided, the workflow automatically: This ensures every build has a unique, meaningful version identifier that traces back to both the base release and the source branch. +### GitHub Release tag format + +The latest GitHub Release tag is used as the base for `PACKAGE_VERSION` and is validated by `npm version` against semver. Release tags must therefore exactly match this pattern: + +``` +[v]MAJOR.MINOR.PATCH[-IDENTIFIER] +``` + +
+Valid and invalid samples + +**Valid:** +- `1.2.3` +- `v1.2.3` +- `1.2.3-alpha` +- `1.2.3-feature.1` +- `1.2.3-2026-05-21` + +**Invalid:** +- `1.2` → missing PATCH +- `1.2.3.4` → too many segments +- `1.2.3-` → empty identifier +- `v.1.2.3` → dot after `v` +- `a.b.c` → non-numeric segments +- `release/1.2.3` → contains a slash + +
+ ## Simple usage example ### WordPress Plugin/Theme or PHP Library From 77b623e301217708dc7474343ec49fb7e4166e37 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Thu, 21 May 2026 13:02:27 +0200 Subject: [PATCH 7/7] Lint the updated Markdown file --- docs/build-and-distribute.md | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/docs/build-and-distribute.md b/docs/build-and-distribute.md index c6799a2a..f7618ac0 100644 --- a/docs/build-and-distribute.md +++ b/docs/build-and-distribute.md @@ -54,6 +54,7 @@ The latest GitHub Release tag is used as the base for `PACKAGE_VERSION` and is v Valid and invalid samples **Valid:** + - `1.2.3` - `v1.2.3` - `1.2.3-alpha` @@ -61,6 +62,7 @@ The latest GitHub Release tag is used as the base for `PACKAGE_VERSION` and is v - `1.2.3-2026-05-21` **Invalid:** + - `1.2` → missing PATCH - `1.2.3.4` → too many segments - `1.2.3-` → empty identifier @@ -139,20 +141,19 @@ jobs: ### Inputs -| Name | Default | Description | -|-----------------------|--------------------------------------------------|------------------------------------------------------------------------------------------------------------------| -| `NODE_OPTIONS` | `''` | Space-separated list of command-line Node options | -| `NODE_VERSION` | `18` | Node version with which the assets will be compiled | -| `NPM_REGISTRY_DOMAIN` | `'https://npm.pkg.github.com/'` | Domain of the private npm registry | -| `PHP_VERSION` | `'8.2'` | PHP version with which the PHP tools are to be executed | -| `PHP_EXTENSIONS` | `''` | PHP extensions supported by shivammathur/setup-php to be installed or disabled | -| `PHP_TOOLS` | `''` | PHP tools supported by shivammathur/setup-php to be installed | -| `COMPOSER_ARGS` | `'--no-dev --prefer-dist --optimize-autoloader'` | Set of arguments passed to Composer when gathering production dependencies | -| `PACKAGE_NAME` | `''` | The name of the package (falls back to the repository name) | +| Name | Default | Description | +|-----------------------|--------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------| +| `NODE_OPTIONS` | `''` | Space-separated list of command-line Node options | +| `NODE_VERSION` | `18` | Node version with which the assets will be compiled | +| `NPM_REGISTRY_DOMAIN` | `'https://npm.pkg.github.com/'` | Domain of the private npm registry | +| `PHP_VERSION` | `'8.2'` | PHP version with which the PHP tools are to be executed | +| `PHP_EXTENSIONS` | `''` | PHP extensions supported by shivammathur/setup-php to be installed or disabled | +| `PHP_TOOLS` | `''` | PHP tools supported by shivammathur/setup-php to be installed | +| `COMPOSER_ARGS` | `'--no-dev --prefer-dist --optimize-autoloader'` | Set of arguments passed to Composer when gathering production dependencies | +| `PACKAGE_NAME` | `''` | The name of the package (falls back to the repository name) | | `PACKAGE_VERSION` | `''` | The new package version. If not provided, will use the latest GitHub Release version with branch name as pre-release identifier | -| `PRE_SCRIPT` | `''` | Run custom shell code before creating the release archive | -| `BUILT_BRANCH_NAME` | `''` | Override the automatic build branch naming (defaults to stripping `dev/` prefix from origin branch) | - +| `PRE_SCRIPT` | `''` | Run custom shell code before creating the release archive | +| `BUILT_BRANCH_NAME` | `''` | Override the automatic build branch naming (defaults to stripping `dev/` prefix from origin branch) | #### A note on `BUILT_BRANCH_NAME`