Commit 8fc6a201 authored by Miguel Rincon's avatar Miguel Rincon

Introduce feature flag to render pipeline with Vue

This change adds introduces a feature flag to render the pipeline mini
graph in the commit that has historically been implemented with HAML
and jQuery.
parent 6131d5c5
import { fetchCommitMergeRequests } from '~/commit_merge_requests';
import MiniPipelineGraph from '~/mini_pipeline_graph_dropdown';
import { initCommitPipelineMiniGraph } from './init_commit_pipeline_mini_graph';
import { initDetailsButton } from './init_details_button';
import { loadBranches } from './load_branches';
......@@ -12,10 +13,15 @@ export const initCommitBoxInfo = (containerSelector = '.js-commit-box-info') =>
// Related merge requests to this commit
fetchCommitMergeRequests();
// Display pipeline info for this commit
new MiniPipelineGraph({
container: '.js-commit-pipeline-graph',
}).bindEvents();
// Display pipeline mini graph for this commit
// Feature flag ci_commit_pipeline_mini_graph_vue
if (gon.features.ciCommitPipelineMiniGraphVue) {
initCommitPipelineMiniGraph();
} else {
new MiniPipelineGraph({
container: '.js-commit-pipeline-graph',
}).bindEvents();
}
initDetailsButton();
};
import Vue from 'vue';
export const initCommitPipelineMiniGraph = async (selector = '.js-commit-pipeline-mini-graph') => {
const el = document.querySelector(selector);
if (!el) {
return;
}
// Some commits have no pipeline, code splitting to load the pipeline optionally
const { stages } = el.dataset;
const { default: PipelineMiniGraph } = await import(
/* webpackChunkName: 'pipelineMiniGraph' */ '~/pipelines/components/pipelines_list/pipeline_mini_graph.vue'
);
// eslint-disable-next-line no-new
new Vue({
el,
render(createElement) {
return createElement(PipelineMiniGraph, {
props: {
stages: JSON.parse(stages),
},
});
},
});
};
......@@ -16,9 +16,14 @@ class Projects::CommitController < Projects::ApplicationController
before_action :authorize_read_pipeline!, only: [:pipelines]
before_action :commit
before_action :define_commit_vars, only: [:show, :diff_for_path, :diff_files, :pipelines, :merge_requests]
before_action :define_commit_box_vars, only: [:show, :pipelines]
before_action :define_note_vars, only: [:show, :diff_for_path, :diff_files]
before_action :authorize_edit_tree!, only: [:revert, :cherry_pick]
before_action only: [:show, :pipelines] do
push_frontend_feature_flag(:ci_commit_pipeline_mini_graph_vue, @project, default_enabled: :yaml)
end
BRANCH_SEARCH_LIMIT = 1000
COMMIT_DIFFS_PER_PAGE = 75
......@@ -202,6 +207,15 @@ class Projects::CommitController < Projects::ApplicationController
end
# rubocop: enable CodeReuse/ActiveRecord
def define_commit_box_vars
@last_pipeline = @commit.last_pipeline
return unless ::Gitlab::Ci::Features.ci_commit_pipeline_mini_graph_vue_enabled?(@project)
return unless @commit.last_pipeline
@last_pipeline_stages = StageSerializer.new(project: @project, current_user: @current_user).represent(@last_pipeline.stages)
end
def assign_change_commit_vars
@start_branch = params[:start_branch]
@commit_params = { commit: @commit }
......
......@@ -74,22 +74,25 @@
%span.commit-info.merge-requests{ 'data-project-commit-path' => merge_requests_project_commit_path(@project, @commit.id, format: :json) }
.spinner.vertical-align-middle
- last_pipeline = @commit.last_pipeline
- if can?(current_user, :read_pipeline, last_pipeline)
- if can?(current_user, :read_pipeline, @last_pipeline)
.well-segment.pipeline-info
.status-icon-container
= link_to project_pipeline_path(@project, last_pipeline.id), class: "ci-status-icon-#{last_pipeline.status}" do
= ci_icon_for_status(last_pipeline.status)
= link_to project_pipeline_path(@project, @last_pipeline.id), class: "ci-status-icon-#{@last_pipeline.status}" do
= ci_icon_for_status(@last_pipeline.status)
#{ _('Pipeline') }
= link_to "##{last_pipeline.id}", project_pipeline_path(@project, last_pipeline.id)
= ci_label_for_status(last_pipeline.status)
- if last_pipeline.stages_count.nonzero?
#{ n_(s_('Pipeline|with stage'), s_('Pipeline|with stages'), last_pipeline.stages_count) }
= link_to "##{@last_pipeline.id}", project_pipeline_path(@project, @last_pipeline.id)
= ci_label_for_status(@last_pipeline.status)
- if @last_pipeline.stages_count.nonzero?
#{ n_(s_('Pipeline|with stage'), s_('Pipeline|with stages'), @last_pipeline.stages_count) }
.mr-widget-pipeline-graph
= render 'shared/mini_pipeline_graph', pipeline: last_pipeline, klass: 'js-commit-pipeline-graph'
- if last_pipeline.duration
- if ::Gitlab::Ci::Features.ci_commit_pipeline_mini_graph_vue_enabled?(@project)
.stage-cell
.js-commit-pipeline-mini-graph{ data: { stages: @last_pipeline_stages.to_json.html_safe } }
- else
= render 'shared/mini_pipeline_graph', pipeline: @last_pipeline, klass: 'js-commit-pipeline-graph'
- if @last_pipeline.duration
in
= time_interval_in_words last_pipeline.duration
= time_interval_in_words @last_pipeline.duration
- if @merge_request
.well-segment
......
---
name: ci_commit_pipeline_mini_graph_vue
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55363
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/323356
milestone: '13.10'
type: development
group: group::pipeline authoring
default_enabled: false
......@@ -67,6 +67,10 @@ module Gitlab
def self.multiple_cache_per_job?
::Feature.enabled?(:multiple_cache_per_job, default_enabled: :yaml)
end
def self.ci_commit_pipeline_mini_graph_vue_enabled?(project)
::Feature.enabled?(:ci_commit_pipeline_mini_graph_vue, project, default_enabled: :yaml)
end
end
end
end
......@@ -9,6 +9,8 @@ RSpec.describe Projects::CommitController do
let(:commit) { project.commit("master") }
let(:master_pickable_sha) { '7d3b0f7cff5f37573aea97cebfd5692ea1689924' }
let(:master_pickable_commit) { project.commit(master_pickable_sha) }
let(:pipeline) { create(:ci_pipeline, project: project, ref: project.default_branch, sha: commit.sha, status: :running) }
let(:build) { create(:ci_build, pipeline: pipeline, status: :running) }
before do
sign_in(user)
......@@ -33,6 +35,19 @@ RSpec.describe Projects::CommitController do
expect(response).to be_ok
end
context 'when a pipeline job is running' do
before do
build.run
end
it 'defines last pipeline information' do
go(id: commit.id)
expect(assigns(:last_pipeline)).to have_attributes(id: pipeline.id, status: 'running')
expect(assigns(:last_pipeline_stages)).not_to be_empty
end
end
end
context 'with invalid id' do
......@@ -363,15 +378,22 @@ RSpec.describe Projects::CommitController do
context 'when the commit exists' do
context 'when the commit has pipelines' do
before do
create(:ci_pipeline, project: project, sha: commit.id)
build.run
end
context 'when rendering a HTML format' do
it 'shows pipelines' do
before do
get_pipelines(id: commit.id)
end
it 'shows pipelines' do
expect(response).to be_ok
end
it 'defines last pipeline information' do
expect(assigns(:last_pipeline)).to have_attributes(id: pipeline.id, status: 'running')
expect(assigns(:last_pipeline_stages)).not_to be_empty
end
end
context 'when rendering a JSON format' do
......
......@@ -7,37 +7,55 @@ RSpec.describe 'Mini Pipeline Graph in Commit View', :js do
context 'when commit has pipelines' do
let(:pipeline) do
create(:ci_empty_pipeline,
create(:ci_pipeline,
status: :running,
project: project,
ref: project.default_branch,
sha: project.commit.sha)
end
let(:build) { create(:ci_build, pipeline: pipeline) }
let(:build) { create(:ci_build, pipeline: pipeline, status: :running) }
it 'display icon with status' do
build.run
visit project_commit_path(project, project.commit.id)
shared_examples 'shows ci icon and mini pipeline' do
before do
build.run
visit project_commit_path(project, project.commit.id)
end
expect(page).to have_selector('.ci-status-icon-running')
end
it 'display icon with status' do
expect(page).to have_selector('.ci-status-icon-running')
end
it 'displays a mini pipeline graph' do
build.run
visit project_commit_path(project, project.commit.id)
it 'displays a mini pipeline graph' do
expect(page).to have_selector('.mr-widget-pipeline-graph')
expect(page).to have_selector('.mr-widget-pipeline-graph')
first('.mini-pipeline-graph-dropdown-toggle').click
first('.mini-pipeline-graph-dropdown-toggle').click
wait_for_requests
wait_for_requests
page.within '.js-builds-dropdown-list' do
expect(page).to have_selector('.ci-status-icon-running')
expect(page).to have_content(build.stage)
end
page.within '.js-builds-dropdown-list' do
expect(page).to have_selector('.ci-status-icon-running')
expect(page).to have_content(build.stage)
build.drop
end
end
context 'when ci_commit_pipeline_mini_graph_vue is disabled' do
before do
stub_feature_flags(ci_commit_pipeline_mini_graph_vue: false)
end
it_behaves_like 'shows ci icon and mini pipeline'
end
context 'when ci_commit_pipeline_mini_graph_vue is enabled' do
before do
stub_feature_flags(ci_commit_pipeline_mini_graph_vue: true)
end
build.drop
it_behaves_like 'shows ci icon and mini pipeline'
end
end
......
......@@ -21,12 +21,37 @@ RSpec.describe 'projects/commit/_commit_box.html.haml' do
end
context 'when there is a pipeline present' do
context 'when pipeline has stages' do
before do
pipeline = create(:ci_pipeline, project: project, sha: project.commit.id, status: 'success')
create(:ci_build, pipeline: pipeline, stage: 'build')
assign(:last_pipeline, project.commit.last_pipeline)
end
it 'shows pipeline stages in vue' do
render
expect(rendered).to have_selector('.js-commit-pipeline-mini-graph')
end
it 'shows pipeline stages in haml when feature flag is disabled' do
stub_feature_flags(ci_commit_pipeline_mini_graph_vue: false)
render
expect(rendered).to have_selector('.js-commit-pipeline-graph')
end
end
context 'when there are multiple pipelines for a commit' do
it 'shows the last pipeline' do
create(:ci_pipeline, project: project, sha: project.commit.id, status: 'success')
create(:ci_pipeline, project: project, sha: project.commit.id, status: 'canceled')
third_pipeline = create(:ci_pipeline, project: project, sha: project.commit.id, status: 'failed')
assign(:last_pipeline, third_pipeline)
render
expect(rendered).to have_text("Pipeline ##{third_pipeline.id} failed")
......@@ -40,6 +65,8 @@ RSpec.describe 'projects/commit/_commit_box.html.haml' do
end
it 'shows correct pipeline description' do
assign(:last_pipeline, pipeline)
render
expect(rendered).to have_text "Pipeline ##{pipeline.id} " \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment