Add a feature spec and a global Vue 3 flag for the Jira Connect app

What does this MR do and why?

This MR adds a :js feature spec for the GitLab for Jira Cloud app (the jira_connect_app bundle). It also lets the app run under Vue 3 behind a new global feature flag, vue3_migrate_jira_connect_app.

The feature spec

The bundle had no browser-level test. The existing spec/features/jira_connect/subscriptions_spec.rb is not a :js spec. It checks Content-Security-Policy headers and never boots Vue.

The new spec covers the two states a Jira admin sees before signing in:

  • No linked groups: the heading, the intro text and the sign-in button.
  • One linked group: the sign-in button and the linked groups table with its Unlink button.

RSpec turns on unsaved feature flags, so the spec runs the Vue 3 build.

Why a global flag, and why ?vue3

An earlier version of this MR put the bundle under vue3_migrate_jira with a vue3_migration.yml. That mechanism checks the flag with the current user as the actor. JiraConnect::ApplicationController skips authenticate_user!, and the app runs inside an Atlassian iframe, so current_user is nil for most loads. A percentage rollout would never reach those loads (question on the MR).

The app answers to a Jira site, not to a GitLab user, so the flag now has no actor. It is off or on for the whole instance. The app now uses Option 2 of the Vue 3 migration guide:

  • JiraConnect::SubscriptionsController#index pushes vue3_migrate_jira_connect_app to the frontend, with no actor.
  • entrypoints/jira_connect_app.js imports ~/jira_connect/subscriptions?vue3 when the flag is on. If that import fails, it reports the error to Sentry and starts the Vue 2 build.
  • jira_connect/subscriptions/index.js no longer starts the app when it is imported. The entrypoint, its only importer, calls initJiraConnect().

The flag is new, and vue3_migrate_jira is not reused. That flag uses the user actor on the other Jira pages. One flag with two actor types would make its percentage steps mean different things on different pages.

Options ruled out:

  • Current.organization as the actor: almost every installation on GitLab.com is in the default organization, so it would also work as a single switch.
  • The Jira installation as the actor: this needs FeatureGate on JiraConnectInstallation. It also ties an instance-level migration to individual Jira sites.

The AP stub

The app reads the AP global that Atlassian's all.js defines inside a Jira iframe. In the test browser that global does not exist, and jira_connect/subscriptions/utils.js throws ReferenceError: AP is not defined before the app mounts.

The spec adds a minimal window.AP with Page.addScriptToEvaluateOnNewDocument. It removes the script in an after block, because the script survives Capybara's session reset and would leak into later :js specs in the same browser (review note).

Screenshots or screen recordings

Flag on, live in GDK:

Vue 3 build, linked groups table
jira-vue3-on

How to set up and validate locally

bin/rspec spec/features/jira_connect/user_views_subscriptions_spec.rb

Both examples pass locally against GDK.

To check the leak fix, run a probe spec that visits /help and prints typeof window.AP after this spec, with --order defined. It prints undefined. Before the fix it printed object.

Live check in GDK with Playwright. The test used a JiraConnectInstallation with one linked group, a JWT built from the route helpers, and a stubbed window.AP:

Flag gon.features.vue3MigrateJiraConnectApp [data-gitlab-vue3-app] Console Linked groups table
off false 0 no Vue 3 log renders
on true 1 [V] Using Vue.js 3 for JiraConnectAppRoot renders

The publicKeyStorageEnabled prop warning appears in both states. The HAML leaves out the data attribute when the setting is false. That warning is not caused by this MR.

To check by hand, run Feature.enable(:vue3_migrate_jira_connect_app), open the app from a Jira site, and run document.querySelectorAll('[data-gitlab-vue3-app]') in the console.

References

Edited by Miguel Rincon

Merge request reports

Loading
Loading