Migrate Verify: CI/CD Apps to Vue 3
Part of https://gitlab.com/groups/gitlab-org/-/epics/6252.
This epic tracks the Vue 3 migration of the page entrypoints owned by the Verify stage.
## Resources:
- Migration guide: https://docs.gitlab.com/development/fe_guide/vue3_migration/#option-1-recommended-migrate-your-page-entrypoint-using-a-feature-flag-and-vue3_migrationyml
- Example MR: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/250219
- Sibling epic (Create: Source Code): https://gitlab.com/groups/gitlab-org/-/epics/23084
## Method
Verify owns 64 page entrypoints. 30 are in rollout and 1 is partly migrated by hand. This epic groups the remaining 34 into feature flags. Each group shares Vue components.
The groups came from the dependency-cruiser import graph. Run `node scripts/frontend/vue3_migration_stats.mjs --owners` to build it.
The comparison uses only "distinctive" components. A distinctive component is reachable from fewer than 25 of the 581 page entrypoints in the repository. This filter removes generic infrastructure from the comparison.
Without the filter, generic components dominate. For example, `explore/catalog`, `projects/artifacts/file` and `projects/artifacts/browse` share 51 `glql/components` and 18 `content_editor/components`. That overlap makes the three pages look 65-95% identical. They share almost no other code.
## Status
All work is open as of 2026-08-17.
Verify had 34 entrypoints left to migrate. They are accounted for as follows.
| Outcome | Entrypoints |
|---|---|
| Seven new flags | 22 |
| Attached to a flag that already exists | 5 |
| Deleted as unreachable | 3 |
| Dropped from this epic's scope | 1 |
| Still to do, under `vue3_migrate_ci_cd_settings` | 3 |
| **Total** | **34** |
| Flag | Entrypoints | Migration issue | Rollout issue | MR |
|---|---|---|---|---|
| `vue3_migrate_ci_catalog` | 1 | gitlab-org/gitlab#616161 | gitlab-org/gitlab#616162 | gitlab-org/gitlab!250411 |
| `vue3_migrate_clusters` | 13 | gitlab-org/gitlab#616227 | gitlab-org/gitlab#616228 | gitlab-org/gitlab!250421 |
| `vue3_migrate_artifacts` | 3 | gitlab-org/gitlab#616230 | gitlab-org/gitlab#616231 | gitlab-org/gitlab!250423 |
| `vue3_migrate_terraform` | 1 | gitlab-org/gitlab#616237 | gitlab-org/gitlab#616242 | gitlab-org/gitlab!250429 |
| `vue3_migrate_pipeline_usage_quotas` | 1 | gitlab-org/gitlab#616238 | gitlab-org/gitlab#616243 | gitlab-org/gitlab!250431 |
| `vue3_migrate_admin_ci_settings` | 1 (CE+EE) | gitlab-org/gitlab#616239 | gitlab-org/gitlab#616244 | gitlab-org/gitlab!250432 |
| `vue3_migrate_cluster_agents` | 2 | gitlab-org/gitlab#616240 | gitlab-org/gitlab#616245 | gitlab-org/gitlab!250433 |
| Attach to existing flags | 5 | gitlab-org/gitlab#616234 | n/a | gitlab-org/gitlab!250425, gitlab-org/gitlab!250426, gitlab-org/gitlab!250427, gitlab-org/gitlab!250428 |
| Cleanup: remove dead bundles | 3 removed | n/a | n/a | gitlab-org/gitlab!250422 |
| `vue3_migrate_ci_cd_settings` | 3 | **still to do** | | |
`pages/admin/index.js` was dropped from this epic. The stats tool attributes it
to Verify only because `Admin::ClustersController` falls back to that bundle. It
is the admin dashboard, so it belongs to whoever owns that page.
## List of entry points/efforts/impacts/status:
### **Already done / in rollout:**
| Feature flag | Entrypoints | Status |
|---|---|---|
| `vue3_migrate_admin_runners` | 14 | rollout |
| `vue3_migrate_pipelines` | 11 | rollout |
| `vue3_migrate_jobs` | 3 | rollout |
| `vue3_migrate_runners_dashboard` | 2 | rollout |
| `vue3_migrate_pipelines` | 1 (`projects/settings/ci_cd/show`) | manual, partly done |
### **Remaining:**
| Flag | Entrypoints | Distinctive `.vue` | Notes |
|---|---|---|---|
| `vue3_migrate_ci_catalog` | `explore/catalog` | 31 (28 in `ci/catalog`) | **In review**: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/250411. Issues: https://gitlab.com/gitlab-org/gitlab/-/issues/616161 and https://gitlab.com/gitlab-org/gitlab/-/issues/616162. |
| `vue3_migrate_clusters` | 13: `admin`, `groups` and `projects`, each with `clusters/index`, `clusters/show`, `clusters/edit`, `clusters/connect`; plus `groups/clusters` | ~22, in `clusters/` and `clusters_list/` | **In review**: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/250421. Issues: https://gitlab.com/gitlab-org/gitlab/-/issues/616227 and https://gitlab.com/gitlab-org/gitlab/-/issues/616228. Scope dropped from 16 to 13 after a reachability check — see the note below. |
| `vue3_migrate_artifacts` | `projects/artifacts`, `projects/artifacts/file`, `projects/artifacts/browse` | 11, in `ci/artifacts` | `file` and `browse` add no new components. Their trees are the notebook, PDF and blob viewers, already proven under `vue3_migrate_repository`. |
| `vue3_migrate_ci_cd_settings` | `projects/settings/ci_cd/show` (CE+EE), `groups/settings/ci_cd/show` (CE+EE), `projects/settings` | 67 | Use Option 2 here, not Option 1. `projects/settings/ci_cd/show` mounts about 14 independent Vue apps. Two already use `?vue3` imports, gated by `vue3_migrate_pipelines` and `vue3_migrate_admin_runners`. Option 1 would flip all 14 at once. Do this last. |
| `vue3_migrate_cluster_agents` | `projects/cluster_agents/show`, `clusters/agents/dashboard` | 38 | `cluster_agents/show` is 74% proven: 48 of its 77 distinctive components are `security_dashboard`, covered by the pipeline security tabs. `clusters/agents/dashboard` is `kubernetes_dashboard` and adds 18 new components. |
| `vue3_migrate_terraform` | `projects/terraform/index` | 5, in `terraform/` | — |
| `vue3_migrate_pipeline_usage_quotas` | `ee/admin/application_settings/usage_quotas` | 7, in `usage_quotas/pipelines` | Fulfillment owns these components. Ask them to review. |
| `vue3_migrate_admin_ci_settings` | `admin/application_settings/ci_cd` (CE+EE) | 4 | One entry name in both page roots, so it needs two byte-identical ymls. The EE file imports the CE file and adds the CI template dropdown. |
### **Reachability note on the cluster pages**
Most Kubernetes cluster pages sit behind the `certificate_based_clusters` ops
flag, which is `default_enabled: false`. `Admin::ClustersController` adds a
second `before_action :ensure_feature_enabled!` with no `except:`
(`app/controllers/admin/clusters_controller.rb:6`), so every admin cluster page
returns 404 while the flag is off. The integration was announced as deprecated
in 14.5 and still shows an in-product banner.
`~/clusters_list` is not deprecated. It renders the GitLab agent UI whether or
not the certificate flag is on, and the environments page imports from it. That
is why the `clusters/index` pages are worth migrating.
The three `*/clusters/destroy` bundles can never execute. The `destroy` action
only calls `redirect_to` (`app/controllers/clusters/clusters_controller.rb:70-77`),
so the page never renders HTML and the bundle never loads. They are removed in
https://gitlab.com/gitlab-org/gitlab/-/merge_requests/250422 rather than migrated.
Caveat for reviewers: the cluster feature specs never stub
`certificate_based_clusters`, and it is absent from the ops-flags-disabled list
at `spec/spec_helper.rb:289-296`. The suite only exercises the flag-on path,
which is the opposite of the production default.
### **Attach to an existing flag (no new flag):**
| Entrypoint | Attach to | Why |
|---|---|---|
| `projects/ci/lints/show` | `vue3_migrate_pipelines` | 83% of its distinctive tree already ships under that flag, through `ci/pipeline_editor`. It adds 1 component, `ci/ci_lint`. |
| `projects/jobs/viewer` | `vue3_migrate_jobs` | 3 components, all in `ci/job_log_viewer`. |
| `projects/jobs/terminal` | `vue3_migrate_jobs` | The page has no Vue components. |
| `projects/pipelines/charts` | `vue3_migrate_ci_cd_analytics` | It is the project-scope version of the group page already on that flag. It adds 18 distinctive components in `ci/analytics`. |
| `ee/projects/merge_trains` | `vue3_migrate_pipelines` | Same page family and same group as the pipeline pages. Grouped by ownership, not by shared components: all 6 of its components in `ci/merge_trains` are new ground on that flag, so it inherits the flag's current percentage with no soak of its own. It previously had its own flag, `vue3_migrate_merge_trains`, dropped before it ever merged. |
## Order
1. `vue3_migrate_ci_catalog`
1. `vue3_migrate_clusters`
1. `vue3_migrate_artifacts`
1. `vue3_migrate_terraform`
1. `vue3_migrate_pipeline_usage_quotas`
1. `vue3_migrate_admin_ci_settings`
1. `vue3_migrate_cluster_agents`
1. `vue3_migrate_ci_cd_settings`
epic