Draft: Demo: MFE delivery end to end with Duo Chat (dev + prod)

What does this MR do and why?

Demonstration — not part of the mergeable stack. This MR carries the whole MFE delivery stack plus a single demonstration commit of its own: config/mfe.yml pinning the real Duo Chat MFE 0.2.0, published from https://gitlab.com/gitlab-org/frontend/gitlab-mfe to its generic package registry (212 files + sidecar manifest). It exists so the platform can be seen working end to end — production path and development path — with a real application. It is not meant to be merged as-is; the stack below merges bottom-up, and production pins land through their owning surfaces.

Local configuration (config/gitlab.yml)

These blocks live only in local GDK config (never committed). Note: gdk reconfigure / gdk reset-data regenerate gitlab.yml and silently wipe them — re-add afterwards.

Under development: (before <<: *base):

  mfe:
    enabled: true
    registry:
      url: "https://gitlab.com"
      group: "gitlab-org/frontend/playground"
      token:
    object_store:
      enabled: false
      remote_directory: mfe
      connection:
        provider: AWS
        aws_access_key_id: minio
        aws_secret_access_key: gdk-minio
        region: gdk

Under test: (the object_store.connection stanza is required by stub_mfe_object_storage when running the specs locally; CI gets it from gitlab.yml.example):

  mfe:
    enabled: false
    registry:
      url: "https://gitlab.com"
      group: "gitlab-org/frontend/playground"
      token:
    object_store:
      enabled: false
      remote_directory: mfe
      connection:
        provider: AWS
        aws_access_key_id: AWS_ACCESS_KEY_ID
        aws_secret_access_key: AWS_SECRET_ACCESS_KEY
        region: us-east-1

Then enable the flag and restart: Feature.enable(:mfe_enabled), gdk restart rails-web.

Production path: registry → pin → bake → serve

bin/rake gitlab:mfe:bake
# MFE bake: baked 1 app(s) into .../public/assets/mfe.

Enable delivery (mfe.enabled: true in gitlab.yml + Feature.enable(:mfe_enabled)), then:

# 200 with immutable public Cache-Control, nosniff, allow-listed Content-Type,
# and Content-Security-Policy: default-src 'none'
curl -sI http://gdk.test:3000/-/mfe/duo_chat/0.2.0/mf-manifest.json | grep -iE "^HTTP|cache-control|content-type|nosniff|security"
curl -sI http://gdk.test:3000/-/mfe/duo_chat/0.2.0/remoteEntry.js | grep -iE "^HTTP|content-type"
curl -s -o /dev/null -w "%{http_code}\n" http://gdk.test:3000/-/mfe/duo_chat/9.9.9/mf-manifest.json   # 404

Tamper check: flip one hex digit of the pinned manifest_sha256 and re-run the bake — it aborts with a digest mismatch and a non-zero exit, writing nothing.

Development path: dev proxy + HMR

Uses the patched gitlab-mfe branch (three dev-server fixes required for consumption through the monolith proxy: explicit HMR websocket target, relaxed Host/Origin check, lazy compilation off): https://gitlab.com/gitlab-org/frontend/gitlab-mfe/-/tree/xanf/dev-server-monolith-proxy

git clone https://gitlab.com/gitlab-org/frontend/gitlab-mfe && cd gitlab-mfe
git checkout xanf/dev-server-monolith-proxy
pnpm install
pnpm dev:rspack   # serves the remote on http://localhost:4001

Point GDK at it in <gdk>/env.runit, then gdk restart rails-web:

export GITLAB_MFE_DEV_APPS=duo_chat
export GITLAB_MFE_DEV_SERVERS=duo_chat=http://localhost:4001

Verify — no consumer code needed:

curl -s http://gdk.test:3000/-/mfe/duo_chat/dev/mf-manifest.json | head -c 120   # the dev server's live manifest
// on any GDK page, in the browser console:
s = document.createElement('script'); s.src = '/-/mfe/duo_chat/dev/remoteEntry.js'; document.head.append(s);
window.mfe_duo_chat   // => the federation container, served and executed through the proxy

HMR: touch mfes/duo-chat/src/components/duo_chat/duo_chat_view.vue — the console logs [HMR] Updated modules: ... App is up to date. without a page reload (the HMR websocket to ws://localhost:4001/ws is allowed by the development CSP from part 5). Misconfiguration fails loudly: removing the server variables makes any page raise Gitlab::Mfe::MissingDevServerError with instructions.

Stack (reviewed and merged separately)

# 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)
Edited by Illya Klymov

Merge request reports

Loading