Switch Convert to GitLab CI button to use developer/v1 flow

What does this MR do and why?

Switches the "Convert to GitLab CI/CD" button on Jenkinsfile blob views from the legacy convert_to_gl_ci/v1 foundational flow to the actively-maintained developer/v1 flow, with an explicit conversion-goal prompt that instructs the agent to read the Jenkinsfile + any files it depends on, generate a self-contained .gitlab-ci.yml, validate the output via glab ci lint, and open a merge request with the converted files.

The change is gated behind a new feature flag duo_convert_ci_use_developer_flow (default disabled, project actor, gitlab_com_derisk rollout) so we can bake on .com before flipping defaults.

This is the first of two MRs for #597606. A follow-up MR will expand the button to additional CI config files (GitHub Actions, CircleCI, Bamboo specs, TeamCity, Azure Pipelines, Travis CI) and replace the hard-coded 'Jenkins' source-platform name with a per-fileType lookup map.

Related: !230512 (merged) (the same developer/v1 button pattern used for "Resolve with Duo" on MR conflicts).

Closes part of #597606.

How to set up and validate locally

  1. Have a project with project_setting.duo_remote_flows_enabled = true and namespace_settings.duo_features_enabled = true.
  2. Add a Jenkinsfile to its default branch.
  3. View the file in the repo browser — the "Convert to GitLab CI/CD" button appears in the blob header.
  4. FF off (default): click → request to POST /api/v4/ai/duo_workflows/workflows contains workflow_definition: 'convert_to_gl_ci/v1' and goal: '<blob.path>' (legacy contract unchanged).
  5. FF on: Feature.enable(:duo_convert_ci_use_developer_flow, Project.find(...)) then click → request contains workflow_definition: 'developer/v1' and goal: carries the full 4-step conversion prompt with glab ci lint validation and the MR title "Convert Jenkins CI to GitLab CI".

Screenshots or screen recordings

Visual diff for the button itself: none. The change is in the click payload, not the rendered UI. Verified locally with Playwright against GDK — the captured POST body (FF on) was:

{
  "project_id": 1000000,
  "start_workflow": true,
  "workflow_definition": "developer/v1",
  "agent_privileges": [1, 2, 3, 5],
  "source_branch": "main",
  "goal": "Convert the Jenkins CI pipeline configuration at `Jenkinsfile` to a GitLab CI/CD pipeline.\n\n1. Read the source file. Identify any files it depends on (shared libraries, reusable workflows, orbs, ...)\n2. Generate an equivalent .gitlab-ci.yml at the repository root ...\n3. Validate the generated YAML by running `glab ci lint .gitlab-ci.yml` ...\n4. Open a merge request titled \"Convert Jenkins CI to GitLab CI\" ..."
}

Database

No migrations. No new tables, columns, or queries.

Performance, reliability, observability

  • One additional push_frontend_feature_flag call in the blob controller — negligible cost.
  • No new GraphQL/REST traffic; same endpoint, different payload string.
  • Telemetry: this MR does not add new tracking. The existing Tableau slice for "Convert to Gitlab CI/CD" (which today filters duo_workflow_workload_completed.workflow_definition for convert_to_gl_ci/v1) may go blind once the FF is enabled in production and workflow_definition flips to developer/v1. We deliberately deferred adding a dedicated click event until we can verify the slice's current population path. A follow-up MR will add per-platform tracking after that verification.

How was the user impact validated?

  • New jest spec asserts both branches: FF off → legacy convert_to_gl_ci/v1 + bare blob.path goal; FF on → developer/v1 + multi-step conversion prompt with glab ci lint validation and the MR title fragment. 8/8 jest tests pass.
  • Manual Playwright verification end-to-end against GDK (signed in, navigated to a Jenkinsfile blob, captured the network request after clicking the button) — all 12 assertions on the request payload passed.
  • Behind a default-off feature flag so the production blast radius is bounded until the rollout issue advances it.

Compliance

Merge request reports

Loading