Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
2b085a8ae1
commit
79158c32d1
12 changed files with 35 additions and 364 deletions
|
@ -1,32 +0,0 @@
|
|||
import EditorLite from '~/editor/editor_lite';
|
||||
|
||||
export default class CILintEditor {
|
||||
constructor() {
|
||||
this.clearYml = document.querySelector('.clear-yml');
|
||||
this.clearYml.addEventListener('click', this.clear.bind(this));
|
||||
|
||||
return this.initEditorLite();
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.editor.setValue('');
|
||||
}
|
||||
|
||||
initEditorLite() {
|
||||
const editorEl = document.getElementById('editor');
|
||||
const fileContentEl = document.getElementById('content');
|
||||
const form = document.querySelector('.js-ci-lint-form');
|
||||
|
||||
const rootEditor = new EditorLite();
|
||||
|
||||
this.editor = rootEditor.createInstance({
|
||||
el: editorEl,
|
||||
blobPath: '.gitlab-ci.yml',
|
||||
blobContent: editorEl.innerText,
|
||||
});
|
||||
|
||||
form.addEventListener('submit', () => {
|
||||
fileContentEl.value = this.editor.getValue();
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
import createFlash from '~/flash';
|
||||
import { __ } from '~/locale';
|
||||
|
||||
const ERROR = __('An error occurred while rendering the linter');
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
if (gon?.features?.ciLintVue) {
|
||||
import(/* webpackChunkName: 'ciLintIndex' */ '~/ci_lint/index')
|
||||
.then(module => module.default())
|
||||
.catch(() => createFlash({ message: ERROR }));
|
||||
} else {
|
||||
import(/* webpackChunkName: 'ciLintEditor' */ '../ci_lint_editor')
|
||||
// eslint-disable-next-line new-cap
|
||||
.then(module => new module.default())
|
||||
.catch(() => createFlash({ message: ERROR }));
|
||||
}
|
||||
});
|
|
@ -1,17 +1,3 @@
|
|||
import createFlash from '~/flash';
|
||||
import { __ } from '~/locale';
|
||||
import initCiLint from '~/ci_lint';
|
||||
|
||||
const ERROR = __('An error occurred while rendering the linter');
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
if (gon?.features?.ciLintVue) {
|
||||
import(/* webpackChunkName: 'ciLintIndex' */ '~/ci_lint/index')
|
||||
.then(module => module.default())
|
||||
.catch(() => createFlash({ message: ERROR }));
|
||||
} else {
|
||||
import(/* webpackChunkName: 'ciLintEditor' */ '../ci_lint_editor')
|
||||
// eslint-disable-next-line new-cap
|
||||
.then(module => new module.default())
|
||||
.catch(() => createFlash({ message: ERROR }));
|
||||
}
|
||||
});
|
||||
initCiLint();
|
||||
|
|
|
@ -2,28 +2,22 @@
|
|||
|
||||
class Projects::Ci::LintsController < Projects::ApplicationController
|
||||
before_action :authorize_create_pipeline!
|
||||
before_action do
|
||||
push_frontend_feature_flag(:ci_lint_vue, project, default_enabled: true)
|
||||
end
|
||||
|
||||
feature_category :pipeline_authoring
|
||||
|
||||
respond_to :json, only: [:create]
|
||||
|
||||
def show
|
||||
end
|
||||
|
||||
def create
|
||||
@content = params[:content]
|
||||
@dry_run = params[:dry_run]
|
||||
content = params[:content]
|
||||
dry_run = params[:dry_run]
|
||||
|
||||
@result = Gitlab::Ci::Lint
|
||||
result = Gitlab::Ci::Lint
|
||||
.new(project: @project, current_user: current_user)
|
||||
.validate(@content, dry_run: @dry_run)
|
||||
.validate(content, dry_run: dry_run)
|
||||
|
||||
respond_to do |format|
|
||||
format.html { render :show }
|
||||
format.json do
|
||||
render json: ::Ci::Lint::ResultSerializer.new.represent(@result)
|
||||
end
|
||||
end
|
||||
render json: ::Ci::Lint::ResultSerializer.new.represent(result)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
- if @result.valid?
|
||||
.bs-callout.bs-callout-success
|
||||
%p
|
||||
%b= _("Status:")
|
||||
= _("syntax is correct")
|
||||
|
||||
= render "projects/ci/lints/lint_warnings", warnings: @result.warnings
|
||||
|
||||
.table-holder
|
||||
%table.table.table-bordered
|
||||
%thead
|
||||
%tr
|
||||
%th= _("Parameter")
|
||||
%th= _("Value")
|
||||
%tbody
|
||||
- @result.jobs.each do |job|
|
||||
%tr
|
||||
%td #{job[:stage].capitalize} Job - #{job[:name]}
|
||||
%td
|
||||
%pre= job[:before_script].to_a.join('<br />')
|
||||
%pre= job[:script].to_a.join('<br />')
|
||||
%pre= job[:after_script].to_a.join('<br />')
|
||||
%br
|
||||
%b= _("Tag list:")
|
||||
= job[:tag_list].to_a.join(", ")
|
||||
- unless @dry_run
|
||||
%br
|
||||
%b= _("Only policy:")
|
||||
= job[:only].to_a.join(", ")
|
||||
%br
|
||||
%b= _("Except policy:")
|
||||
= job[:except].to_a.join(", ")
|
||||
%br
|
||||
%b= _("Environment:")
|
||||
= job[:environment]
|
||||
%br
|
||||
%b= _("When:")
|
||||
= job[:when]
|
||||
- if job[:allow_failure]
|
||||
%b= _("Allowed to fail")
|
||||
|
||||
- else
|
||||
.bs-callout.bs-callout-danger
|
||||
%p
|
||||
%b= _("Status:")
|
||||
= _("syntax is incorrect")
|
||||
%pre
|
||||
- @result.errors.each do |message|
|
||||
%p= message
|
||||
|
||||
= render "projects/ci/lints/lint_warnings", warnings: @result.warnings
|
|
@ -1,10 +0,0 @@
|
|||
- if warnings
|
||||
- total_warnings = warnings.length
|
||||
- message = warning_header(total_warnings)
|
||||
|
||||
- if warnings.any?
|
||||
.bs-callout.bs-callout-warning
|
||||
%details
|
||||
%summary.gl-mb-2= message
|
||||
- warnings.each do |warning|
|
||||
= markdown(warning)
|
|
@ -3,32 +3,4 @@
|
|||
|
||||
%h2.pt-3.pb-3= _("Validate your GitLab CI configuration")
|
||||
|
||||
- if Feature.enabled?(:ci_lint_vue, @project, default_enabled: true)
|
||||
#js-ci-lint{ data: { endpoint: project_ci_lint_path(@project), help_page_path: help_page_path('ci/lint', anchor: 'pipeline-simulation') } }
|
||||
|
||||
- else
|
||||
.project-ci-linter
|
||||
= form_tag project_ci_lint_path(@project), method: :post, class: 'js-ci-lint-form' do
|
||||
.row
|
||||
.col-sm-12
|
||||
.file-holder
|
||||
.js-file-title.file-title.clearfix
|
||||
= _("Contents of .gitlab-ci.yml")
|
||||
.file-editor.code
|
||||
.js-edit-mode-pane.qa-editor#editor{ data: { 'editor-loading': true } }<
|
||||
%pre.editor-loading-content= params[:content]
|
||||
= text_area_tag(:content, @content, class: 'hidden form-control span1', rows: 7, require: true)
|
||||
.col-sm-12
|
||||
.float-left.gl-mt-3
|
||||
= submit_tag(_('Validate'), class: 'gl-button btn btn-success submit-yml')
|
||||
- if Gitlab::Ci::Features.lint_creates_pipeline_with_dry_run?(@project)
|
||||
= check_box_tag(:dry_run, 'true', params[:dry_run])
|
||||
= label_tag(:dry_run, _('Simulate a pipeline created for the default branch'))
|
||||
= link_to sprite_icon('question-o'), help_page_path('ci/lint', anchor: 'pipeline-simulation'), target: '_blank', rel: 'noopener noreferrer'
|
||||
.float-right.prepend-top-10
|
||||
= button_tag(_('Clear'), type: 'button', class: 'gl-button btn btn-default clear-yml')
|
||||
|
||||
.row.prepend-top-20
|
||||
.col-sm-12
|
||||
.results.project-ci-template
|
||||
= render partial: 'create' if defined?(@result)
|
||||
#js-ci-lint{ data: { endpoint: project_ci_lint_path(@project), help_page_path: help_page_path('ci/lint', anchor: 'pipeline-simulation') } }
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
---
|
||||
name: ci_lint_vue
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/42401
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/249661
|
||||
group: group::continuous integration
|
||||
type: development
|
||||
default_enabled: true
|
|
@ -3154,9 +3154,6 @@ msgstr ""
|
|||
msgid "An error occurred while rendering the editor"
|
||||
msgstr ""
|
||||
|
||||
msgid "An error occurred while rendering the linter"
|
||||
msgstr ""
|
||||
|
||||
msgid "An error occurred while reordering issues."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -47,9 +47,9 @@ RSpec.describe Projects::Ci::LintsController do
|
|||
describe 'POST #create' do
|
||||
subject { post :create, params: params }
|
||||
|
||||
let(:format) { :html }
|
||||
let(:params) { { namespace_id: project.namespace, project_id: project, content: content, format: format } }
|
||||
let(:params) { { namespace_id: project.namespace, project_id: project, content: content, format: :json } }
|
||||
let(:remote_file_path) { 'https://gitlab.com/gitlab-org/gitlab-foss/blob/1234/.gitlab-ci-1.yml' }
|
||||
let(:parsed_body) { Gitlab::Json.parse(response.body) }
|
||||
|
||||
let(:remote_file_content) do
|
||||
<<~HEREDOC
|
||||
|
@ -72,17 +72,23 @@ RSpec.describe Projects::Ci::LintsController do
|
|||
HEREDOC
|
||||
end
|
||||
|
||||
shared_examples 'successful request with format json' do
|
||||
context 'with format json' do
|
||||
let(:format) { :json }
|
||||
let(:parsed_body) { Gitlab::Json.parse(response.body) }
|
||||
shared_examples 'returns a successful validation' do
|
||||
before do
|
||||
subject
|
||||
end
|
||||
|
||||
it 'renders json' do
|
||||
expect(response).to have_gitlab_http_status :ok
|
||||
expect(response.content_type).to eq 'application/json'
|
||||
expect(parsed_body).to include('errors', 'warnings', 'jobs', 'valid')
|
||||
expect(parsed_body).to match_schema('entities/lint_result_entity')
|
||||
end
|
||||
it 'returns successfully' do
|
||||
expect(response).to have_gitlab_http_status :ok
|
||||
end
|
||||
|
||||
it 'renders json' do
|
||||
expect(response.content_type).to eq 'application/json'
|
||||
expect(parsed_body).to include('errors', 'warnings', 'jobs', 'valid')
|
||||
expect(parsed_body).to match_schema('entities/lint_result_entity')
|
||||
end
|
||||
|
||||
it 'retrieves project' do
|
||||
expect(assigns(:project)).to eq(project)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -92,25 +98,7 @@ RSpec.describe Projects::Ci::LintsController do
|
|||
project.add_developer(user)
|
||||
end
|
||||
|
||||
shared_examples 'returns a successful validation' do
|
||||
before do
|
||||
subject
|
||||
end
|
||||
|
||||
it 'returns successfully' do
|
||||
expect(response).to have_gitlab_http_status :ok
|
||||
end
|
||||
|
||||
it 'renders show page' do
|
||||
expect(response).to render_template :show
|
||||
end
|
||||
|
||||
it 'retrieves project' do
|
||||
expect(assigns(:project)).to eq(project)
|
||||
end
|
||||
|
||||
it_behaves_like 'successful request with format json'
|
||||
end
|
||||
it_behaves_like 'returns a successful validation'
|
||||
|
||||
context 'using legacy validation (YamlProcessor)' do
|
||||
it_behaves_like 'returns a successful validation'
|
||||
|
@ -166,27 +154,23 @@ RSpec.describe Projects::Ci::LintsController do
|
|||
subject
|
||||
end
|
||||
|
||||
it_behaves_like 'returns a successful validation'
|
||||
|
||||
it 'assigns result with errors' do
|
||||
expect(assigns[:result].errors).to match_array([
|
||||
expect(parsed_body['errors']).to match_array([
|
||||
'jobs rubocop config should implement a script: or a trigger: keyword',
|
||||
'jobs config should contain at least one visible job'
|
||||
])
|
||||
end
|
||||
|
||||
it 'render show page' do
|
||||
expect(response).to render_template :show
|
||||
end
|
||||
|
||||
it_behaves_like 'successful request with format json'
|
||||
|
||||
context 'with dry_run mode' do
|
||||
subject { post :create, params: params.merge(dry_run: 'true') }
|
||||
|
||||
it 'assigns result with errors' do
|
||||
expect(assigns[:result].errors).to eq(['jobs rubocop config should implement a script: or a trigger: keyword'])
|
||||
expect(parsed_body['errors']).to eq(['jobs rubocop config should implement a script: or a trigger: keyword'])
|
||||
end
|
||||
|
||||
it_behaves_like 'successful request with format json'
|
||||
it_behaves_like 'returns a successful validation'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -200,14 +184,6 @@ RSpec.describe Projects::Ci::LintsController do
|
|||
it 'responds with 404' do
|
||||
expect(response).to have_gitlab_http_status(:not_found)
|
||||
end
|
||||
|
||||
context 'with format json' do
|
||||
let(:format) { :json }
|
||||
|
||||
it 'responds with 404' do
|
||||
expect(response).to have_gitlab_http_status :not_found
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -11,7 +11,6 @@ RSpec.describe 'CI Lint', :js do
|
|||
let(:content_selector) { '.content .view-lines' }
|
||||
|
||||
before do
|
||||
stub_feature_flags(ci_lint_vue: false)
|
||||
project.add_developer(user)
|
||||
sign_in(user)
|
||||
|
||||
|
@ -26,7 +25,6 @@ RSpec.describe 'CI Lint', :js do
|
|||
describe 'YAML parsing' do
|
||||
shared_examples 'validates the YAML' do
|
||||
before do
|
||||
stub_feature_flags(ci_lint_vue: false)
|
||||
click_on 'Validate'
|
||||
end
|
||||
|
||||
|
@ -68,14 +66,6 @@ RSpec.describe 'CI Lint', :js do
|
|||
|
||||
it_behaves_like 'validates the YAML'
|
||||
end
|
||||
|
||||
describe 'YAML revalidate' do
|
||||
let(:yaml_content) { 'my yaml content' }
|
||||
|
||||
it 'loads previous YAML content after validation' do
|
||||
expect(page).to have_field('content', with: 'my yaml content', visible: false, type: 'textarea')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'YAML clearing' do
|
||||
|
@ -89,7 +79,7 @@ RSpec.describe 'CI Lint', :js do
|
|||
end
|
||||
|
||||
it 'YAML content is cleared' do
|
||||
expect(page).to have_field('content', with: '', visible: false, type: 'textarea')
|
||||
expect(page).to have_field(class: 'inputarea', with: '', visible: false, type: 'textarea')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,127 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe 'projects/ci/lints/show' do
|
||||
include Devise::Test::ControllerHelpers
|
||||
let_it_be(:user) { create(:user) }
|
||||
let_it_be(:project) { create(:project, :repository) }
|
||||
let(:lint) { Gitlab::Ci::Lint.new(project: project, current_user: user) }
|
||||
let(:result) { lint.validate(YAML.dump(content)) }
|
||||
|
||||
describe 'XSS protection' do
|
||||
before do
|
||||
assign(:project, project)
|
||||
assign(:result, result)
|
||||
stub_feature_flags(ci_lint_vue: false)
|
||||
end
|
||||
|
||||
context 'when builds attrbiutes contain HTML nodes' do
|
||||
let(:content) do
|
||||
{
|
||||
rspec: {
|
||||
script: '<h1>rspec</h1>',
|
||||
stage: 'test'
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
it 'does not render HTML elements' do
|
||||
render
|
||||
|
||||
expect(rendered).not_to have_css('h1', text: 'rspec')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when builds attributes do not contain HTML nodes' do
|
||||
let(:content) do
|
||||
{
|
||||
rspec: {
|
||||
script: 'rspec',
|
||||
stage: 'test'
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
it 'shows configuration in the table' do
|
||||
render
|
||||
|
||||
expect(rendered).to have_css('td pre', text: 'rspec')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the content is valid' do
|
||||
let(:content) do
|
||||
{
|
||||
build_template: {
|
||||
script: './build.sh',
|
||||
tags: ['dotnet'],
|
||||
only: ['test@dude/repo'],
|
||||
except: ['deploy'],
|
||||
environment: 'testing'
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
before do
|
||||
assign(:project, project)
|
||||
assign(:result, result)
|
||||
stub_feature_flags(ci_lint_vue: false)
|
||||
end
|
||||
|
||||
it 'shows the correct values' do
|
||||
render
|
||||
|
||||
expect(rendered).to have_content('Status: syntax is correct')
|
||||
expect(rendered).to have_content('Tag list: dotnet')
|
||||
expect(rendered).to have_content('Only policy: refs, test@dude/repo')
|
||||
expect(rendered).to have_content('Except policy: refs, deploy')
|
||||
expect(rendered).to have_content('Environment: testing')
|
||||
expect(rendered).to have_content('When: on_success')
|
||||
end
|
||||
|
||||
context 'when content has warnings' do
|
||||
before do
|
||||
allow(result).to receive(:warnings).and_return(['Warning 1', 'Warning 2'])
|
||||
end
|
||||
|
||||
it 'shows warning messages' do
|
||||
render
|
||||
|
||||
expect(rendered).to have_content('2 warning(s) found:')
|
||||
expect(rendered).to have_content('Warning 1')
|
||||
expect(rendered).to have_content('Warning 2')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the content is invalid' do
|
||||
let(:content) { double(:content) }
|
||||
|
||||
before do
|
||||
allow(result).to receive(:warnings).and_return(['Warning 1', 'Warning 2'])
|
||||
allow(result).to receive(:errors).and_return(['Undefined error'])
|
||||
|
||||
assign(:project, project)
|
||||
assign(:result, result)
|
||||
stub_feature_flags(ci_lint_vue: false)
|
||||
end
|
||||
|
||||
it 'shows error message' do
|
||||
render
|
||||
|
||||
expect(rendered).to have_content('Status: syntax is incorrect')
|
||||
expect(rendered).to have_content('Undefined error')
|
||||
expect(rendered).not_to have_content('Tag list:')
|
||||
end
|
||||
|
||||
it 'shows warning messages' do
|
||||
render
|
||||
|
||||
expect(rendered).to have_content('2 warning(s) found:')
|
||||
expect(rendered).to have_content('Warning 1')
|
||||
expect(rendered).to have_content('Warning 2')
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue