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.

vue3-browse-root

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
vue3-file-image vue3-file-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.js lazy-loads by file type. The seeded archive holds only .txt, .yml, .jpg, .gif and .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 under vue3_migrate_repository (default_enabled: true since 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, .html artifacts redirect to the external_file warning page rather than rendering the viewer. external_file has no page bundle and is unaffected by this MR. .yml was used for the text case instead.

Pre-existing issues found, not fixed here

  • The list page has no empty state. GlTable is rendered without show-empty, so a project with no artifacts shows headers over an empty body.
  • .geojson artifacts have no viewer partial and no case in loadRichBlobViewer.
  • BuildArtifacts.disablePropagation targets .top-block, which does not exist on the browse page.

References

Edited by Miguel Rincon

Merge request reports

Loading
Loading