Add Vue 3 rollout flag for the artifacts pages
Description
Adds the vue3_migrate_artifacts feature flag and a vue3_migration.yml for
the three artifacts page entrypoints.
Note: I've added coverage for this feature at, so this feature is verified to be working there: !251287 (merged)
Scope
| Entrypoint | Vue apps mounted | Reaches Vue? |
|---|---|---|
projects/artifacts |
Artifacts table, via initVueApp + VueApollo |
yes |
projects/artifacts/browse |
none. BuildArtifacts is a plain class |
no (build_artifacts.js is not infected) |
projects/artifacts/file |
none directly. BlobViewer lazy-loads the viewers |
yes (blob/viewer/index.js is infected) |
Why a new flag
grouppipeline execution (verify) can own this flag independently.
Also, vue3_migrate_repository already covers the lazy blob viewers, but it is
default_enabled: true as of 19.1.
Verification
Artifacts list page
| Check | Result |
|---|---|
| Header size and count | Total artifacts size 0 B Total artifacts count 33 |
| Table | 20 rows per page, keyset pagination to a 4-row second page via ?next= |
File-type badges, +N more popover |
opens on hover, lists metadata |
| Row expansion | multiple rows expand, and stay expanded after a delete |
| Virtual scroller | vue-recycle-scroller ready direction-vertical, container max-height: 228px = 4 × (56 + 1), matching ARTIFACTS_SHOWN_WITHOUT_SCROLLING and ARTIFACT_ROW_HEIGHT |
| Scroller recycling | a removed row is parked at translateY(-9999px), the pool behaves as on Vue 2 |
| Download / Browse gating | both disabled on a junit-only job, which has no metadata |
| Single delete | modal Delete ci_build_artifacts_metadata.gz? → count 33 → 32, row removed from cache with no refetch, job stayed expanded, and that job's Browse button correctly became disabled |
| Bulk selection | select-all checks 20 rows, banner 33 artifacts selected, Clear selection empties it |
| Bulk delete modal | Delete 33 artifacts? with a matching primary button (cancelled, not executed) |
The virtual scroller is the important one: it is the vendor/vue-virtual-scroller
code path that !250882 (merged) fixed.
Browse page
Server-rendered, so the review is that this MR did not break it.
| Check | Result |
|---|---|
| Root listing | 2 directories, 4 files, sizes, per-file Download links |
| Directory navigation | descend and ascend via .. |
| Row-background click | clicking the size cell navigates — BuildArtifacts.setupEntryClick still works |
| Breadcrumbs | correct at every depth |
| Empty directory | shows only .. and Empty |
| UTF-8 directory names | utf8 test dir ✓ renders |
| Bogus path / path traversal | both 404 |
| Keyboard shortcuts | ? opens exactly one Keyboard shortcuts modal |
The shortcuts check matters because both pages/projects/index.js and the browse
entry call addShortcutsExtension, and after this MR those two entries run under
different Vue builds. behaviors/shortcuts/index.js is not infected — the
Vue-importing part sits behind a dynamic import — so both share one Shortcuts
instance. Confirmed in the browser, not just inferred.
File page
| Check | Result |
|---|---|
| Image artifact | rails_sample.jpg decodes and renders at 316×376 in .file-content.image_file |
| Nested path | other_artifacts_0.1.2/another-subdirectory/banana_sample.gif resolves |
| Text artifact | shows the expected "stored as a job artifact" fallback with a working download link |
| File header | icon, name, copy-path button, size |
| Download button | present in .file-actions |
| Console errors | 0 |
| Image viewer | Text fallback |
|---|---|
![]() |
![]() |
Recording — list page
Sign-in, the artifacts list, expanding a build:linux row, and paging to the
second page.
Not covered, and why
- The Vue rich viewers on the file page. CSV, PDF and notebook viewers are
Vue apps that
blob/viewer/index.jslazy-loads by file type. The seeded archive holds only.txt,.yml,.jpg,.gifand.png, and the codebase ships only an artifact-metadata reader (lib/gitlab/ci/build/artifacts/metadata.rb), so a custom archive cannot easily be produced locally. These viewers are shared with the repository blob page, which already runs Vue 3 undervue3_migrate_repository(default_enabled: truesince 19.1). canDestroyArtifacts: false. The local user is an admin, so the permission-gated branch was not exercised. It is covered by Jest.- On this GDK the Pages artifacts server is on, so
.txt,.log,.json,.xml,.htmlartifacts redirect to theexternal_filewarning page rather than rendering the viewer.external_filehas no page bundle and is unaffected by this MR..ymlwas used for the text case instead.
Pre-existing issues found, not fixed here
- The list page has no empty state.
GlTableis rendered withoutshow-empty, so a project with no artifacts shows headers over an empty body. .geojsonartifacts have no viewer partial and no case inloadRichBlobViewer.BuildArtifacts.disablePropagationtargets.top-block, which does not exist on the browse page.
References
- Migration issue: #616230
- Rollout issue: #616231
- Epic: &23285
- Feature spec follow-up: #619189
- Blocking defect: #619357 (closed)


