diff options
author | Simon Knox <psimyn@gmail.com> | 2017-12-02 09:08:05 +1100 |
---|---|---|
committer | Simon Knox <psimyn@gmail.com> | 2017-12-02 09:08:05 +1100 |
commit | 560d52ce926c2bc7592ce0666ab9b287be1d2324 (patch) | |
tree | 29395b1e706c4e07d9a796c15b3164d8f60e0f1c | |
parent | afa6359f1e047fb0b258eaf221a67ea749e2f980 (diff) | |
parent | e0f84130567dc34edf1ae75fcf595e24991d2fa9 (diff) | |
download | gitlab-ce-psimyn-issue-note-refac.tar.gz |
Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ce into psimyn-issue-note-refacpsimyn-issue-note-refac
22 files changed, 254 insertions, 114 deletions
diff --git a/app/assets/javascripts/groups/components/group_item.vue b/app/assets/javascripts/groups/components/group_item.vue index 356a95c05ca..0cd0c59a275 100644 --- a/app/assets/javascripts/groups/components/group_item.vue +++ b/app/assets/javascripts/groups/components/group_item.vue @@ -1,4 +1,5 @@ <script> +import tooltip from '../../vue_shared/directives/tooltip'; import identicon from '../../vue_shared/components/identicon.vue'; import eventHub from '../event_hub'; @@ -8,6 +9,9 @@ import itemStats from './item_stats.vue'; import itemActions from './item_actions.vue'; export default { + directives: { + tooltip, + }, components: { identicon, itemCaret, @@ -112,10 +116,16 @@ export default { </a> </div> <div - class="title"> + class="title namespace-title"> <a + v-tooltip :href="group.relativePath" - class="no-expand">{{group.fullName}}</a> + :title="group.fullName" + class="no-expand" + data-placement="top" + > + {{group.name}} + </a> <span v-if="group.permission" class="access-type" diff --git a/app/assets/stylesheets/framework/lists.scss b/app/assets/stylesheets/framework/lists.scss index ad3bb0e35d1..cd505bcaf6d 100644 --- a/app/assets/stylesheets/framework/lists.scss +++ b/app/assets/stylesheets/framework/lists.scss @@ -449,6 +449,12 @@ ul.indent-list { } } +.namespace-title { + .tooltip-inner { + max-width: 350px; + } +} + ul.group-list-tree { li.group-row { &.has-description { diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index fd64670f6b0..eebbf7c4218 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -40,7 +40,6 @@ module Ci validates :status, presence: { unless: :importing? } validate :valid_commit_sha, unless: :importing? - after_initialize :set_config_source, if: :new_record? after_create :keep_around_commits, unless: :importing? enum source: { diff --git a/app/models/project.rb b/app/models/project.rb index c6f7f56f311..eaf4f555d3b 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -234,8 +234,8 @@ class Project < ActiveRecord::Base validates :creator, presence: true, on: :create validates :description, length: { maximum: 2000 }, allow_blank: true validates :ci_config_path, - format: { without: /\.{2}/, - message: 'cannot include directory traversal.' }, + format: { without: /(\.{2}|\A\/)/, + message: 'cannot include leading slash or directory traversal.' }, length: { maximum: 255 }, allow_blank: true validates :name, @@ -599,7 +599,7 @@ class Project < ActiveRecord::Base def ci_config_path=(value) # Strip all leading slashes so that //foo -> foo - super(value&.sub(%r{\A/+}, '')&.delete("\0")) + super(value&.delete("\0")) end def import_url=(value) diff --git a/app/services/ci/create_pipeline_service.rb b/app/services/ci/create_pipeline_service.rb index 31a712ccc1b..7b9ea223d26 100644 --- a/app/services/ci/create_pipeline_service.rb +++ b/app/services/ci/create_pipeline_service.rb @@ -2,27 +2,24 @@ module Ci class CreatePipelineService < BaseService attr_reader :pipeline - SEQUENCE = [Gitlab::Ci::Pipeline::Chain::Validate::Abilities, + SEQUENCE = [Gitlab::Ci::Pipeline::Chain::Build, + Gitlab::Ci::Pipeline::Chain::Validate::Abilities, Gitlab::Ci::Pipeline::Chain::Validate::Repository, Gitlab::Ci::Pipeline::Chain::Validate::Config, Gitlab::Ci::Pipeline::Chain::Skip, Gitlab::Ci::Pipeline::Chain::Create].freeze def execute(source, ignore_skip_ci: false, save_on_errors: true, trigger_request: nil, schedule: nil, &block) - @pipeline = Ci::Pipeline.new( - source: source, - project: project, - ref: ref, - sha: sha, - before_sha: before_sha, - tag: tag_exists?, - trigger_requests: Array(trigger_request), - user: current_user, - pipeline_schedule: schedule, - protected: project.protected_for?(ref) - ) - - command = OpenStruct.new(ignore_skip_ci: ignore_skip_ci, + @pipeline = Ci::Pipeline.new + + command = OpenStruct.new(source: source, + origin_ref: params[:ref], + checkout_sha: params[:checkout_sha], + after_sha: params[:after], + before_sha: params[:before], + trigger_request: trigger_request, + schedule: schedule, + ignore_skip_ci: ignore_skip_ci, save_incompleted: save_on_errors, seeds_block: block, project: project, @@ -45,14 +42,6 @@ module Ci private - def commit - @commit ||= project.commit(origin_sha || origin_ref) - end - - def sha - commit.try(:id) - end - def update_merge_requests_head_pipeline return unless pipeline.latest? @@ -76,26 +65,6 @@ module Ci .created_or_pending end - def before_sha - params[:checkout_sha] || params[:before] || Gitlab::Git::BLANK_SHA - end - - def origin_sha - params[:checkout_sha] || params[:after] - end - - def origin_ref - params[:ref] - end - - def tag_exists? - project.repository.tag_exists?(ref) - end - - def ref - @ref ||= Gitlab::Git.ref_name(origin_ref) - end - def pipeline_created_counter @pipeline_created_counter ||= Gitlab::Metrics .counter(:pipelines_created_total, "Counter of pipelines created") diff --git a/changelogs/unreleased/40286-hide-full-namespace-groups-tree.yml b/changelogs/unreleased/40286-hide-full-namespace-groups-tree.yml new file mode 100644 index 00000000000..cae02d0c2f6 --- /dev/null +++ b/changelogs/unreleased/40286-hide-full-namespace-groups-tree.yml @@ -0,0 +1,6 @@ +--- +title: Show only group name by default and put full namespace in tooltip in Groups + tree +merge_request: 15650 +author: +type: changed diff --git a/changelogs/unreleased/add_project_ci_config_path_leading_slash_validation.yml b/changelogs/unreleased/add_project_ci_config_path_leading_slash_validation.yml new file mode 100644 index 00000000000..1c96bd66ed4 --- /dev/null +++ b/changelogs/unreleased/add_project_ci_config_path_leading_slash_validation.yml @@ -0,0 +1,6 @@ +--- +title: Prefer ci_config_path validation for leading slashes instead of sanitizing + the input +merge_request: 15672 +author: Christiaan Van den Poel +type: other diff --git a/changelogs/unreleased/sh-fix-root-ref-repository.yml b/changelogs/unreleased/sh-fix-root-ref-repository.yml new file mode 100644 index 00000000000..0670db84fa6 --- /dev/null +++ b/changelogs/unreleased/sh-fix-root-ref-repository.yml @@ -0,0 +1,5 @@ +--- +title: "Gracefully handle case when repository's root ref does not exist" +merge_request: +author: +type: fixed diff --git a/doc/user/project/integrations/img/issue_configuration.png b/doc/user/project/integrations/img/issue_configuration.png Binary files differnew file mode 100644 index 00000000000..2049d60fdd2 --- /dev/null +++ b/doc/user/project/integrations/img/issue_configuration.png diff --git a/doc/user/project/integrations/redmine.md b/doc/user/project/integrations/redmine.md index cf92465da53..f530b6cb649 100644 --- a/doc/user/project/integrations/redmine.md +++ b/doc/user/project/integrations/redmine.md @@ -1,26 +1,29 @@ # Redmine Service -To enable the Redmine integration in a project, navigate to the +1. To enable the Redmine integration in a project, navigate to the [Integrations page](project_services.md#accessing-the-project-services), click the **Redmine** service, and fill in the required details on the page as described in the table below. -| Field | Description | -| ----- | ----------- | -| `description` | A name for the issue tracker (to differentiate between instances, for example) | -| `project_url` | The URL to the project in Redmine which is being linked to this GitLab project | -| `issues_url` | The URL to the issue in Redmine project that is linked to this GitLab project. Note that the `issues_url` requires `:id` in the URL. This ID is used by GitLab as a placeholder to replace the issue number. | -| `new_issue_url` | This is the URL to create a new issue in Redmine for the project linked to this GitLab project | + | Field | Description | + | ----- | ----------- | + | `description` | A name for the issue tracker (to differentiate between instances, for example) | + | `project_url` | The URL to the project in Redmine which is being linked to this GitLab project | + | `issues_url` | The URL to the issue in Redmine project that is linked to this GitLab project. Note that the `issues_url` requires `:id` in the URL. This ID is used by GitLab as a placeholder to replace the issue number. | + | `new_issue_url` | This is the URL to create a new issue in Redmine for the project linked to this GitLab project | -Once you have configured and enabled Redmine: + Once you have configured and enabled Redmine: + - the **Issues** link on the GitLab project pages takes you to the appropriate + Redmine issue index + - clicking **New issue** on the project dashboard creates a new Redmine issue -- the **Issues** link on the GitLab project pages takes you to the appropriate - Redmine issue index -- clicking **New issue** on the project dashboard creates a new Redmine issue + As an example, below is a configuration for a project named gitlab-ci. -As an example, below is a configuration for a project named gitlab-ci. + ![Redmine configuration](img/redmine_configuration.png) -![Redmine configuration](img/redmine_configuration.png) +2. To disable the internal issue tracking system in a project, navigate to the General page, expand [Permissions](../settings/index.md#sharing-and-permissions), and slide the Issues switch invalid. + + ![Issue configuration](img/issue_configuration.png) ## Referencing issues in Redmine diff --git a/lib/gitlab/ci/pipeline/chain/build.rb b/lib/gitlab/ci/pipeline/chain/build.rb new file mode 100644 index 00000000000..a126dded1ae --- /dev/null +++ b/lib/gitlab/ci/pipeline/chain/build.rb @@ -0,0 +1,58 @@ +module Gitlab + module Ci + module Pipeline + module Chain + class Build < Chain::Base + include Chain::Helpers + + def perform! + @pipeline.assign_attributes( + source: @command.source, + project: @project, + ref: ref, + sha: sha, + before_sha: before_sha, + tag: tag_exists?, + trigger_requests: Array(@command.trigger_request), + user: @current_user, + pipeline_schedule: @command.schedule, + protected: protected_ref? + ) + + @pipeline.set_config_source + end + + def break? + false + end + + private + + def ref + @ref ||= Gitlab::Git.ref_name(origin_ref) + end + + def sha + @project.commit(origin_sha || origin_ref).try(:id) + end + + def origin_ref + @command.origin_ref + end + + def origin_sha + @command.checkout_sha || @command.after_sha + end + + def before_sha + @command.checkout_sha || @command.before_sha || Gitlab::Git::BLANK_SHA + end + + def protected_ref? + @project.protected_for?(ref) + end + end + end + end + end +end diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb index fb9c3e92d3f..dbc08747228 100644 --- a/lib/gitlab/git/repository.rb +++ b/lib/gitlab/git/repository.rb @@ -1253,7 +1253,11 @@ module Gitlab # Gitaly migration: https://gitlab.com/gitlab-org/gitaly/issues/695 def git_merged_branch_names(branch_names = []) - root_sha = find_branch(root_ref).target + return [] unless root_ref + + root_sha = find_branch(root_ref)&.target + + return [] unless root_sha git_arguments = %W[branch --merged #{root_sha} diff --git a/lib/gitlab/kubernetes/helm.rb b/lib/gitlab/kubernetes/helm.rb index 7a50f07f3c5..407cdefc04d 100644 --- a/lib/gitlab/kubernetes/helm.rb +++ b/lib/gitlab/kubernetes/helm.rb @@ -18,7 +18,7 @@ module Gitlab def initialize(kubeclient) @kubeclient = kubeclient - @namespace = Namespace.new(NAMESPACE, kubeclient) + @namespace = Gitlab::Kubernetes::Namespace.new(NAMESPACE, kubeclient) end def install(command) diff --git a/scripts/trigger-build-omnibus b/scripts/trigger-build-omnibus index 0c662ac19d2..3c5c22c9372 100755 --- a/scripts/trigger-build-omnibus +++ b/scripts/trigger-build-omnibus @@ -30,12 +30,16 @@ module Omnibus private + def ee? + File.exist?('CHANGELOG-EE.md') + end + def env_params { "ref" => ENV["OMNIBUS_BRANCH"] || "master", "variables[GITLAB_VERSION]" => ENV["CI_COMMIT_SHA"], "variables[ALTERNATIVE_SOURCES]" => true, - "variables[ee]" => ENV["EE_PACKAGE"] || "false" + "variables[ee]" => ee? ? 'true' : 'false' } end diff --git a/spec/lib/gitlab/ci/pipeline/chain/build_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/build_spec.rb new file mode 100644 index 00000000000..0f1d72080c5 --- /dev/null +++ b/spec/lib/gitlab/ci/pipeline/chain/build_spec.rb @@ -0,0 +1,51 @@ +require 'spec_helper' + +describe Gitlab::Ci::Pipeline::Chain::Build do + set(:project) { create(:project, :repository) } + set(:user) { create(:user) } + let(:pipeline) { Ci::Pipeline.new } + + let(:command) do + double('command', source: :push, + origin_ref: 'master', + checkout_sha: project.commit.id, + after_sha: nil, + before_sha: nil, + trigger_request: nil, + schedule: nil, + project: project, + current_user: user) + end + + let(:step) { described_class.new(pipeline, command) } + + before do + stub_repository_ci_yaml_file(sha: anything) + + step.perform! + end + + it 'never breaks the chain' do + expect(step.break?).to be false + end + + it 'fills pipeline object with data' do + expect(pipeline.sha).not_to be_empty + expect(pipeline.sha).to eq project.commit.id + expect(pipeline.ref).to eq 'master' + expect(pipeline.user).to eq user + expect(pipeline.project).to eq project + end + + it 'sets a valid config source' do + expect(pipeline.repository_source?).to be true + end + + it 'returns a valid pipeline' do + expect(pipeline).to be_valid + end + + it 'does not persist a pipeline' do + expect(pipeline).not_to be_persisted + end +end diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb index 2f49bd1bcf2..08dd6ea80ff 100644 --- a/spec/lib/gitlab/git/repository_spec.rb +++ b/spec/lib/gitlab/git/repository_spec.rb @@ -1210,6 +1210,16 @@ describe Gitlab::Git::Repository, seed_helper: true do end end + context 'when no root ref is available' do + it 'returns empty list' do + project = create(:project, :empty_repo) + + names = project.repository.merged_branch_names(%w[feature]) + + expect(names).to be_empty + end + end + context 'when no branch names are specified' do before do repository.create_branch('identical', 'master') diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index 4cf0088ac9c..d4b1e7c8dd4 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -868,62 +868,59 @@ describe Ci::Pipeline, :mailer do end describe '#set_config_source' do - context 'on object initialisation' do - context 'when pipelines does not contain needed data' do - let(:pipeline) do - Ci::Pipeline.new - end + context 'when pipelines does not contain needed data' do + it 'defines source to be unknown' do + pipeline.set_config_source - it 'defines source to be unknown' do - expect(pipeline).to be_unknown_source - end + expect(pipeline).to be_unknown_source end + end - context 'when pipeline contains all needed data' do - let(:pipeline) do - Ci::Pipeline.new( - project: project, - sha: '1234', - ref: 'master', - source: :push) + context 'when pipeline contains all needed data' do + let(:pipeline) do + create(:ci_pipeline, project: project, + sha: '1234', + ref: 'master', + source: :push) + end + + context 'when the repository has a config file' do + before do + allow(project.repository).to receive(:gitlab_ci_yml_for) + .and_return('config') end - context 'when the repository has a config file' do - before do - allow(project.repository).to receive(:gitlab_ci_yml_for) - .and_return('config') - end + it 'defines source to be from repository' do + pipeline.set_config_source - it 'defines source to be from repository' do - expect(pipeline).to be_repository_source - end + expect(pipeline).to be_repository_source + end - context 'when loading an object' do - let(:new_pipeline) { Ci::Pipeline.find(pipeline.id) } + context 'when loading an object' do + let(:new_pipeline) { Ci::Pipeline.find(pipeline.id) } - it 'does not redefine the source' do - # force to overwrite the source - pipeline.unknown_source! + it 'does not redefine the source' do + # force to overwrite the source + pipeline.unknown_source! - expect(new_pipeline).to be_unknown_source - end + expect(new_pipeline).to be_unknown_source end end + end - context 'when the repository does not have a config file' do - let(:implied_yml) { Gitlab::Template::GitlabCiYmlTemplate.find('Auto-DevOps').content } + context 'when the repository does not have a config file' do + let(:implied_yml) { Gitlab::Template::GitlabCiYmlTemplate.find('Auto-DevOps').content } - context 'auto devops enabled' do - before do - stub_application_setting(auto_devops_enabled: true) - allow(project).to receive(:ci_config_path) { 'custom' } - end + context 'auto devops enabled' do + before do + stub_application_setting(auto_devops_enabled: true) + allow(project).to receive(:ci_config_path) { 'custom' } + end - it 'defines source to be auto devops' do - subject + it 'defines source to be auto devops' do + pipeline.set_config_source - expect(pipeline).to be_auto_devops_source - end + expect(pipeline).to be_auto_devops_source end end end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index a4abcc49a0d..521b7bd70ba 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -138,6 +138,7 @@ describe Project do it { is_expected.to validate_length_of(:ci_config_path).is_at_most(255) } it { is_expected.to allow_value('').for(:ci_config_path) } it { is_expected.not_to allow_value('test/../foo').for(:ci_config_path) } + it { is_expected.not_to allow_value('/test/foo').for(:ci_config_path) } it { is_expected.to validate_presence_of(:creator) } @@ -1548,8 +1549,8 @@ describe Project do expect(project.ci_config_path).to eq('foo/.gitlab_ci.yml') end - it 'sets a string but removes all leading slashes and null characters' do - project.update!(ci_config_path: "///f\0oo/\0/.gitlab_ci.yml") + it 'sets a string but removes all null characters' do + project.update!(ci_config_path: "f\0oo/\0/.gitlab_ci.yml") expect(project.ci_config_path).to eq('foo//.gitlab_ci.yml') end diff --git a/spec/services/ci/create_pipeline_service_spec.rb b/spec/services/ci/create_pipeline_service_spec.rb index 08847183bf4..befd0faf1b6 100644 --- a/spec/services/ci/create_pipeline_service_spec.rb +++ b/spec/services/ci/create_pipeline_service_spec.rb @@ -8,7 +8,7 @@ describe Ci::CreatePipelineService do let(:ref_name) { 'refs/heads/master' } before do - stub_ci_pipeline_to_return_yaml_file + stub_repository_ci_yaml_file(sha: anything) end describe '#execute' do @@ -44,6 +44,7 @@ describe Ci::CreatePipelineService do expect(pipeline).to eq(project.pipelines.last) expect(pipeline).to have_attributes(user: user) expect(pipeline).to have_attributes(status: 'pending') + expect(pipeline.repository_source?).to be true expect(pipeline.builds.first).to be_kind_of(Ci::Build) end diff --git a/spec/services/clusters/applications/schedule_installation_service_spec.rb b/spec/services/clusters/applications/schedule_installation_service_spec.rb index cf95361c935..047a6e44dab 100644 --- a/spec/services/clusters/applications/schedule_installation_service_spec.rb +++ b/spec/services/clusters/applications/schedule_installation_service_spec.rb @@ -22,6 +22,8 @@ describe Clusters::Applications::ScheduleInstallationService do let(:service) { described_class.new(project, nil, cluster: cluster, application_class: application_class) } it 'creates a new application' do + allow(ClusterInstallAppWorker).to receive(:perform_async) + expect { service.execute }.to change { application_class.count }.by(1) end diff --git a/spec/support/stub_gitlab_calls.rb b/spec/support/stub_gitlab_calls.rb index 5f22d886910..c1618f5086c 100644 --- a/spec/support/stub_gitlab_calls.rb +++ b/spec/support/stub_gitlab_calls.rb @@ -21,6 +21,12 @@ module StubGitlabCalls allow_any_instance_of(Ci::Pipeline).to receive(:ci_yaml_file) { ci_yaml } end + def stub_repository_ci_yaml_file(sha:, path: '.gitlab-ci.yml') + allow_any_instance_of(Repository) + .to receive(:gitlab_ci_yml_for).with(sha, path) + .and_return(gitlab_ci_yaml) + end + def stub_ci_builds_disabled allow_any_instance_of(Project).to receive(:builds_enabled?).and_return(false) end diff --git a/spec/workers/post_receive_spec.rb b/spec/workers/post_receive_spec.rb index 05eecf5f0bb..5d9b0679796 100644 --- a/spec/workers/post_receive_spec.rb +++ b/spec/workers/post_receive_spec.rb @@ -66,19 +66,21 @@ describe PostReceive do end context "gitlab-ci.yml" do + let(:changes) { "123456 789012 refs/heads/feature\n654321 210987 refs/tags/tag" } + subject { described_class.new.perform(gl_repository, key_id, base64_changes) } context "creates a Ci::Pipeline for every change" do before do stub_ci_pipeline_to_return_yaml_file - # TODO, don't stub private methods - # - allow_any_instance_of(Ci::CreatePipelineService) - .to receive(:commit).and_return(OpenStruct.new(id: '123456')) + allow_any_instance_of(Project) + .to receive(:commit) + .and_return(project.commit) allow_any_instance_of(Repository) - .to receive(:branch_exists?).and_return(true) + .to receive(:branch_exists?) + .and_return(true) end it { expect { subject }.to change { Ci::Pipeline.count }.by(2) } |