Ship the frontend build as a packaged archive - #40
Merged
Merged
Conversation
Replace the committed public/build/ directory with a single committed archive, build-dist/build-<id>.zip, which the Studio UI Bundle extracts into public/build/ during cache warmup. - rsbuild.config.ts derives the build id from the contents of assets/ via getBuildGroupId() instead of a random uuid, and writes it into the output with pluginWriteBuildId(). Unchanged source now yields the same id, so a rebuild produces no diff. - Add the package-build script (studio-package-build) and drop the now unused uuid dependency. - WebpackEntryPointProvider implements BuildArchiveProviderInterface via BuildArchiveExtractionTrait. - Gitignore public/build/ and commit build-dist/ instead. - Collapse the two build workflows that were both active into a single thin caller of reusable-studio-frontend-build-packaged.yaml. The old hand-rolled workflow committed the expanded ./public/ output, and the parked reusable caller watched assets/studio/** which does not exist in this repo. The archive mechanism needs studio-ui-bundle 2025.4.9+ or 2026.2.1+, so the composer constraint and the npm dependency are raised accordingly. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…tead Restore .github/workflows/studio-frontend-build.yaml to its state on main and move the packaged build over to studio-frontend-build.yml, which now calls reusable-studio-frontend-build-packaged.yaml with working-directory: assets and watches assets/** instead of the assets/studio/** path that does not exist in this repository. Renamed to "Studio Frontend Build Packaged" so the two workflows are distinguishable in the Actions UI. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Removed comments explaining the build process.
Gitignoring the expanded build left no tracked file under public/, so the directory would not exist after a fresh composer install and there would be nothing for assets:install to link. Track public/build/.gitkeep and negate it in .gitignore, following studio-ui-bundle. The pre-build cleanup in rsbuild.config.ts swept every entry in public/build/, which deleted that .gitkeep on each build. Restrict it to directories; plain files at that level are left alone. pluginWriteBuildId already skips non-directories. Remove the 43 "peer": true markers that the dependency update added to assets/package-lock.json, keeping the 2 that were already there. They are install metadata and do not affect npm ci resolution. The build id is a hash of assets/, so the lockfile and config edits change it: the archive is rebuilt as build-fc755267691a.zip. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
studio-frontend-build.yaml was the old inline lint/check-types/build
pipeline. It was superseded by studio-frontend-build.yml, which delegates
to the reusable workflow, but the file was never removed, so both ran
under the same name "Studio Frontend Build".
The leftover one could not work any more: its jobs inherit the
workflow-level `contents: read` permission, so the install job's
actions/cache step runs in read mode ("cache write denied: token has no
writable scopes") and never saves ./assets/node_modules. The dependent
lint and check-types jobs then start on a cache miss with no
node_modules, which is why lint reports "eslint: not found" and
check-types falls through to the runner's global tsc (a newer major that
removed baseUrl) without @types/webpack-env installed.
It also used pull_request_target while checking out the pull request
head, which runs fork code with a write-scoped token.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Carries the two jobs over from the removed studio-frontend-build.yaml so the repository keeps its own lint-fix and type-check steps, and turns the reusable workflow's equivalents off so neither runs twice and only one job pushes to the branch. The jobs install their own dependencies instead of depending on a shared install job that caches ./assets/node_modules. That cache was the reason both jobs failed: the cache token is not writable here, so the save was denied and the restore missed, leaving the jobs with nothing installed. setup-node's npm cache is kept, since it caches the download cache rather than the installed tree and needs no cross-job save. The build is ordered after both jobs, matching the removed workflow. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The caller's own lint and check-types jobs ran npm ci and repo scripts with a contents: write token and persisted git credentials, so any npm install hook could push to the repository. The reusable packaged workflow already runs the same lint-fix and check-types scripts, but in read-only jobs without git credentials, and keeps the write token in commit jobs that execute no project code. It also checks out fork PRs via refs/pull/<n>/head, which works for private forks. Drop the duplicated jobs and go back to a thin caller. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
berfinyuksel
approved these changes
Sep 30, 2026
berfinyuksel
requested changes
Sep 30, 2026
berfinyuksel
left a comment
Contributor
There was a problem hiding this comment.
workflow needs to be checked
berfinyuksel
added a commit
that referenced
this pull request
Sep 30, 2026
The install job saves node_modules to actions/cache for the lint and check-types jobs. Since GitHub's read-only cache for untrusted triggers (2026-06-26), pull_request_target runs cannot save, so those jobs start with nothing installed and fail on every PR. The reusable packaged workflow in studio-frontend-build.yml replaces it (see #40).
berfinyuksel
self-requested a review
September 30, 2026 15:18
berfinyuksel
approved these changes
Sep 30, 2026
berfinyuksel
left a comment
Contributor
There was a problem hiding this comment.
after rebase tests will turn green you can continue merge
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ValeriaMaltseva
added a commit
to pimcore/studio-ui-bundle
that referenced
this pull request
Sep 30, 2026
pimcore/studio-example-bundle#40 added the build-id logic above the entry config, moving `main: './js/src/main.ts'` from line 49 to line 59. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ValeriaMaltseva
added a commit
to pimcore/studio-ui-bundle
that referenced
this pull request
Sep 30, 2026
…4124) * [Docs] The Studio Example Bundle now ships its build as an archive The Example Bundle moved from a committed public/build/ directory to a committed build-dist/build-<id>.zip (pimcore/studio-example-bundle#40), so it is no longer an example of the "commit the expanded build directory" option, and the provider linked from Registering the Frontend Build is no longer a plain provider. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * [Docs] Point the rsbuild main.ts link at its new line pimcore/studio-example-bundle#40 added the build-id logic above the entry config, moving `main: './js/src/main.ts'` from line 49 to line 59. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resolves pimcore/platform-version#501.
Rolls out the packaged frontend-build mechanism (zip archive + warmup extraction) documented in
Shipping the Frontend Build as an Archive.
Until now this bundle committed the expanded
public/build/directory, so every build churned therepository with newly hashed filenames and branches conflicted on the output. It now commits a single
build-dist/build-<id>.zip, which the Studio UI Bundle extracts intopublic/build/duringbin/console cache:warmup.Changes
assets/rsbuild.config.tsgetBuildGroupId(__dirname)instead of a randomuuid; addspluginWriteBuildIdso the id is written into the output as.build-id; the pre-build cleanup only sweeps stale build directories, sopublic/build/.gitkeepsurvivesassets/package.jsonpackage-buildscript (studio-package-build);@pimcore/studio-ui-bundle2026.2.0→^2026.2.11; drops the now unuseduuiddependencyassets/package-lock.jsonsrc/Webpack/WebpackEntryPointProvider.phpBuildArchiveProviderInterfaceviaBuildArchiveExtractionTrait.gitignore/public/build/*, keeps/public/build/.gitkeeppublic/build/.gitkeeppublic/build/in git so it exists aftercomposer installforassets:installto linkbuild-dist/build-fc755267691a.zippublic/build/.github/workflows/studio-frontend-build.ymlreusable-studio-frontend-build-packaged.yamlwithworking-directory: assets.github/workflows/studio-frontend-build.yamlcomposer.jsonpimcore/studio-ui-bundle→^2025.4.9 || ^2026.2.1README.mdWorkflows
The repository had two workflows, both named "Studio Frontend Build":
studio-frontend-build.ymlcalled the non-packagedreusable-studio-frontend-build.yamlbut watchedassets/studio/**, a path that does not exist in this repository, so it never triggered.studio-frontend-build.yamlwas the old inline lint/check-types/build pipeline that committed theexpanded
./public/output.studio-frontend-build.ymlnow calls the packaged reusable workflow withworking-directory: assets,watches
assets/**(plusbuild-dist/**on push) and is renamed to "Studio Frontend Build Packaged".Lint (
lint-fix) and type checks (check-types) run inside the reusable workflow. It executes projectcode in read-only jobs without persisted git credentials and keeps the
contents: writetoken in commitjobs that run no project code.
studio-frontend-build.yamlis removed. It could not work any more: its jobs rely on anactions/cacheof./assets/node_modulessaved by a separate install job, but the token has nowritable cache scope, so the save is denied and
lint/check-typesstart with nothing installed.It also used
pull_request_targetwhile checking out the pull request head, which runs fork code witha write-scoped token.
Composer constraint drops the 2026.1 line
The archive mechanism is only available in studio-ui-bundle 2025.4.9+ and 2026.2.1+, so
^2025.4 || ^2026.1became^2025.4.9 || ^2026.2.1.studio-backend-bundleandstudio-dashboards-bundleare left at^2025.4 || ^2026.1— pre-existing and out of scope here, butthey are now inconsistent with the ui constraint and probably want the same treatment.
Verification
"Studio Frontend Build Packaged" is green on the branch head: lint, check-types, build and
commit-build all pass. The meaningful result is what
commit-builddid not do: CI rebuilt fromsource on a clean runner, derived the same build id, produced the same archive and had nothing to
commit, leaving the branch head unchanged. That is the no-churn property the change exists for,
confirmed across machines rather than only locally.
Also checked locally in a clean clone:
npm run check-typespasses;npm run lint-fixproduces no diffnpm run build && npm run package-buildproducesbuild-dist/build-<id>.zip; repeating bothleaves it byte-identical (
already up to date for this source; nothing to do)public/build/reproduces exactly the*/entrypoints.jsonglob theextractor uses, with
.build-idpresent and the declaredexposeRemoteentry point in placeentrypoints.jsonURLs match theassetPrefix(
/bundles/pimcorestudioexample/build/<id>/...)Not verified locally: no PHP lint or static analysis was run (no PHP available on the machine). The
provider was checked against the upstream
BuildArchiveExtractionTrait/BuildArchiveProviderInterfacesignatures and mirrors the equivalent one in
studio-dashboards-bundle.Note on the red
lint/check-typeschecksThese come from
studio-frontend-build.yaml, not from this branch. It triggers onpull_request_target, so GitHub runs the copy onmain(where the file still exists) against this PR,and it fails for the reason above (
eslint: not found, and the runner's globaltscrejectingbaseUrlwithout@types/webpack-env). The same checks pass in "Studio Frontend Build Packaged".The red checks disappear once this merges and the file is gone from
main.Follow-up
doc/04_Extending/04_Shipping_the_Frontend_Build_as_an_Archive.mdin studio-ui-bundle states"Commit the expanded build directory (
public/build/). This is what the Studio Example Bundle does",which stops being true once this merges. Handled in pimcore/studio-ui-bundle#4124.
🤖 Generated with Claude Code