You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add duplicate run detection to skip redundant builds (#253)
* Add duplicate run detection to skip redundant builds
Introduce a `Check if already built for this SHA` step that
inspects the remote build branch before any toolchain setup.
If the current commit SHA is already embedded in `style.css`
(themes) or the main plugin PHP file (plugins), the entire
compilation pipeline is skipped and the workflow proceeds
directly to packaging the existing build branch content.
Key changes:
- New early-exit step reads `SHA:` header from the remote
build branch and sets `SKIP_BUILD=true` when a match is
found, bypassing install, compile, and commit steps
- All subsequent build steps are guarded with
`SKIP_BUILD != 'true'` conditions
- `Determine package type` and `Prepare WordPress *` steps
moved earlier (before npm/composer install) so the SHA
can be embedded before compilation
- SHA field handling changed from a plain replace to an
upsert: inserts a new `SHA:` line after `Version:` when
the field is absent, replaces it when present
- Downstream jobs remain unaffected; the artifact output is
always populated regardless of whether the build was fresh
or reused
- Library projects do not embed a `SHA:` field and always
rebuild
- Trailing whitespace cleaned up throughout the file
* chore: merge prepare package steps
* chore: merge check and prepare package steps
* Update .github/workflows/build-and-distribute.yml
Co-authored-by: Philipp Bammes <8144115+tyrann0us@users.noreply.github.com>
Signed-off-by: Moritz Meißelbach <arbelzapf@gmail.com>
* Add concurrency serialization to build-and-distribute job
Prevent duplicate builds when the same SHA is triggered more than
once (e.g., push + manual dispatch racing). By setting
`cancel-in-progress: false`, a queued second run will detect the
already-built artifact and resolve without repeating the full build.
- Add `concurrency` group scoped to SHA + branch name on the job
- Update docs to reflect the new serialization behavior and recommend
`cancel-in-progress: false` in caller workflows
---------
Signed-off-by: Moritz Meißelbach <arbelzapf@gmail.com>
Co-authored-by: Philipp Bammes <p.bammes@syde.com>
Co-authored-by: Philipp Bammes <8144115+tyrann0us@users.noreply.github.com>
Copy file name to clipboardExpand all lines: docs/build-and-distribute.md
+22-11Lines changed: 22 additions & 11 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,14 +5,15 @@ This action can be used to build plugin and theme archives and push them to corr
5
5
To achieve that, the reusable workflow:
6
6
7
7
1. Inspects the origin branch and determines the correlating build branch (strips `dev/` prefix)
8
-
2. Installs dependencies (including dev-dependencies) defined in `composer.json`
9
-
3. Installs Node.js dependencies and compiles assets via `npm run build`
10
-
4. Updates version information in plugin/theme headers and `package.json`
11
-
5. Executes [WordPress Translation Downloader](https://github.com/inpsyde/wp-translation-downloader) if configured by the package
12
-
6. Executes [PHP-Scoper](https://github.com/humbug/php-scoper) if configured by the package
13
-
7. Applies `.distignore` file filtering if present
14
-
8. Commits and pushes the build artifact to the determined build branch
15
-
9. Uploads the build as a GitHub Actions artifact for download
8
+
2. Checks whether the build branch already contains the current commit SHA — if so, skips steps 3–8 entirely (see [Duplicate run detection](#duplicate-run-detection))
9
+
3. Installs dependencies (including dev-dependencies) defined in `composer.json`
10
+
4. Installs Node.js dependencies and compiles assets via `npm run build`
11
+
5. Updates version and SHA information in plugin/theme headers and `package.json`
12
+
6. Executes [WordPress Translation Downloader](https://github.com/inpsyde/wp-translation-downloader) if configured by the package
13
+
7. Executes [PHP-Scoper](https://github.com/humbug/php-scoper) if configured by the package
14
+
8. Applies `.distignore` file filtering if present
15
+
9. Commits and pushes the build artifact to the determined build branch
16
+
10. Uploads the build as a GitHub Actions artifact for download
16
17
17
18
## Branch naming convention
18
19
@@ -177,7 +178,7 @@ By default, the workflow strips the `dev/` prefix from the origin branch to dete
177
178
- Ensure your `package.json` includes a `build` script for asset compilation
178
179
- Use `.distignore` to exclude development files from the final build
179
180
- Consider using [path filters](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#example-including-paths) to avoid unnecessary builds when only documentation changes
180
-
- Use [concurrency settings](https://docs.github.com/en/actions/using-jobs/using-concurrency) to prevent conflicts when multiple pushes occur rapidly
181
+
- Use [concurrency settings](https://docs.github.com/en/actions/using-jobs/using-concurrency) to prevent conflicts when multiple pushes occur rapidly — the workflow serializes concurrent builds for the same SHA internally, so a queued second run will skip the actual build and resolve via the pre-built artifact
181
182
182
183
```yml
183
184
name: Build and push assets
@@ -201,7 +202,7 @@ on:
201
202
202
203
concurrency:
203
204
group: ${{ github.workflow }}-${{ github.ref }}
204
-
cancel-in-progress: true
205
+
cancel-in-progress: false
205
206
206
207
jobs:
207
208
build-and-distribute:
@@ -249,7 +250,7 @@ This makes the workflow flexible enough to handle both full-stack WordPress proj
249
250
The workflow handles version information for both plugins and themes:
250
251
251
252
- Updates `Version:` header in the main plugin file
252
-
- Updates `SHA:` header with the current commit hash
253
+
- Upserts `SHA:` header with the current commit hash — replaces the existing value if the field is present, or inserts a new line after `Version:` if it is absent
253
254
- Updates version in `package.json` and `composer.json`
254
255
255
256
### Asset Compilation
@@ -272,6 +273,16 @@ If a `scoper.inc.php` file is present, the workflow will:
272
273
2. Rebuild the autoloader for the scoped dependencies
273
274
3. Ensure unique autoload cache keys to prevent conflicts
274
275
276
+
### Duplicate run detection
277
+
278
+
The workflow detects when the build branch already contains a build for the current commit SHA and skips the entire compilation pipeline in that case.
279
+
280
+
After each successful build, the commit SHA is written into the `SHA:` header of `style.css` (themes) or the main plugin PHP file (plugins). On subsequent runs for the same commit, the workflow reads that field from the remote build branch _before_ any toolchain setup. If the SHA matches, all build and compile steps are skipped and the workflow proceeds directly to packaging the existing build branch content and uploading the artifact.
281
+
282
+
This is transparent to downstream jobs: the `artifact` output is always populated, whether the build was freshly compiled or reused.
283
+
284
+
**Applies to WordPress plugins and themes only.** Library projects do not embed a `SHA:` field, so they always rebuild.
285
+
275
286
### Distignore Support
276
287
277
288
If a `.distignore` file is present, the workflow will:
0 commit comments