Add verified MFE bake task and baked manifest

What does this MR do and why?

rake gitlab:mfe:bake — the verified path from registry to release assets:

  1. downloads each pinned app's sidecar manifest from the configured registry (generic packages API),
  2. verifies the sidecar SHA-256 against the pin,
  3. downloads every listed file and verifies every per-file SHA-256 before writing a single byte under public/assets/mfe/<name>/<version>/,
  4. records the result in baked-manifest.json (Gitlab::Mfe::BakedManifest, mtime-cached reader for request-time version lookups).

Any failure aborts the whole bake with a non-zero exit, so browsers never see partially- or un-verified assets. The task performs no DB access, so it can run during CI asset compilation. With the pin file still empty the task is a clean no-op.

Note: wiring this task into the build pipeline (compile-production-assets or a dedicated job), so release artifacts actually carry baked apps, is tracked separately in #605806.

How to verify

bin/rspec spec/tasks/gitlab/mfe_rake_spec.rb spec/lib/gitlab/mfe/baked_manifest_spec.rb
bin/rake gitlab:mfe:bake   # clean no-op with the empty pin file

Bake a real application (Duo Chat)

No configuration is needed for baking itself: registry reads are anonymous against the default source (gitlab.com), and the task touches no database. Pin the real Duo Chat MFE — published from https://gitlab.com/gitlab-org/frontend/gitlab-mfe to its generic package registry — in config/mfe.yml:

apps:
  - name: duo_chat
    project: gitlab-org/frontend/gitlab-mfe
    version: 0.2.0
    manifest_sha256: 13a8f610c44190e6cbead9e7ba2b48316677479a1e682fc894ed1c1c669eb38d
bin/rake gitlab:mfe:bake
# MFE bake: baked 1 app(s) into .../public/assets/mfe.

The bake downloads ~212 files and verifies every digest before writing. The result must be publicly fetchable — baked assets are plain files under public/assets/, served statically with no auth and no new routes:

curl -I http://gdk.test:3000/assets/mfe/duo_chat/0.2.0/mf-manifest.json   # HTTP 200
curl -s http://gdk.test:3000/assets/mfe/baked-manifest.json               # {"schemaVersion":1,"apps":{"duo_chat":{"version":"0.2.0"}}}

Negative check: flip one hex digit of the pinned manifest_sha256 and re-run — the bake must abort with a digest mismatch and a non-zero exit, without writing anything.

Stack

This is part of a stacked series extracted from a single 1700+ line MR for reviewability. Each part is independently verifiable and leaves master inert: nothing is user-reachable until an application is pinned.

# Scope MR
1 Config plumbing + instance kill switch !245043 (closed)
2 Sidecar manifest validation + pin-file catalog !245044 (closed)
3 Verified bake task + baked manifest !245045 (closed)
4 Same-origin delivery endpoint !245046 (closed)
5 Dev-mode proxy for local development !245301 (closed)

Merging bottom-up; when a part merges, GitLab retargets the next one to master automatically.

A separate demonstration MR shows the whole stack working end to end with the real Duo Chat MFE (production bake + dev-mode HMR): !245014.

Related to #605798.

Edited by Illya Klymov

Merge request reports

Loading