From fb6586151acc290bed8d4337f019d86aed84a33d Mon Sep 17 00:00:00 2001 From: fliespl Date: Mon, 9 May 2016 08:11:07 +0000 Subject: Broken instructions. git fetch --all --tags doesn't refresh tags --- doc/update/8.6-to-8.7.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/update/8.6-to-8.7.md b/doc/update/8.6-to-8.7.md index 4a2c6ea91d2..8aceb292243 100644 --- a/doc/update/8.6-to-8.7.md +++ b/doc/update/8.6-to-8.7.md @@ -45,7 +45,7 @@ sudo -u git -H git checkout 8-7-stable-ee ```bash cd /home/git/gitlab-shell -sudo -u git -H git fetch --all --tags +sudo -u git -H git fetch --tags sudo -u git -H git checkout v2.7.2 ``` -- cgit v1.2.1 From 17c6bec79d876ce932edc0edc5d17622adb2f724 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Fri, 3 Jun 2016 13:57:40 +0200 Subject: WIP --- CHANGELOG | 1 + lib/gitlab/backend/grack_auth.rb | 2 +- lib/gitlab/lfs/response.rb | 7 ++++--- lib/gitlab/lfs/router.rb | 5 +++-- spec/lib/gitlab/lfs/lfs_router_spec.rb | 36 +++++++++++++++++++++++----------- 5 files changed, 34 insertions(+), 17 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index d1cde40c1c7..b6c1959bc4c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -22,6 +22,7 @@ v 8.9.0 (unreleased) - Remove 'main language' feature - Pipelines can be canceled only when there are running builds - Use downcased path to container repository as this is expected path by Docker + - Allow to use CI token to fetch LFS objects - Projects pending deletion will render a 404 page - Measure queue duration between gitlab-workhorse and Rails - Make authentication service for Container Registry to be compatible with < Docker 1.11 diff --git a/lib/gitlab/backend/grack_auth.rb b/lib/gitlab/backend/grack_auth.rb index cdcaae8094c..baa81d92dd9 100644 --- a/lib/gitlab/backend/grack_auth.rb +++ b/lib/gitlab/backend/grack_auth.rb @@ -33,7 +33,7 @@ module Grack auth! - lfs_response = Gitlab::Lfs::Router.new(project, @user, @request).try_call + lfs_response = Gitlab::Lfs::Router.new(project, @user, @ci, @request).try_call return lfs_response unless lfs_response.nil? if project && authorized_request? diff --git a/lib/gitlab/lfs/response.rb b/lib/gitlab/lfs/response.rb index 9d9617761b3..e3ed2f6791d 100644 --- a/lib/gitlab/lfs/response.rb +++ b/lib/gitlab/lfs/response.rb @@ -2,10 +2,11 @@ module Gitlab module Lfs class Response - def initialize(project, user, request) + def initialize(project, user, ci, request) @origin_project = project @project = storage_project(project) @user = user + @ci = ci @env = request.env @request = request end @@ -189,7 +190,7 @@ module Gitlab return render_not_enabled unless Gitlab.config.lfs.enabled unless @project.public? - return render_unauthorized unless @user + return render_unauthorized unless @user || @ci return render_forbidden unless user_can_fetch? end @@ -210,7 +211,7 @@ module Gitlab def user_can_fetch? # Check user access against the project they used to initiate the pull - @user.can?(:download_code, @origin_project) + @ci || @user.can?(:download_code, @origin_project) end def user_can_push? diff --git a/lib/gitlab/lfs/router.rb b/lib/gitlab/lfs/router.rb index 78d02891102..f0c58890547 100644 --- a/lib/gitlab/lfs/router.rb +++ b/lib/gitlab/lfs/router.rb @@ -1,9 +1,10 @@ module Gitlab module Lfs class Router - def initialize(project, user, request) + def initialize(project, user, ci, request) @project = project @user = user + @ci = ci @env = request.env @request = request end @@ -80,7 +81,7 @@ module Gitlab def lfs return unless @project - Gitlab::Lfs::Response.new(@project, @user, @request) + Gitlab::Lfs::Response.new(@project, @user, @ci, @request) end def sanitize_tmp_filename(name) diff --git a/spec/lib/gitlab/lfs/lfs_router_spec.rb b/spec/lib/gitlab/lfs/lfs_router_spec.rb index 88814bc474d..8c5a27bf368 100644 --- a/spec/lib/gitlab/lfs/lfs_router_spec.rb +++ b/spec/lib/gitlab/lfs/lfs_router_spec.rb @@ -17,12 +17,15 @@ describe Gitlab::Lfs::Router, lib: true do } end - let(:lfs_router_auth) { new_lfs_router(project, user) } - let(:lfs_router_noauth) { new_lfs_router(project, nil) } - let(:lfs_router_public_auth) { new_lfs_router(public_project, user) } - let(:lfs_router_public_noauth) { new_lfs_router(public_project, nil) } - let(:lfs_router_forked_noauth) { new_lfs_router(forked_project, nil) } - let(:lfs_router_forked_auth) { new_lfs_router(forked_project, user_two) } + let(:lfs_router_auth) { new_lfs_router(project, user: user) } + let(:lfs_router_ci_auth) { new_lfs_router(project, ci: true) } + let(:lfs_router_noauth) { new_lfs_router(project) } + let(:lfs_router_public_auth) { new_lfs_router(public_project, user: user) } + let(:lfs_router_public_ci_auth) { new_lfs_router(public_project, ci: true) } + let(:lfs_router_public_noauth) { new_lfs_router(public_project) } + let(:lfs_router_forked_noauth) { new_lfs_router(forked_project) } + let(:lfs_router_forked_auth) { new_lfs_router(forked_project, user: user_two) } + let(:lfs_router_forked_ci_auth) { new_lfs_router(forked_project, ci: true) } let(:sample_oid) { "b68143e6463773b1b6c6fd009a76c32aeec041faff32ba2ed42fd7f708a17f80" } let(:sample_size) { 499013 } @@ -104,6 +107,17 @@ describe Gitlab::Lfs::Router, lib: true do expect(lfs_router_auth.try_call[1]['X-Sendfile']).to eq(lfs_object.file.path) end end + + context 'when CI is authorized' do + it "responds with status 200" do + expect(lfs_router_ci_auth.try_call.first).to eq(200) + end + + it "responds with the file location" do + expect(lfs_router_ci_auth.try_call[1]['Content-Type']).to eq("application/octet-stream") + expect(lfs_router_ci_auth.try_call[1]['X-Sendfile']).to eq(lfs_object.file.path) + end + end end context 'without required headers' do @@ -525,7 +539,7 @@ describe Gitlab::Lfs::Router, lib: true do end describe 'when user is unauthenticated' do - let(:lfs_router_noauth) { new_lfs_router(project, nil) } + let(:lfs_router_noauth) { new_lfs_router(project) } context 'and request is sent by gitlab-workhorse to authorize the request' do before do @@ -584,7 +598,7 @@ describe Gitlab::Lfs::Router, lib: true do end describe 'when user is unauthenticated' do - let(:lfs_router_noauth) { new_lfs_router(project, nil) } + let(:lfs_router_noauth) { new_lfs_router(project) } context 'and request is sent by gitlab-workhorse to authorize the request' do before do @@ -716,7 +730,7 @@ describe Gitlab::Lfs::Router, lib: true do describe 'and second project not related to fork or a source project' do let(:second_project) { create(:project) } - let(:lfs_router_second_project) { new_lfs_router(second_project, user) } + let(:lfs_router_second_project) { new_lfs_router(second_project, user: user) } before do public_project.lfs_objects << lfs_object @@ -745,8 +759,8 @@ describe Gitlab::Lfs::Router, lib: true do ActionController::HttpAuthentication::Basic.encode_credentials(user.username, user.password) end - def new_lfs_router(project, user) - Gitlab::Lfs::Router.new(project, user, request) + def new_lfs_router(project, user: nil, ci: false) + Gitlab::Lfs::Router.new(project, user, ci, request) end def header_for_upload_authorize(project) -- cgit v1.2.1 From 9b6c7e365fbf297d72a0c2770d5b8837da2f4879 Mon Sep 17 00:00:00 2001 From: Bartholomew Date: Mon, 6 Jun 2016 00:35:23 +0000 Subject: fix double query string in url --- app/views/dashboard/_projects_head.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/dashboard/_projects_head.html.haml b/app/views/dashboard/_projects_head.html.haml index 9da3fcbd986..5a6c6113d19 100644 --- a/app/views/dashboard/_projects_head.html.haml +++ b/app/views/dashboard/_projects_head.html.haml @@ -13,7 +13,7 @@ Explore Projects .nav-controls - = form_tag request.original_url, method: :get, class: 'project-filter-form', id: 'project-filter-form' do |f| + = form_tag request.original_url.split('?').first, method: :get, class: 'project-filter-form', id: 'project-filter-form' do |f| = search_field_tag :filter_projects, params[:filter_projects], placeholder: 'Filter by name...', class: 'project-filter-form-field form-control input-short projects-list-filter', spellcheck: false, id: 'project-filter-form-field', tabindex: "2" = render 'shared/projects/dropdown' - if current_user.can_create_project? -- cgit v1.2.1 From 860760120843ea5ad003cc2f52b28cf0fc7c647b Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Mon, 9 May 2016 11:18:47 +0200 Subject: Add config field to runner to lock it on project --- db/migrate/20160509091049_add_locked_to_ci_runner.rb | 8 ++++++++ db/schema.rb | 1 + 2 files changed, 9 insertions(+) create mode 100644 db/migrate/20160509091049_add_locked_to_ci_runner.rb diff --git a/db/migrate/20160509091049_add_locked_to_ci_runner.rb b/db/migrate/20160509091049_add_locked_to_ci_runner.rb new file mode 100644 index 00000000000..6294fa9d86b --- /dev/null +++ b/db/migrate/20160509091049_add_locked_to_ci_runner.rb @@ -0,0 +1,8 @@ +class AddLockedToCiRunner < ActiveRecord::Migration + ## + # Downtime expected due to exclusive lock when setting default value. + # + def change + add_column :ci_runners, :locked, :boolean, default: false, null: false + end +end diff --git a/db/schema.rb b/db/schema.rb index b7adf48fdb4..6e60c39fc22 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -285,6 +285,7 @@ ActiveRecord::Schema.define(version: 20160608155312) do t.string "platform" t.string "architecture" t.boolean "run_untagged", default: true, null: false + t.boolean "locked", default: false, null: false end add_index "ci_runners", ["description"], name: "index_ci_runners_on_description_trigram", using: :gin, opclasses: {"description"=>"gin_trgm_ops"} -- cgit v1.2.1 From 4f7f3258c18dfc207b838401f5ed71a3197eb22d Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Wed, 1 Jun 2016 18:34:20 +0800 Subject: Implement the logic for locking runner --- app/models/ci/build.rb | 4 +--- app/models/ci/runner.rb | 18 ++++++++++++++++ spec/models/build_spec.rb | 55 +++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 72 insertions(+), 5 deletions(-) diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index b8ada6361ac..860ac16eefd 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -291,9 +291,7 @@ module Ci end def can_be_served?(runner) - return false unless has_tags? || runner.run_untagged? - - (tag_list - runner.tag_list).empty? + runner.can_serve?(self) end def has_tags? diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb index adb65292208..d61a8c00634 100644 --- a/app/models/ci/runner.rb +++ b/app/models/ci/runner.rb @@ -91,6 +91,12 @@ module Ci !shared? end + def can_serve?(build) + not_locked_or_locked_to?(build.project) && + run_untagged_or_has_tags?(build) && + accepting_tags?(build.tag_list) + end + def only_for?(project) projects == [project] end @@ -111,5 +117,17 @@ module Ci 'can not be empty when runner is not allowed to pick untagged jobs') end end + + def not_locked_or_locked_to?(project) + !locked? || projects.exists?(id: project.id) + end + + def run_untagged_or_has_tags?(build) + run_untagged? || build.has_tags? + end + + def accepting_tags?(target_tags) + (target_tags - tag_list).empty? + end end end diff --git a/spec/models/build_spec.rb b/spec/models/build_spec.rb index 7660ea2659c..8cd1ffae9ce 100644 --- a/spec/models/build_spec.rb +++ b/spec/models/build_spec.rb @@ -296,16 +296,67 @@ describe Ci::Build, models: true do it_behaves_like 'tagged build picker' end - context 'when runner can not pick untagged jobs' do + context 'when runner cannot pick untagged jobs' do before { runner.run_untagged = false } - it 'can not handle builds without tags' do + it 'cannot handle builds without tags' do expect(build.can_be_served?(runner)).to be_falsey end it_behaves_like 'tagged build picker' end end + + context 'when runner is locked' do + before { runner.locked = true } + + shared_examples 'locked build picker' do |serve_matching_tags| + context 'when runner cannot pick untagged jobs' do + before { runner.run_untagged = false } + + it 'cannot handle builds without tags' do + expect(build.can_be_served?(runner)).to be_falsey + end + end + + context 'when having runner tags' do + before { runner.tag_list = ['bb', 'cc'] } + + it "#{serve_matching_tags} handle it for matching tags" do + build.tag_list = ['bb'] + expected = if serve_matching_tags + be_truthy + else + be_falsey + end + expect(build.can_be_served?(runner)).to expected + end + + it 'cannot handle it for builds without matching tags' do + build.tag_list = ['aa'] + expect(build.can_be_served?(runner)).to be_falsey + end + end + end + + context 'when serving the same project' do + it 'can handle it' do + expect(build.can_be_served?(runner)).to be_truthy + end + + it_behaves_like 'locked build picker', true + end + + context 'serving a different project' do + before { runner.runner_projects.destroy_all } + + it 'cannot handle it' do + expect(build.can_be_served?(runner)).to be_falsey + end + + it_behaves_like 'locked build picker', false + end + end end describe '#has_tags?' do -- cgit v1.2.1 From 0eeb4bed497e5f6ba2af558869803432bee65f74 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 2 Jun 2016 18:41:26 +0800 Subject: Introduced Ci::Runner.specific_for for getting specific runners: for a particular project. --- app/controllers/projects/runners_controller.rb | 3 +- app/models/ci/runner.rb | 4 ++ spec/models/ci/runner_spec.rb | 54 ++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/app/controllers/projects/runners_controller.rb b/app/controllers/projects/runners_controller.rb index 0b4fa572501..bc4c5bd4575 100644 --- a/app/controllers/projects/runners_controller.rb +++ b/app/controllers/projects/runners_controller.rb @@ -7,8 +7,7 @@ class Projects::RunnersController < Projects::ApplicationController def index @runners = project.runners.ordered @specific_runners = current_user.ci_authorized_runners. - where.not(id: project.runners). - ordered.page(params[:page]).per(20) + specific_for(project).ordered.page(params[:page]).per(20) @shared_runners = Ci::Runner.shared.active @shared_runners_count = @shared_runners.count(:all) end diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb index d61a8c00634..5c42c94e4dc 100644 --- a/app/models/ci/runner.rb +++ b/app/models/ci/runner.rb @@ -26,6 +26,10 @@ module Ci .where("ci_runner_projects.gl_project_id = :project_id OR ci_runners.is_shared = true", project_id: project_id) end + scope :specific_for, ->(project) do + where(locked: false).where.not(id: project.runners).specific + end + validate :tag_constraints acts_as_taggable diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb index 5d04d8ffcff..0d7ce5a020a 100644 --- a/spec/models/ci/runner_spec.rb +++ b/spec/models/ci/runner_spec.rb @@ -112,6 +112,60 @@ describe Ci::Runner, models: true do end end + describe :specific_for do + let(:runner) { create(:ci_runner) } + let(:project) { create(:project) } + let(:another_project) { create(:project) } + + before { project.runners << runner } + + context 'with shared runners' do + before { runner.update(is_shared: true) } + + context 'should not give owned runner' do + subject { Ci::Runner.specific_for(project) } + + it { is_expected.to be_empty } + end + + context 'should not give shared runner' do + subject { Ci::Runner.specific_for(another_project) } + + it { is_expected.to be_empty } + end + end + + context 'with unlocked runner' do + context 'should not give owned runner' do + subject { Ci::Runner.specific_for(project) } + + it { is_expected.to be_empty } + end + + context 'should give a specific runner' do + subject { Ci::Runner.specific_for(another_project) } + + it { is_expected.to contain_exactly(runner) } + end + end + + context 'with locked runner' do + before { runner.update(locked: true) } + + context 'should not give owned runner' do + subject { Ci::Runner.specific_for(project) } + + it { is_expected.to be_empty } + end + + context 'should not give a locked runner' do + subject { Ci::Runner.specific_for(another_project) } + + it { is_expected.to be_empty } + end + end + end + describe "belongs_to_one_project?" do it "returns false if there are two projects runner assigned to" do runner = FactoryGirl.create(:ci_runner) -- cgit v1.2.1 From 1c302d566b45c83c0c768354b40e86ea0446dfe6 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 2 Jun 2016 19:06:01 +0800 Subject: WIP, try to add views for locked runners --- app/models/ci/runner.rb | 2 +- app/views/projects/runners/_form.html.haml | 6 ++++++ app/views/projects/runners/show.html.haml | 3 +++ lib/api/entities.rb | 1 + lib/api/runners.rb | 2 +- lib/ci/api/runners.rb | 3 ++- 6 files changed, 14 insertions(+), 3 deletions(-) diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb index 5c42c94e4dc..7a3dfaa4e61 100644 --- a/app/models/ci/runner.rb +++ b/app/models/ci/runner.rb @@ -4,7 +4,7 @@ module Ci LAST_CONTACT_TIME = 5.minutes.ago AVAILABLE_SCOPES = %w[specific shared active paused online] - FORM_EDITABLE = %i[description tag_list active run_untagged] + FORM_EDITABLE = %i[description tag_list active run_untagged locked] has_many :builds, class_name: 'Ci::Build' has_many :runner_projects, dependent: :destroy, class_name: 'Ci::RunnerProject' diff --git a/app/views/projects/runners/_form.html.haml b/app/views/projects/runners/_form.html.haml index d62f5c8f131..67839fafd28 100644 --- a/app/views/projects/runners/_form.html.haml +++ b/app/views/projects/runners/_form.html.haml @@ -12,6 +12,12 @@ .checkbox = f.check_box :run_untagged %span.light Indicates whether this runner can pick jobs without tags + .form-group + = label :locked, 'Exclusive to this project', class: 'control-label' + .col-sm-10 + .checkbox + = f.check_box :locked + %span.light Indicates whether this runner can be enabled for other projects .form-group = label_tag :token, class: 'control-label' do Token diff --git a/app/views/projects/runners/show.html.haml b/app/views/projects/runners/show.html.haml index f24e1b9144e..fc6424402ae 100644 --- a/app/views/projects/runners/show.html.haml +++ b/app/views/projects/runners/show.html.haml @@ -22,6 +22,9 @@ %tr %td Can run untagged jobs %td= @runner.run_untagged? ? 'Yes' : 'No' + %tr + %td Exclusive to this project + %td= @runner.locked? ? 'Yes' : 'No' %tr %td Tags %td diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 50d69274b2e..16eeca8c8ac 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -413,6 +413,7 @@ module API class RunnerDetails < Runner expose :tag_list expose :run_untagged + expose :locked expose :version, :revision, :platform, :architecture expose :contacted_at expose :token, if: lambda { |runner, options| options[:current_user].is_admin? || !runner.is_shared? } diff --git a/lib/api/runners.rb b/lib/api/runners.rb index 4faba9dc87b..2d09b6193d9 100644 --- a/lib/api/runners.rb +++ b/lib/api/runners.rb @@ -49,7 +49,7 @@ module API runner = get_runner(params[:id]) authenticate_update_runner!(runner) - attrs = attributes_for_keys [:description, :active, :tag_list, :run_untagged] + attrs = attributes_for_keys [:description, :active, :tag_list, :run_untagged, :locked] if runner.update(attrs) present runner, with: Entities::RunnerDetails, current_user: current_user else diff --git a/lib/ci/api/runners.rb b/lib/ci/api/runners.rb index 0c41f22c7c5..b4b7261fa3b 100644 --- a/lib/ci/api/runners.rb +++ b/lib/ci/api/runners.rb @@ -29,7 +29,8 @@ module Ci required_attributes! [:token] attributes = { description: params[:description], - tag_list: params[:tag_list] } + tag_list: params[:tag_list], + locked: !!params[:locked] } unless params[:run_untagged].nil? attributes[:run_untagged] = params[:run_untagged] -- cgit v1.2.1 From 35954572b898e5a58cd209276e1bff499990867b Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 2 Jun 2016 23:28:14 +0800 Subject: Prefer do and end for before/after: Feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/4404#note_12217415 --- spec/models/ci/runner_spec.rb | 44 ++++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb index 0d7ce5a020a..1e87d7751b8 100644 --- a/spec/models/ci/runner_spec.rb +++ b/spec/models/ci/runner_spec.rb @@ -40,7 +40,9 @@ describe Ci::Runner, models: true do let!(:project) { FactoryGirl.create :empty_project } let!(:shared_runner) { FactoryGirl.create(:ci_runner, :shared) } - before { shared_runner.assign_to(project) } + before do + shared_runner.assign_to(project) + end it { expect(shared_runner).to be_specific } it { expect(shared_runner.projects).to eq([project]) } @@ -64,19 +66,25 @@ describe Ci::Runner, models: true do subject { runner.online? } context 'never contacted' do - before { runner.contacted_at = nil } + before do + runner.contacted_at = nil + end it { is_expected.to be_falsey } end context 'contacted long time ago time' do - before { runner.contacted_at = 1.year.ago } + before do + runner.contacted_at = 1.year.ago + end it { is_expected.to be_falsey } end context 'contacted 1s ago' do - before { runner.contacted_at = 1.second.ago } + before do + runner.contacted_at = 1.second.ago + end it { is_expected.to be_truthy } end @@ -88,25 +96,33 @@ describe Ci::Runner, models: true do subject { runner.status } context 'never connected' do - before { runner.contacted_at = nil } + before do + runner.contacted_at = nil + end it { is_expected.to eq(:not_connected) } end context 'contacted 1s ago' do - before { runner.contacted_at = 1.second.ago } + before do + runner.contacted_at = 1.second.ago + end it { is_expected.to eq(:online) } end context 'contacted long time ago' do - before { runner.contacted_at = 1.year.ago } + before do + runner.contacted_at = 1.year.ago + end it { is_expected.to eq(:offline) } end context 'inactive' do - before { runner.active = false } + before do + runner.active = false + end it { is_expected.to eq(:paused) } end @@ -117,10 +133,14 @@ describe Ci::Runner, models: true do let(:project) { create(:project) } let(:another_project) { create(:project) } - before { project.runners << runner } + before do + project.runners << runner + end context 'with shared runners' do - before { runner.update(is_shared: true) } + before do + runner.update(is_shared: true) + end context 'should not give owned runner' do subject { Ci::Runner.specific_for(project) } @@ -150,7 +170,9 @@ describe Ci::Runner, models: true do end context 'with locked runner' do - before { runner.update(locked: true) } + before do + runner.update(locked: true) + end context 'should not give owned runner' do subject { Ci::Runner.specific_for(project) } -- cgit v1.2.1 From 2ea0148c55fbefee1137c254a94b37c05dca41cf Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Mon, 6 Jun 2016 18:20:30 +0800 Subject: Update migration with add_column_with_default: Feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/4093#note_12278454 --- db/migrate/20160509091049_add_locked_to_ci_runner.rb | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/db/migrate/20160509091049_add_locked_to_ci_runner.rb b/db/migrate/20160509091049_add_locked_to_ci_runner.rb index 6294fa9d86b..43376304bd9 100644 --- a/db/migrate/20160509091049_add_locked_to_ci_runner.rb +++ b/db/migrate/20160509091049_add_locked_to_ci_runner.rb @@ -2,7 +2,12 @@ class AddLockedToCiRunner < ActiveRecord::Migration ## # Downtime expected due to exclusive lock when setting default value. # - def change - add_column :ci_runners, :locked, :boolean, default: false, null: false + def up + add_column_with_default(:ci_runners, :locked, :boolean, + default: false, allow_null: false) + end + + def down + remove_column(:ci_runners, :locked) end end -- cgit v1.2.1 From 894d22f49a24377aad7e693d0343397bc349e412 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Mon, 6 Jun 2016 18:48:18 +0800 Subject: include the helper --- db/migrate/20160509091049_add_locked_to_ci_runner.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/db/migrate/20160509091049_add_locked_to_ci_runner.rb b/db/migrate/20160509091049_add_locked_to_ci_runner.rb index 43376304bd9..3fbaef3b7f0 100644 --- a/db/migrate/20160509091049_add_locked_to_ci_runner.rb +++ b/db/migrate/20160509091049_add_locked_to_ci_runner.rb @@ -1,7 +1,7 @@ class AddLockedToCiRunner < ActiveRecord::Migration - ## - # Downtime expected due to exclusive lock when setting default value. - # + include Gitlab::Database::MigrationHelpers + disable_ddl_transaction! + def up add_column_with_default(:ci_runners, :locked, :boolean, default: false, allow_null: false) -- cgit v1.2.1 From 781d35c191be62366f6c7855f3314a9c371aa0e6 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Tue, 7 Jun 2016 14:50:38 +0800 Subject: Prefer attributes_for_keys so that it ignores nils Also add a test for setting locked. --- lib/ci/api/runners.rb | 10 +++------- spec/requests/api/runners_spec.rb | 6 ++++-- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/lib/ci/api/runners.rb b/lib/ci/api/runners.rb index b4b7261fa3b..bcc82969eb3 100644 --- a/lib/ci/api/runners.rb +++ b/lib/ci/api/runners.rb @@ -28,13 +28,9 @@ module Ci post "register" do required_attributes! [:token] - attributes = { description: params[:description], - tag_list: params[:tag_list], - locked: !!params[:locked] } - - unless params[:run_untagged].nil? - attributes[:run_untagged] = params[:run_untagged] - end + attributes = attributes_for_keys( + [:description, :tag_list, :run_untagged, :locked] + ) runner = if runner_registration_token_valid? diff --git a/spec/requests/api/runners_spec.rb b/spec/requests/api/runners_spec.rb index 73ae8ef631c..f4f9c417bbb 100644 --- a/spec/requests/api/runners_spec.rb +++ b/spec/requests/api/runners_spec.rb @@ -187,14 +187,16 @@ describe API::Runners, api: true do update_runner(shared_runner.id, admin, description: "#{description}_updated", active: !active, tag_list: ['ruby2.1', 'pgsql', 'mysql'], - run_untagged: 'false') + run_untagged: 'false', + locked: 'true') shared_runner.reload expect(response.status).to eq(200) expect(shared_runner.description).to eq("#{description}_updated") expect(shared_runner.active).to eq(!active) expect(shared_runner.tag_list).to include('ruby2.1', 'pgsql', 'mysql') - expect(shared_runner.run_untagged?).to be false + expect(shared_runner.run_untagged?).to be(false) + expect(shared_runner.locked?).to be(true) end end -- cgit v1.2.1 From b08912dbd37eb05243448b2e310939c5679d61e3 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Tue, 7 Jun 2016 15:00:41 +0800 Subject: Use block for before/after as we preferred --- spec/models/build_spec.rb | 89 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 67 insertions(+), 22 deletions(-) diff --git a/spec/models/build_spec.rb b/spec/models/build_spec.rb index 8cd1ffae9ce..1d4b8bc4c98 100644 --- a/spec/models/build_spec.rb +++ b/spec/models/build_spec.rb @@ -36,32 +36,44 @@ describe Ci::Build, models: true do subject { build.ignored? } context 'if build is not allowed to fail' do - before { build.allow_failure = false } + before do + build.allow_failure = false + end context 'and build.status is success' do - before { build.status = 'success' } + before do + build.status = 'success' + end it { is_expected.to be_falsey } end context 'and build.status is failed' do - before { build.status = 'failed' } + before do + build.status = 'failed' + end it { is_expected.to be_falsey } end end context 'if build is allowed to fail' do - before { build.allow_failure = true } + before do + build.allow_failure = true + end context 'and build.status is success' do - before { build.status = 'success' } + before do + build.status = 'success' + end it { is_expected.to be_falsey } end context 'and build.status is failed' do - before { build.status = 'failed' } + before do + build.status = 'failed' + end it { is_expected.to be_truthy } end @@ -75,7 +87,9 @@ describe Ci::Build, models: true do context 'if build.trace contains text' do let(:text) { 'example output' } - before { build.trace = text } + before do + build.trace = text + end it { is_expected.to include(text) } it { expect(subject.length).to be >= text.length } @@ -188,7 +202,9 @@ describe Ci::Build, models: true do ] end - before { build.update_attributes(stage: 'stage') } + before do + build.update_attributes(stage: 'stage') + end it { is_expected.to eq(predefined_variables + yaml_variables) } @@ -199,7 +215,9 @@ describe Ci::Build, models: true do ] end - before { build.update_attributes(tag: true) } + before do + build.update_attributes(tag: true) + end it { is_expected.to eq(tag_variable + predefined_variables + yaml_variables) } end @@ -260,7 +278,9 @@ describe Ci::Build, models: true do describe '#can_be_served?' do let(:runner) { create(:ci_runner) } - before { build.project.runners << runner } + before do + build.project.runners << runner + end context 'when runner does not have tags' do it 'can handle builds without tags' do @@ -274,7 +294,9 @@ describe Ci::Build, models: true do end context 'when runner has tags' do - before { runner.tag_list = ['bb', 'cc'] } + before do + runner.tag_list = ['bb', 'cc'] + end shared_examples 'tagged build picker' do it 'can handle build with matching tags' do @@ -297,7 +319,9 @@ describe Ci::Build, models: true do end context 'when runner cannot pick untagged jobs' do - before { runner.run_untagged = false } + before do + runner.run_untagged = false + end it 'cannot handle builds without tags' do expect(build.can_be_served?(runner)).to be_falsey @@ -308,11 +332,15 @@ describe Ci::Build, models: true do end context 'when runner is locked' do - before { runner.locked = true } + before do + runner.locked = true + end shared_examples 'locked build picker' do |serve_matching_tags| context 'when runner cannot pick untagged jobs' do - before { runner.run_untagged = false } + before do + runner.run_untagged = false + end it 'cannot handle builds without tags' do expect(build.can_be_served?(runner)).to be_falsey @@ -320,7 +348,9 @@ describe Ci::Build, models: true do end context 'when having runner tags' do - before { runner.tag_list = ['bb', 'cc'] } + before do + runner.tag_list = ['bb', 'cc'] + end it "#{serve_matching_tags} handle it for matching tags" do build.tag_list = ['bb'] @@ -348,7 +378,9 @@ describe Ci::Build, models: true do end context 'serving a different project' do - before { runner.runner_projects.destroy_all } + before do + runner.runner_projects.destroy_all + end it 'cannot handle it' do expect(build.can_be_served?(runner)).to be_falsey @@ -411,7 +443,9 @@ describe Ci::Build, models: true do %w(pending).each do |state| context "if commit_status.status is #{state}" do - before { build.status = state } + before do + build.status = state + end it { is_expected.to be_truthy } @@ -430,7 +464,9 @@ describe Ci::Build, models: true do %w(success failed canceled running).each do |state| context "if commit_status.status is #{state}" do - before { build.status = state } + before do + build.status = state + end it { is_expected.to be_falsey } end @@ -441,7 +477,10 @@ describe Ci::Build, models: true do subject { build.artifacts? } context 'artifacts archive does not exist' do - before { build.update_attributes(artifacts_file: nil) } + before do + build.update_attributes(artifacts_file: nil) + end + it { is_expected.to be_falsy } end @@ -606,7 +645,9 @@ describe Ci::Build, models: true do let!(:build) { create(:ci_build, :trace, :success, :artifacts) } describe '#erase' do - before { build.erase(erased_by: user) } + before do + build.erase(erased_by: user) + end context 'erased by user' do let!(:user) { create(:user, username: 'eraser') } @@ -643,7 +684,9 @@ describe Ci::Build, models: true do end context 'build has been erased' do - before { build.erase } + before do + build.erase + end it { is_expected.to be true } end @@ -651,7 +694,9 @@ describe Ci::Build, models: true do context 'metadata and build trace are not available' do let!(:build) { create(:ci_build, :success, :artifacts) } - before { build.remove_artifacts_metadata! } + before do + build.remove_artifacts_metadata! + end describe '#erase' do it 'should not raise error' do -- cgit v1.2.1 From fc51bf324826799ec43c8a0b59ad94f0220df8e2 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Tue, 7 Jun 2016 15:58:44 +0800 Subject: Found a workaround for that weird SQL error: Without that, Rails would complain: > bind message supplies 5 parameters, but prepared statement "a4" requires 4 However without this workaround it would still work in Rails console, so I still think this is a Rails bug somewhere. --- app/models/ci/runner.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb index 7a3dfaa4e61..6565a12fe62 100644 --- a/app/models/ci/runner.rb +++ b/app/models/ci/runner.rb @@ -27,7 +27,9 @@ module Ci end scope :specific_for, ->(project) do - where(locked: false).where.not(id: project.runners).specific + # TODO: That `to_sql` is needed to workaround a weird Rails bug. + # Without that, placeholders would miss one and couldn't match. + where(locked: false).where.not(id: project.runners.to_sql).specific end validate :tag_constraints -- cgit v1.2.1 From 5bd077bd41653ead0925fd775fd07ba3fd26468f Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Tue, 7 Jun 2016 17:43:18 +0800 Subject: Manually build the SQL so that it properly skips Rails. --- app/models/ci/runner.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb index 6565a12fe62..bb5340a0f03 100644 --- a/app/models/ci/runner.rb +++ b/app/models/ci/runner.rb @@ -29,7 +29,8 @@ module Ci scope :specific_for, ->(project) do # TODO: That `to_sql` is needed to workaround a weird Rails bug. # Without that, placeholders would miss one and couldn't match. - where(locked: false).where.not(id: project.runners.to_sql).specific + where(locked: false). + where.not("id IN (#{project.runners.select(:id).to_sql})").specific end validate :tag_constraints -- cgit v1.2.1 From 7fa80a79cdf91782f68794e5a5b879abf6d986dc Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Tue, 7 Jun 2016 22:42:07 +0800 Subject: Fixed a typo (remove extra n) --- doc/ci/runners/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/ci/runners/README.md b/doc/ci/runners/README.md index b42d7a62ebc..40dc13d53b1 100644 --- a/doc/ci/runners/README.md +++ b/doc/ci/runners/README.md @@ -66,7 +66,7 @@ Now simply register the runner as any runner: sudo gitlab-runner register ``` -Shared runners are enabled by default as of GitLab 8.2, but can be disabled with the +Shared runners are enabled by default as of GitLab 8.2, but can be disabled with the `DISABLE SHARED RUNNERS` button. Previous versions of GitLab defaulted shared runners to disabled. @@ -128,7 +128,7 @@ the appropriate dependencies to run Rails test suites. ### Prevent runner with tags from picking jobs without tags You can configure a runner to prevent it from picking jobs with tags when -the runnner does not have tags assigned. This setting is available on each +the runner does not have tags assigned. This setting is available on each runner in *Project Settings* > *Runners*. ### Be careful with sensitive information -- cgit v1.2.1 From 9e14ebe6bce26fc16b7310b61870f41747e83d14 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Tue, 7 Jun 2016 22:48:16 +0800 Subject: Update CHANGELOG and doc for locked runner feature --- CHANGELOG | 1 + doc/ci/runners/README.md | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 0ea307a3713..a23eda6c026 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -39,6 +39,7 @@ v 8.9.0 (unreleased) - Projects pending deletion will render a 404 page - Measure queue duration between gitlab-workhorse and Rails - Make authentication service for Container Registry to be compatible with < Docker 1.11 + - Make it possible to lock a runner from being enabled for other projects - Add Application Setting to configure Container Registry token expire delay (default 5min) - Cache assigned issue and merge request counts in sidebar nav - Use Knapsack only in CI environment diff --git a/doc/ci/runners/README.md b/doc/ci/runners/README.md index 40dc13d53b1..bd654e655d6 100644 --- a/doc/ci/runners/README.md +++ b/doc/ci/runners/README.md @@ -96,6 +96,12 @@ To register the runner, run the command below and follow instructions: sudo gitlab-runner register ``` +### Lock a specific runner from being enabled from other projects + +You can configure a runner to prevent it from being enabled for the other +projects, so it's exclusive to current projects. This setting is available +on each runner in *Project Settings* > *Runners*. + ### Making an existing Shared Runner Specific If you are an admin on your GitLab instance, -- cgit v1.2.1 From de04004803b76cb9945ef027d04968cef7b41b2b Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Wed, 8 Jun 2016 14:46:41 +0800 Subject: Prefer string for describe, feedback from: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/4093#note_12321029 --- spec/models/ci/runner_spec.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb index 1e87d7751b8..c3b715dcb92 100644 --- a/spec/models/ci/runner_spec.rb +++ b/spec/models/ci/runner_spec.rb @@ -36,7 +36,7 @@ describe Ci::Runner, models: true do end end - describe :assign_to do + describe '#assign_to' do let!(:project) { FactoryGirl.create :empty_project } let!(:shared_runner) { FactoryGirl.create(:ci_runner, :shared) } @@ -49,7 +49,7 @@ describe Ci::Runner, models: true do it { expect(shared_runner.only_for?(project)).to be_truthy } end - describe :online do + describe '.online' do subject { Ci::Runner.online } before do @@ -60,7 +60,7 @@ describe Ci::Runner, models: true do it { is_expected.to eq([@runner2])} end - describe :online? do + describe '#online?' do let(:runner) { FactoryGirl.create(:ci_runner, :shared) } subject { runner.online? } @@ -90,7 +90,7 @@ describe Ci::Runner, models: true do end end - describe :status do + describe '#status' do let(:runner) { FactoryGirl.create(:ci_runner, :shared, contacted_at: 1.second.ago) } subject { runner.status } @@ -128,7 +128,7 @@ describe Ci::Runner, models: true do end end - describe :specific_for do + describe '.specific_for' do let(:runner) { create(:ci_runner) } let(:project) { create(:project) } let(:another_project) { create(:project) } -- cgit v1.2.1 From 268f7713a9c076204a8b6badb847d2e23bafdd71 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Wed, 8 Jun 2016 15:19:49 +0800 Subject: Remove Build#can_be_served? and rename Runner#can_serve? to can_pick? This also moves tests from build_spec.rb to runner_spec.rb --- app/models/ci/build.rb | 6 +- app/models/ci/runner.rb | 2 +- app/services/ci/register_build_service.rb | 2 +- spec/models/build_spec.rb | 118 +---------------------------- spec/models/ci/runner_spec.rb | 119 ++++++++++++++++++++++++++++++ 5 files changed, 123 insertions(+), 124 deletions(-) diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index 860ac16eefd..a3a30fe17c2 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -290,16 +290,12 @@ module Ci project.valid_runners_token? token end - def can_be_served?(runner) - runner.can_serve?(self) - end - def has_tags? tag_list.any? end def any_runners_online? - project.any_runners? { |runner| runner.active? && runner.online? && can_be_served?(runner) } + project.any_runners? { |runner| runner.active? && runner.online? && runner.can_pick?(self) } end def stuck? diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb index bb5340a0f03..44f820d100b 100644 --- a/app/models/ci/runner.rb +++ b/app/models/ci/runner.rb @@ -98,7 +98,7 @@ module Ci !shared? end - def can_serve?(build) + def can_pick?(build) not_locked_or_locked_to?(build.project) && run_untagged_or_has_tags?(build) && accepting_tags?(build.tag_list) diff --git a/app/services/ci/register_build_service.rb b/app/services/ci/register_build_service.rb index 4ff268a6f06..511505bc9a9 100644 --- a/app/services/ci/register_build_service.rb +++ b/app/services/ci/register_build_service.rb @@ -17,7 +17,7 @@ module Ci builds = builds.order('created_at ASC') build = builds.find do |build| - build.can_be_served?(current_runner) + current_runner.can_pick?(build) end if build diff --git a/spec/models/build_spec.rb b/spec/models/build_spec.rb index 1d4b8bc4c98..e703a07013b 100644 --- a/spec/models/build_spec.rb +++ b/spec/models/build_spec.rb @@ -275,122 +275,6 @@ describe Ci::Build, models: true do end end - describe '#can_be_served?' do - let(:runner) { create(:ci_runner) } - - before do - build.project.runners << runner - end - - context 'when runner does not have tags' do - it 'can handle builds without tags' do - expect(build.can_be_served?(runner)).to be_truthy - end - - it 'cannot handle build with tags' do - build.tag_list = ['aa'] - expect(build.can_be_served?(runner)).to be_falsey - end - end - - context 'when runner has tags' do - before do - runner.tag_list = ['bb', 'cc'] - end - - shared_examples 'tagged build picker' do - it 'can handle build with matching tags' do - build.tag_list = ['bb'] - expect(build.can_be_served?(runner)).to be_truthy - end - - it 'cannot handle build without matching tags' do - build.tag_list = ['aa'] - expect(build.can_be_served?(runner)).to be_falsey - end - end - - context 'when runner can pick untagged jobs' do - it 'can handle builds without tags' do - expect(build.can_be_served?(runner)).to be_truthy - end - - it_behaves_like 'tagged build picker' - end - - context 'when runner cannot pick untagged jobs' do - before do - runner.run_untagged = false - end - - it 'cannot handle builds without tags' do - expect(build.can_be_served?(runner)).to be_falsey - end - - it_behaves_like 'tagged build picker' - end - end - - context 'when runner is locked' do - before do - runner.locked = true - end - - shared_examples 'locked build picker' do |serve_matching_tags| - context 'when runner cannot pick untagged jobs' do - before do - runner.run_untagged = false - end - - it 'cannot handle builds without tags' do - expect(build.can_be_served?(runner)).to be_falsey - end - end - - context 'when having runner tags' do - before do - runner.tag_list = ['bb', 'cc'] - end - - it "#{serve_matching_tags} handle it for matching tags" do - build.tag_list = ['bb'] - expected = if serve_matching_tags - be_truthy - else - be_falsey - end - expect(build.can_be_served?(runner)).to expected - end - - it 'cannot handle it for builds without matching tags' do - build.tag_list = ['aa'] - expect(build.can_be_served?(runner)).to be_falsey - end - end - end - - context 'when serving the same project' do - it 'can handle it' do - expect(build.can_be_served?(runner)).to be_truthy - end - - it_behaves_like 'locked build picker', true - end - - context 'serving a different project' do - before do - runner.runner_projects.destroy_all - end - - it 'cannot handle it' do - expect(build.can_be_served?(runner)).to be_falsey - end - - it_behaves_like 'locked build picker', false - end - end - end - describe '#has_tags?' do context 'when build has tags' do subject { create(:ci_build, tag_list: ['tag']) } @@ -431,7 +315,7 @@ describe Ci::Build, models: true do end it 'that cannot handle build' do - expect_any_instance_of(Ci::Build).to receive(:can_be_served?).and_return(false) + expect_any_instance_of(Ci::Runner).to receive(:can_pick?).and_return(false) is_expected.to be_falsey end diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb index c3b715dcb92..477a32a1f9e 100644 --- a/spec/models/ci/runner_spec.rb +++ b/spec/models/ci/runner_spec.rb @@ -90,6 +90,125 @@ describe Ci::Runner, models: true do end end + describe '#can_pick?' do + let(:project) { create(:project) } + let(:commit) { create(:ci_commit, project: project) } + let(:build) { create(:ci_build, commit: commit) } + let(:runner) { create(:ci_runner) } + + before do + build.project.runners << runner + end + + context 'when runner does not have tags' do + it 'can handle builds without tags' do + expect(runner.can_pick?(build)).to be_truthy + end + + it 'cannot handle build with tags' do + build.tag_list = ['aa'] + expect(runner.can_pick?(build)).to be_falsey + end + end + + context 'when runner has tags' do + before do + runner.tag_list = ['bb', 'cc'] + end + + shared_examples 'tagged build picker' do + it 'can handle build with matching tags' do + build.tag_list = ['bb'] + expect(runner.can_pick?(build)).to be_truthy + end + + it 'cannot handle build without matching tags' do + build.tag_list = ['aa'] + expect(runner.can_pick?(build)).to be_falsey + end + end + + context 'when runner can pick untagged jobs' do + it 'can handle builds without tags' do + expect(runner.can_pick?(build)).to be_truthy + end + + it_behaves_like 'tagged build picker' + end + + context 'when runner cannot pick untagged jobs' do + before do + runner.run_untagged = false + end + + it 'cannot handle builds without tags' do + expect(runner.can_pick?(build)).to be_falsey + end + + it_behaves_like 'tagged build picker' + end + end + + context 'when runner is locked' do + before do + runner.locked = true + end + + shared_examples 'locked build picker' do |serve_matching_tags| + context 'when runner cannot pick untagged jobs' do + before do + runner.run_untagged = false + end + + it 'cannot handle builds without tags' do + expect(runner.can_pick?(build)).to be_falsey + end + end + + context 'when having runner tags' do + before do + runner.tag_list = ['bb', 'cc'] + end + + it "#{serve_matching_tags} handle it for matching tags" do + build.tag_list = ['bb'] + expected = if serve_matching_tags + be_truthy + else + be_falsey + end + expect(runner.can_pick?(build)).to expected + end + + it 'cannot handle it for builds without matching tags' do + build.tag_list = ['aa'] + expect(runner.can_pick?(build)).to be_falsey + end + end + end + + context 'when serving the same project' do + it 'can handle it' do + expect(runner.can_pick?(build)).to be_truthy + end + + it_behaves_like 'locked build picker', true + end + + context 'serving a different project' do + before do + runner.runner_projects.destroy_all + end + + it 'cannot handle it' do + expect(runner.can_pick?(build)).to be_falsey + end + + it_behaves_like 'locked build picker', false + end + end + end + describe '#status' do let(:runner) { FactoryGirl.create(:ci_runner, :shared, contacted_at: 1.second.ago) } -- cgit v1.2.1 From d7b08024afa41d59c5d41c0e1972e2580e019996 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Wed, 8 Jun 2016 15:38:34 +0800 Subject: Renamed to available_for? Feedback from: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/4093#note_12321240 --- app/models/ci/runner.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb index 44f820d100b..9bd4d3ab0a5 100644 --- a/app/models/ci/runner.rb +++ b/app/models/ci/runner.rb @@ -99,7 +99,7 @@ module Ci end def can_pick?(build) - not_locked_or_locked_to?(build.project) && + available_for?(build.project) && run_untagged_or_has_tags?(build) && accepting_tags?(build.tag_list) end @@ -125,7 +125,7 @@ module Ci end end - def not_locked_or_locked_to?(project) + def available_for?(project) !locked? || projects.exists?(id: project.id) end -- cgit v1.2.1 From 8b34687a36c1ec4e558724513bcabdfa3b706854 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Wed, 8 Jun 2016 15:43:43 +0800 Subject: Merge conditions. Not worth an additional pointless method: Feedback from: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/4093#note_12321267 --- app/models/ci/runner.rb | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb index 9bd4d3ab0a5..bb1cffdcae6 100644 --- a/app/models/ci/runner.rb +++ b/app/models/ci/runner.rb @@ -99,9 +99,7 @@ module Ci end def can_pick?(build) - available_for?(build.project) && - run_untagged_or_has_tags?(build) && - accepting_tags?(build.tag_list) + available_for?(build.project) && accepting_tags?(build) end def only_for?(project) @@ -129,12 +127,8 @@ module Ci !locked? || projects.exists?(id: project.id) end - def run_untagged_or_has_tags?(build) - run_untagged? || build.has_tags? - end - - def accepting_tags?(target_tags) - (target_tags - tag_list).empty? + def accepting_tags?(build) + (run_untagged? || build.has_tags?) && (build.tag_list - tag_list).empty? end end end -- cgit v1.2.1 From b0908d873921c30ea58da703bf74b4149b6fc145 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Wed, 8 Jun 2016 16:07:08 +0800 Subject: Extra tests inside shared_examples: Feedback from: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/4093#note_12321421 The advantage of this is that tests are less about logic and more straightforward, thus could be easier to reason about each individual tests. The disadvantage of this is that we write more duplicated codes and once something changed we might need to change all places and it's harder to reason all tests as a whole. Because now we need to look at more places to figure out how it should work under another option! --- spec/models/ci/runner_spec.rb | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb index 477a32a1f9e..9a6bc6b96c1 100644 --- a/spec/models/ci/runner_spec.rb +++ b/spec/models/ci/runner_spec.rb @@ -154,7 +154,7 @@ describe Ci::Runner, models: true do runner.locked = true end - shared_examples 'locked build picker' do |serve_matching_tags| + shared_examples 'locked build picker' do context 'when runner cannot pick untagged jobs' do before do runner.run_untagged = false @@ -170,16 +170,6 @@ describe Ci::Runner, models: true do runner.tag_list = ['bb', 'cc'] end - it "#{serve_matching_tags} handle it for matching tags" do - build.tag_list = ['bb'] - expected = if serve_matching_tags - be_truthy - else - be_falsey - end - expect(runner.can_pick?(build)).to expected - end - it 'cannot handle it for builds without matching tags' do build.tag_list = ['aa'] expect(runner.can_pick?(build)).to be_falsey @@ -192,7 +182,18 @@ describe Ci::Runner, models: true do expect(runner.can_pick?(build)).to be_truthy end - it_behaves_like 'locked build picker', true + it_behaves_like 'locked build picker' + + context 'when having runner tags' do + before do + runner.tag_list = ['bb', 'cc'] + build.tag_list = ['bb'] + end + + it 'can handle it for matching tags' do + expect(runner.can_pick?(build)).to be_truthy + end + end end context 'serving a different project' do @@ -204,7 +205,18 @@ describe Ci::Runner, models: true do expect(runner.can_pick?(build)).to be_falsey end - it_behaves_like 'locked build picker', false + it_behaves_like 'locked build picker' + + context 'when having runner tags' do + before do + runner.tag_list = ['bb', 'cc'] + build.tag_list = ['bb'] + end + + it 'cannot handle it for matching tags' do + expect(runner.can_pick?(build)).to be_falsey + end + end end end end -- cgit v1.2.1 From f59d972d5f51792bf3d432908eeb09c6865c977c Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 9 Jun 2016 15:49:34 +0800 Subject: Updated description for the form --- app/views/projects/runners/_form.html.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/projects/runners/_form.html.haml b/app/views/projects/runners/_form.html.haml index 67839fafd28..0946e5e327a 100644 --- a/app/views/projects/runners/_form.html.haml +++ b/app/views/projects/runners/_form.html.haml @@ -13,11 +13,11 @@ = f.check_box :run_untagged %span.light Indicates whether this runner can pick jobs without tags .form-group - = label :locked, 'Exclusive to this project', class: 'control-label' + = label :locked, 'Lock to this project', class: 'control-label' .col-sm-10 .checkbox = f.check_box :locked - %span.light Indicates whether this runner can be enabled for other projects + %span.light When a runner is locked, it cannot be enabled for other projects .form-group = label_tag :token, class: 'control-label' do Token -- cgit v1.2.1 From 4d277b9c747cb0bf14b6c6a88de228083be7f580 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 9 Jun 2016 16:06:02 +0800 Subject: Updated doc description according to feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/4093#note_12345562 --- doc/ci/runners/README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/ci/runners/README.md b/doc/ci/runners/README.md index bd654e655d6..49b283c43c8 100644 --- a/doc/ci/runners/README.md +++ b/doc/ci/runners/README.md @@ -98,9 +98,10 @@ sudo gitlab-runner register ### Lock a specific runner from being enabled from other projects -You can configure a runner to prevent it from being enabled for the other -projects, so it's exclusive to current projects. This setting is available -on each runner in *Project Settings* > *Runners*. +You can configure a runner to assign it exclusively to the one project. +When a runner is locked on project this way, it can no longer be enabled +for other projects. This setting is available on each runner in +*Project Settings* > *Runners*. ### Making an existing Shared Runner Specific -- cgit v1.2.1 From d936c32ed97894a333f27cdc9b9c8c9c4f64697d Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 9 Jun 2016 16:29:10 +0800 Subject: Tweak the wordings and grammar slightly --- doc/ci/runners/README.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/doc/ci/runners/README.md b/doc/ci/runners/README.md index 49b283c43c8..36556f8e670 100644 --- a/doc/ci/runners/README.md +++ b/doc/ci/runners/README.md @@ -96,12 +96,11 @@ To register the runner, run the command below and follow instructions: sudo gitlab-runner register ``` -### Lock a specific runner from being enabled from other projects +### Lock a specific runner from being enabled for other projects -You can configure a runner to assign it exclusively to the one project. -When a runner is locked on project this way, it can no longer be enabled -for other projects. This setting is available on each runner in -*Project Settings* > *Runners*. +You can configure a runner to assign it exclusively to a project. When a +runner is locked this way, it can no longer be enabled for other projects. +This setting is available on each runner in *Project Settings* > *Runners*. ### Making an existing Shared Runner Specific -- cgit v1.2.1 From 53121601f38155e926eed300160f79dd4bc0768b Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 9 Jun 2016 17:07:09 +0800 Subject: Add a small locked icon if it's locked: This is probably not the way we add icons, but well. Not sure if this should be put next to the status icon or edit icon, my first thought was put this next to status, but it looks a bit better next to edit button. Please tweak this accordingly. I don't have strong opinion regarding views. Feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/4093#note_12345567 --- app/views/projects/runners/_runner.html.haml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/views/projects/runners/_runner.html.haml b/app/views/projects/runners/_runner.html.haml index 96e2aac451f..08389528dc9 100644 --- a/app/views/projects/runners/_runner.html.haml +++ b/app/views/projects/runners/_runner.html.haml @@ -4,6 +4,8 @@ %span.monospace - if @runners.include?(runner) = link_to runner.short_sha, runner_path(runner) + - if runner.locked? + %small{title: 'Exclusive to this project'} 🔒 %small = link_to edit_namespace_project_runner_path(@project.namespace, @project, runner) do %i.fa.fa-edit.btn -- cgit v1.2.1 From b36d84b32912bada57d8d6af9df64cb0a2478f7c Mon Sep 17 00:00:00 2001 From: "Luke \"Jared\" Bennett" Date: Thu, 9 Jun 2016 16:06:13 +0100 Subject: Moved private forks notice to projects-list so its above the pagination and inline with list Updated CHANGELOG Removed CHANGELOG entry --- app/views/projects/forks/index.html.haml | 6 ------ app/views/shared/projects/_list.html.haml | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/views/projects/forks/index.html.haml b/app/views/projects/forks/index.html.haml index 4bcf2d9d533..dbe9ddfde2f 100644 --- a/app/views/projects/forks/index.html.haml +++ b/app/views/projects/forks/index.html.haml @@ -40,9 +40,3 @@ = render 'projects', projects: @forks - -- if @private_forks_count > 0 - .private-forks-notice - = icon('lock fw', base: 'circle', class: 'fa-lg private-fork-icon') - %strong= pluralize(@private_forks_count, 'private fork') - %span you have no access to. diff --git a/app/views/shared/projects/_list.html.haml b/app/views/shared/projects/_list.html.haml index 2e08bb2ac08..3a9dd37dc7d 100644 --- a/app/views/shared/projects/_list.html.haml +++ b/app/views/shared/projects/_list.html.haml @@ -16,6 +16,12 @@ = render "shared/projects/project", project: project, skip_namespace: skip_namespace, avatar: avatar, stars: stars, css_class: css_class, ci: ci, use_creator_avatar: use_creator_avatar, forks: forks, show_last_commit_as_description: show_last_commit_as_description + + - if @private_forks_count && @private_forks_count > 0 + %li.project-row.private-forks-notice + = icon('lock fw', base: 'circle', class: 'fa-lg private-fork-icon') + %strong= pluralize(@private_forks_count, 'private fork') + %span you have no access to. = paginate(projects, remote: remote, theme: "gitlab") if projects.respond_to? :total_pages - else .nothing-here-block No projects found -- cgit v1.2.1 From ad57a94a092d8b8326c1bbd854ea49c1cd9f5743 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Mon, 13 Jun 2016 16:13:16 +0100 Subject: Hides award emoji & access level on system notes --- app/views/projects/notes/_note.html.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml index bcdbff08011..57050a87d40 100644 --- a/app/views/projects/notes/_note.html.haml +++ b/app/views/projects/notes/_note.html.haml @@ -18,9 +18,9 @@ = time_ago_with_tooltip(note.created_at, placement: 'bottom', html_class: 'note-created-ago') .note-actions - access = note.project.team.human_max_access(note.author.id) - - if access + - if access and !note.system %span.note-role.hidden-xs= access - - if current_user + - if current_user and !note.system = link_to '#', title: 'Award Emoji', class: 'note-action-button note-emoji-button js-add-award js-note-emoji', data: { position: 'right' } do = icon('spinner spin') = icon('smile-o') -- cgit v1.2.1 From cbd6ca6985c1a7eefcfa5b3ca170fdf1865aee45 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Tue, 14 Jun 2016 16:07:57 +0800 Subject: Rename specific_for to available_for: Feedback from: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/4093#note_12413950 --- app/controllers/projects/runners_controller.rb | 2 +- app/models/ci/runner.rb | 2 +- spec/models/ci/runner_spec.rb | 14 +++++++------- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/controllers/projects/runners_controller.rb b/app/controllers/projects/runners_controller.rb index bc4c5bd4575..798d668f251 100644 --- a/app/controllers/projects/runners_controller.rb +++ b/app/controllers/projects/runners_controller.rb @@ -7,7 +7,7 @@ class Projects::RunnersController < Projects::ApplicationController def index @runners = project.runners.ordered @specific_runners = current_user.ci_authorized_runners. - specific_for(project).ordered.page(params[:page]).per(20) + available_for(project).ordered.page(params[:page]).per(20) @shared_runners = Ci::Runner.shared.active @shared_runners_count = @shared_runners.count(:all) end diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb index bb1cffdcae6..101817e1f56 100644 --- a/app/models/ci/runner.rb +++ b/app/models/ci/runner.rb @@ -26,7 +26,7 @@ module Ci .where("ci_runner_projects.gl_project_id = :project_id OR ci_runners.is_shared = true", project_id: project_id) end - scope :specific_for, ->(project) do + scope :available_for, ->(project) do # TODO: That `to_sql` is needed to workaround a weird Rails bug. # Without that, placeholders would miss one and couldn't match. where(locked: false). diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb index 9a6bc6b96c1..51e60ef8ada 100644 --- a/spec/models/ci/runner_spec.rb +++ b/spec/models/ci/runner_spec.rb @@ -259,7 +259,7 @@ describe Ci::Runner, models: true do end end - describe '.specific_for' do + describe '.available_for' do let(:runner) { create(:ci_runner) } let(:project) { create(:project) } let(:another_project) { create(:project) } @@ -274,13 +274,13 @@ describe Ci::Runner, models: true do end context 'should not give owned runner' do - subject { Ci::Runner.specific_for(project) } + subject { Ci::Runner.available_for(project) } it { is_expected.to be_empty } end context 'should not give shared runner' do - subject { Ci::Runner.specific_for(another_project) } + subject { Ci::Runner.available_for(another_project) } it { is_expected.to be_empty } end @@ -288,13 +288,13 @@ describe Ci::Runner, models: true do context 'with unlocked runner' do context 'should not give owned runner' do - subject { Ci::Runner.specific_for(project) } + subject { Ci::Runner.available_for(project) } it { is_expected.to be_empty } end context 'should give a specific runner' do - subject { Ci::Runner.specific_for(another_project) } + subject { Ci::Runner.available_for(another_project) } it { is_expected.to contain_exactly(runner) } end @@ -306,13 +306,13 @@ describe Ci::Runner, models: true do end context 'should not give owned runner' do - subject { Ci::Runner.specific_for(project) } + subject { Ci::Runner.available_for(project) } it { is_expected.to be_empty } end context 'should not give a locked runner' do - subject { Ci::Runner.specific_for(another_project) } + subject { Ci::Runner.available_for(another_project) } it { is_expected.to be_empty } end -- cgit v1.2.1 From 5f887344c033d9a5e07a784b56d048a1f33045ab Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Tue, 14 Jun 2016 16:36:54 +0800 Subject: Prefer Runner#assign_to instead of creating directly --- lib/api/runners.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/api/runners.rb b/lib/api/runners.rb index 4faba9dc87b..be92355d9a6 100644 --- a/lib/api/runners.rb +++ b/lib/api/runners.rb @@ -96,7 +96,7 @@ module API runner = get_runner(params[:runner_id]) authenticate_enable_runner!(runner) - Ci::RunnerProject.create(runner: runner, project: user_project) + runner.assign_to(user_project) present runner, with: Entities::Runner end -- cgit v1.2.1 From 1b03c5807fab6d2122e5a590cebfb2e7978a6659 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Tue, 14 Jun 2016 17:28:11 +0800 Subject: We're checking return value rather than rescuing exceptions --- app/models/ci/runner.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb index adb65292208..288e044fb86 100644 --- a/app/models/ci/runner.rb +++ b/app/models/ci/runner.rb @@ -56,7 +56,7 @@ module Ci def assign_to(project, current_user = nil) self.is_shared = false if shared? self.save - project.runner_projects.create!(runner_id: self.id) + project.runner_projects.create(runner_id: self.id) end def display_name -- cgit v1.2.1 From f74f42386029077d0f12ac407fc6ee39aaeeaf53 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Tue, 14 Jun 2016 22:17:01 +0800 Subject: Give 409 Conflict whenever the runner was already enabled --- CHANGELOG | 1 + app/models/ci/runner.rb | 2 +- lib/api/runners.rb | 7 +++++-- spec/requests/api/runners_spec.rb | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 3387394de5b..7abe41bc81d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -40,6 +40,7 @@ v 8.9.0 (unreleased) - Added artifacts:when to .gitlab-ci.yml - this requires GitLab Runner 1.3 - Todos will display target state if issuable target is 'Closed' or 'Merged' - Fix bug when sorting issues by milestone due date and filtering by two or more labels + - POST to API /projects/:id/runners/:runner_id would give 409 if the runner was already enabled for this project - Add support for using Yubikeys (U2F) for two-factor authentication - Link to blank group icon doesn't throw a 404 anymore - Remove 'main language' feature diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb index 288e044fb86..a5a55e0a2cd 100644 --- a/app/models/ci/runner.rb +++ b/app/models/ci/runner.rb @@ -56,7 +56,7 @@ module Ci def assign_to(project, current_user = nil) self.is_shared = false if shared? self.save - project.runner_projects.create(runner_id: self.id) + project.runner_projects.create(runner_id: self.id).persisted? end def display_name diff --git a/lib/api/runners.rb b/lib/api/runners.rb index be92355d9a6..7bea4386e03 100644 --- a/lib/api/runners.rb +++ b/lib/api/runners.rb @@ -96,9 +96,12 @@ module API runner = get_runner(params[:runner_id]) authenticate_enable_runner!(runner) - runner.assign_to(user_project) - present runner, with: Entities::Runner + if runner.assign_to(user_project) + present runner, with: Entities::Runner + else + conflict!("Runner was already enabled for this project") + end end # Disable project's runner diff --git a/spec/requests/api/runners_spec.rb b/spec/requests/api/runners_spec.rb index 73ae8ef631c..7aae0192fcb 100644 --- a/spec/requests/api/runners_spec.rb +++ b/spec/requests/api/runners_spec.rb @@ -375,7 +375,7 @@ describe API::Runners, api: true do expect do post api("/projects/#{project.id}/runners", user), runner_id: specific_runner.id end.to change{ project.runners.count }.by(0) - expect(response.status).to eq(201) + expect(response.status).to eq(409) end it 'should not enable shared runner' do -- cgit v1.2.1 From 1b8f52d9206bdf19c0dde04505c4c0b1cf46cfbe Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Tue, 14 Jun 2016 22:58:38 +0800 Subject: Avoid enabling locked runners. Give 403 in this case --- app/controllers/admin/runner_projects_controller.rb | 2 ++ app/controllers/projects/runner_projects_controller.rb | 1 + lib/api/runners.rb | 1 + spec/requests/api/runners_spec.rb | 16 ++++++++++++++-- 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/app/controllers/admin/runner_projects_controller.rb b/app/controllers/admin/runner_projects_controller.rb index d25619d94e0..29307aeab6d 100644 --- a/app/controllers/admin/runner_projects_controller.rb +++ b/app/controllers/admin/runner_projects_controller.rb @@ -9,6 +9,8 @@ class Admin::RunnerProjectsController < Admin::ApplicationController def create @runner = Ci::Runner.find(params[:runner_project][:runner_id]) + return head(403) if runner.is_shared? || runner.is_locked? + if @runner.assign_to(@project, current_user) redirect_to admin_runner_path(@runner) else diff --git a/app/controllers/projects/runner_projects_controller.rb b/app/controllers/projects/runner_projects_controller.rb index bedeb4a295c..4c013303269 100644 --- a/app/controllers/projects/runner_projects_controller.rb +++ b/app/controllers/projects/runner_projects_controller.rb @@ -6,6 +6,7 @@ class Projects::RunnerProjectsController < Projects::ApplicationController def create @runner = Ci::Runner.find(params[:runner_project][:runner_id]) + return head(403) if runner.is_shared? || runner.is_locked? return head(403) unless current_user.ci_authorized_runners.include?(@runner) path = runners_path(project) diff --git a/lib/api/runners.rb b/lib/api/runners.rb index 2d09b6193d9..3ae228d61d8 100644 --- a/lib/api/runners.rb +++ b/lib/api/runners.rb @@ -163,6 +163,7 @@ module API def authenticate_enable_runner!(runner) forbidden!("Runner is shared") if runner.is_shared? + forbidden!("Runner is locked") if runner.locked? return if current_user.is_admin? forbidden!("No access granted") unless user_can_access_runner?(runner) end diff --git a/spec/requests/api/runners_spec.rb b/spec/requests/api/runners_spec.rb index f4f9c417bbb..26dfa7bed05 100644 --- a/spec/requests/api/runners_spec.rb +++ b/spec/requests/api/runners_spec.rb @@ -362,11 +362,13 @@ describe API::Runners, api: true do describe 'POST /projects/:id/runners' do context 'authorized user' do - it 'should enable specific runner' do - specific_runner2 = create(:ci_runner).tap do |runner| + let(:specific_runner2) do + create(:ci_runner).tap do |runner| create(:ci_runner_project, runner: runner, project: project2) end + end + it 'should enable specific runner' do expect do post api("/projects/#{project.id}/runners", user), runner_id: specific_runner2.id end.to change{ project.runners.count }.by(+1) @@ -380,6 +382,16 @@ describe API::Runners, api: true do expect(response.status).to eq(201) end + it 'should not enable locked runner' do + specific_runner2.update(locked: true) + + expect do + post api("/projects/#{project.id}/runners", user), runner_id: specific_runner2.id + end.to change{ project.runners.count }.by(0) + + expect(response.status).to eq(403) + end + it 'should not enable shared runner' do post api("/projects/#{project.id}/runners", user), runner_id: shared_runner.id -- cgit v1.2.1 From 9cf45b058627f039040165519de9c2074dda141f Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Tue, 14 Jun 2016 23:11:43 +0800 Subject: Return the association and check it in controller instead: Feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/4641#note_12444891 --- app/controllers/admin/runner_projects_controller.rb | 4 +++- app/controllers/projects/runner_projects_controller.rb | 3 ++- app/models/ci/runner.rb | 2 +- lib/api/runners.rb | 4 +++- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/app/controllers/admin/runner_projects_controller.rb b/app/controllers/admin/runner_projects_controller.rb index 29307aeab6d..5383afdbd20 100644 --- a/app/controllers/admin/runner_projects_controller.rb +++ b/app/controllers/admin/runner_projects_controller.rb @@ -11,7 +11,9 @@ class Admin::RunnerProjectsController < Admin::ApplicationController return head(403) if runner.is_shared? || runner.is_locked? - if @runner.assign_to(@project, current_user) + runner_project = @runner.assign_to(@project, current_user) + + if runner_project.persisted? redirect_to admin_runner_path(@runner) else redirect_to admin_runner_path(@runner), alert: 'Failed adding runner to project' diff --git a/app/controllers/projects/runner_projects_controller.rb b/app/controllers/projects/runner_projects_controller.rb index 4c013303269..2413e583d7b 100644 --- a/app/controllers/projects/runner_projects_controller.rb +++ b/app/controllers/projects/runner_projects_controller.rb @@ -10,8 +10,9 @@ class Projects::RunnerProjectsController < Projects::ApplicationController return head(403) unless current_user.ci_authorized_runners.include?(@runner) path = runners_path(project) + runner_project = @runner.assign_to(project, current_user) - if @runner.assign_to(project, current_user) + if runner_project.persisted? redirect_to path else redirect_to path, alert: 'Failed adding runner to project' diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb index df343fc957a..8149929f492 100644 --- a/app/models/ci/runner.rb +++ b/app/models/ci/runner.rb @@ -63,7 +63,7 @@ module Ci def assign_to(project, current_user = nil) self.is_shared = false if shared? self.save - project.runner_projects.create(runner_id: self.id).persisted? + project.runner_projects.create(runner_id: self.id) end def display_name diff --git a/lib/api/runners.rb b/lib/api/runners.rb index 2c2610fc2e7..ecc8f2fc5a2 100644 --- a/lib/api/runners.rb +++ b/lib/api/runners.rb @@ -97,7 +97,9 @@ module API runner = get_runner(params[:runner_id]) authenticate_enable_runner!(runner) - if runner.assign_to(user_project) + runner_project = runner.assign_to(user_project) + + if runner_project.persisted? present runner, with: Entities::Runner else conflict!("Runner was already enabled for this project") -- cgit v1.2.1 From c866b906e67d42d9ad9537e8a6d6a254c3f74d8b Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Wed, 15 Jun 2016 17:29:07 +0800 Subject: Fix typo. It's ivar and the column was called locked --- app/controllers/projects/runner_projects_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/projects/runner_projects_controller.rb b/app/controllers/projects/runner_projects_controller.rb index 2413e583d7b..dc1a18f8d42 100644 --- a/app/controllers/projects/runner_projects_controller.rb +++ b/app/controllers/projects/runner_projects_controller.rb @@ -6,7 +6,7 @@ class Projects::RunnerProjectsController < Projects::ApplicationController def create @runner = Ci::Runner.find(params[:runner_project][:runner_id]) - return head(403) if runner.is_shared? || runner.is_locked? + return head(403) if @runner.is_shared? || @runner.locked? return head(403) unless current_user.ci_authorized_runners.include?(@runner) path = runners_path(project) -- cgit v1.2.1 From cd3f112f88c2362bb64961e52e6272314287a80b Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Wed, 15 Jun 2016 17:34:44 +0800 Subject: Adopt the rename from ci_commits to ci_pipelines --- spec/factories/ci/commits.rb | 49 ------------------------------------------ spec/factories/ci/pipelines.rb | 49 ++++++++++++++++++++++++++++++++++++++++++ spec/models/ci/runner_spec.rb | 4 ++-- 3 files changed, 51 insertions(+), 51 deletions(-) delete mode 100644 spec/factories/ci/commits.rb create mode 100644 spec/factories/ci/pipelines.rb diff --git a/spec/factories/ci/commits.rb b/spec/factories/ci/commits.rb deleted file mode 100644 index a039bef6f3c..00000000000 --- a/spec/factories/ci/commits.rb +++ /dev/null @@ -1,49 +0,0 @@ -# == Schema Information -# -# Table name: commits -# -# id :integer not null, primary key -# project_id :integer -# ref :string(255) -# sha :string(255) -# before_sha :string(255) -# push_data :text -# created_at :datetime -# updated_at :datetime -# tag :boolean default(FALSE) -# yaml_errors :text -# committed_at :datetime -# gl_project_id :integer -# - -FactoryGirl.define do - factory :ci_empty_pipeline, class: Ci::Pipeline do - sha '97de212e80737a608d939f648d959671fb0a0142' - - project factory: :empty_project - - factory :ci_pipeline_without_jobs do - after(:build) do |commit| - allow(commit).to receive(:ci_yaml_file) { YAML.dump({}) } - end - end - - factory :ci_pipeline_with_one_job do - after(:build) do |commit| - allow(commit).to receive(:ci_yaml_file) { YAML.dump({ rspec: { script: "ls" } }) } - end - end - - factory :ci_pipeline_with_two_job do - after(:build) do |commit| - allow(commit).to receive(:ci_yaml_file) { YAML.dump({ rspec: { script: "ls" }, spinach: { script: "ls" } }) } - end - end - - factory :ci_pipeline do - after(:build) do |commit| - allow(commit).to receive(:ci_yaml_file) { File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml')) } - end - end - end -end diff --git a/spec/factories/ci/pipelines.rb b/spec/factories/ci/pipelines.rb new file mode 100644 index 00000000000..a039bef6f3c --- /dev/null +++ b/spec/factories/ci/pipelines.rb @@ -0,0 +1,49 @@ +# == Schema Information +# +# Table name: commits +# +# id :integer not null, primary key +# project_id :integer +# ref :string(255) +# sha :string(255) +# before_sha :string(255) +# push_data :text +# created_at :datetime +# updated_at :datetime +# tag :boolean default(FALSE) +# yaml_errors :text +# committed_at :datetime +# gl_project_id :integer +# + +FactoryGirl.define do + factory :ci_empty_pipeline, class: Ci::Pipeline do + sha '97de212e80737a608d939f648d959671fb0a0142' + + project factory: :empty_project + + factory :ci_pipeline_without_jobs do + after(:build) do |commit| + allow(commit).to receive(:ci_yaml_file) { YAML.dump({}) } + end + end + + factory :ci_pipeline_with_one_job do + after(:build) do |commit| + allow(commit).to receive(:ci_yaml_file) { YAML.dump({ rspec: { script: "ls" } }) } + end + end + + factory :ci_pipeline_with_two_job do + after(:build) do |commit| + allow(commit).to receive(:ci_yaml_file) { YAML.dump({ rspec: { script: "ls" }, spinach: { script: "ls" } }) } + end + end + + factory :ci_pipeline do + after(:build) do |commit| + allow(commit).to receive(:ci_yaml_file) { File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml')) } + end + end + end +end diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb index 51e60ef8ada..c3638bf407f 100644 --- a/spec/models/ci/runner_spec.rb +++ b/spec/models/ci/runner_spec.rb @@ -92,8 +92,8 @@ describe Ci::Runner, models: true do describe '#can_pick?' do let(:project) { create(:project) } - let(:commit) { create(:ci_commit, project: project) } - let(:build) { create(:ci_build, commit: commit) } + let(:pipeline) { create(:ci_pipeline, project: project) } + let(:build) { create(:ci_build, pipeline: pipeline) } let(:runner) { create(:ci_runner) } before do -- cgit v1.2.1 From 5d76c2553898382531889f001a506eaafcaea56d Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Wed, 15 Jun 2016 19:05:39 +0800 Subject: Use font awesome instead of Unicode. Feedback from: https://gitlab.com/gitlab-org/gitlab-ce/commit/53121601f38155e926eed300160f79dd4bc0768b#note_12465224 --- app/views/projects/runners/_runner.html.haml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/views/projects/runners/_runner.html.haml b/app/views/projects/runners/_runner.html.haml index 08389528dc9..fbd94c34591 100644 --- a/app/views/projects/runners/_runner.html.haml +++ b/app/views/projects/runners/_runner.html.haml @@ -5,7 +5,8 @@ - if @runners.include?(runner) = link_to runner.short_sha, runner_path(runner) - if runner.locked? - %small{title: 'Exclusive to this project'} 🔒 + %small{title: 'Exclusive to this project'} + = icon('lock') %small = link_to edit_namespace_project_runner_path(@project.namespace, @project, runner) do %i.fa.fa-edit.btn -- cgit v1.2.1 From 33684eef83671bb0e551adaebf1425ef4d4bdff9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Wed, 15 Jun 2016 19:04:24 +0200 Subject: Add documentation for the 'request access to project' feature MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémy Coutable --- doc/workflow/add-user/add-user.md | 22 +++++++++++++++++++++ .../add-user/img/access_requests_management.png | Bin 0 -> 15105 bytes .../add-user/img/request_access_button.png | Bin 0 -> 36588 bytes .../img/withdraw_access_request_button.png | Bin 0 -> 37960 bytes 4 files changed, 22 insertions(+) create mode 100644 doc/workflow/add-user/img/access_requests_management.png create mode 100644 doc/workflow/add-user/img/request_access_button.png create mode 100644 doc/workflow/add-user/img/withdraw_access_request_button.png diff --git a/doc/workflow/add-user/add-user.md b/doc/workflow/add-user/add-user.md index fffa0aba57f..040a713e422 100644 --- a/doc/workflow/add-user/add-user.md +++ b/doc/workflow/add-user/add-user.md @@ -87,3 +87,25 @@ invitation, change their access level or even delete them. Once the user accepts the invitation, they will be prompted to create a new GitLab account using the same e-mail address the invitation was sent to. + +## Request access to a project + +As a user, you can request to be a member of a project. Go to the project you'd +like to be a member of, and click the **Request Access** button on the right +side of your screen. + +![Request access button](img/request_access_button.png) + +--- + +Project owners & masters will be notified of your request and will be able to approve or +decline it on the members page. + +![Manage access requests](img/access_requests_management.png) + +--- + +If you change your mind before your request is approved, just click the +**Withdraw Access Request** button. + +![Withdraw access request button](img/withdraw_access_request_button.png) diff --git a/doc/workflow/add-user/img/access_requests_management.png b/doc/workflow/add-user/img/access_requests_management.png new file mode 100644 index 00000000000..e9641cb4f85 Binary files /dev/null and b/doc/workflow/add-user/img/access_requests_management.png differ diff --git a/doc/workflow/add-user/img/request_access_button.png b/doc/workflow/add-user/img/request_access_button.png new file mode 100644 index 00000000000..984d640b0f0 Binary files /dev/null and b/doc/workflow/add-user/img/request_access_button.png differ diff --git a/doc/workflow/add-user/img/withdraw_access_request_button.png b/doc/workflow/add-user/img/withdraw_access_request_button.png new file mode 100644 index 00000000000..ff54a0e4384 Binary files /dev/null and b/doc/workflow/add-user/img/withdraw_access_request_button.png differ -- cgit v1.2.1 From 152af3895e61e55cda5c7bf425c4be2019192ed6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Wed, 15 Jun 2016 19:14:53 +0200 Subject: Add documentation for the 'request access to group' feature MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémy Coutable --- doc/workflow/groups.md | 22 +++++++++++++++++++++ doc/workflow/groups/access_requests_management.png | Bin 0 -> 15193 bytes doc/workflow/groups/request_access_button.png | Bin 0 -> 30470 bytes .../groups/withdraw_access_request_button.png | Bin 0 -> 31681 bytes 4 files changed, 22 insertions(+) create mode 100644 doc/workflow/groups/access_requests_management.png create mode 100644 doc/workflow/groups/request_access_button.png create mode 100644 doc/workflow/groups/withdraw_access_request_button.png diff --git a/doc/workflow/groups.md b/doc/workflow/groups.md index 34ada1774d8..1a316e80976 100644 --- a/doc/workflow/groups.md +++ b/doc/workflow/groups.md @@ -51,6 +51,28 @@ If necessary, you can increase the access level of an individual user for a spec ![Barry effectively has 'Master' access to GitLab CI now](groups/override_access_level.png) +## Request access to a group + +As a user, you can request to be a member of a group. Go to the group you'd +like to be a member of, and click the **Request Access** button on the right +side of your screen. + +![Request access button](groups/request_access_button.png) + +--- + +Group owners & masters will be notified of your request and will be able to approve or +decline it on the members page. + +![Manage access requests](groups/access_requests_management.png) + +--- + +If you change your mind before your request is approved, just click the +**Withdraw Access Request** button. + +![Withdraw access request button](groups/withdraw_access_request_button.png) + ## Managing group memberships via LDAP In GitLab Enterprise Edition it is possible to manage GitLab group memberships using LDAP groups. diff --git a/doc/workflow/groups/access_requests_management.png b/doc/workflow/groups/access_requests_management.png new file mode 100644 index 00000000000..ffede8e9bd6 Binary files /dev/null and b/doc/workflow/groups/access_requests_management.png differ diff --git a/doc/workflow/groups/request_access_button.png b/doc/workflow/groups/request_access_button.png new file mode 100644 index 00000000000..ff0ac8747a7 Binary files /dev/null and b/doc/workflow/groups/request_access_button.png differ diff --git a/doc/workflow/groups/withdraw_access_request_button.png b/doc/workflow/groups/withdraw_access_request_button.png new file mode 100644 index 00000000000..99d7a326ed8 Binary files /dev/null and b/doc/workflow/groups/withdraw_access_request_button.png differ -- cgit v1.2.1 From 4869bdf793f2f28064f1f8b4a3cdf710681e6970 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Wed, 15 Jun 2016 19:15:12 +0200 Subject: Update images for the 'Project users' documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémy Coutable --- doc/workflow/add-user/add-user.md | 2 +- doc/workflow/add-user/img/add_user_email_accept.png | Bin 10833 -> 22961 bytes doc/workflow/add-user/img/add_user_email_ready.png | Bin 16177 -> 40305 bytes doc/workflow/add-user/img/add_user_email_search.png | Bin 15889 -> 45884 bytes .../add-user/img/add_user_give_permissions.png | Bin 22089 -> 56480 bytes ...add_user_import_members_from_another_project.png | Bin 18897 -> 38874 bytes .../add-user/img/add_user_imported_members.png | Bin 23897 -> 37873 bytes doc/workflow/add-user/img/add_user_list_members.png | Bin 15732 -> 24427 bytes doc/workflow/add-user/img/add_user_members_menu.png | Bin 8295 -> 42319 bytes .../add-user/img/add_user_search_people.png | Bin 13518 -> 39941 bytes 10 files changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/workflow/add-user/add-user.md b/doc/workflow/add-user/add-user.md index 040a713e422..4b551130255 100644 --- a/doc/workflow/add-user/add-user.md +++ b/doc/workflow/add-user/add-user.md @@ -8,7 +8,7 @@ You should have `master` or `owner` permissions to add or import a new user to your project. The first step to add or import a user, go to your project and click on -**Members** on the left side of your screen. +**Members** in the drop-down menu on the right side of your screen. ![Members](img/add_user_members_menu.png) diff --git a/doc/workflow/add-user/img/add_user_email_accept.png b/doc/workflow/add-user/img/add_user_email_accept.png index 910affc9659..18aabf93d50 100644 Binary files a/doc/workflow/add-user/img/add_user_email_accept.png and b/doc/workflow/add-user/img/add_user_email_accept.png differ diff --git a/doc/workflow/add-user/img/add_user_email_ready.png b/doc/workflow/add-user/img/add_user_email_ready.png index 5f02ce89b3e..385d64330c0 100644 Binary files a/doc/workflow/add-user/img/add_user_email_ready.png and b/doc/workflow/add-user/img/add_user_email_ready.png differ diff --git a/doc/workflow/add-user/img/add_user_email_search.png b/doc/workflow/add-user/img/add_user_email_search.png index 140979fbe13..84741edbca4 100644 Binary files a/doc/workflow/add-user/img/add_user_email_search.png and b/doc/workflow/add-user/img/add_user_email_search.png differ diff --git a/doc/workflow/add-user/img/add_user_give_permissions.png b/doc/workflow/add-user/img/add_user_give_permissions.png index 8ef9156c8d5..7e580384e54 100644 Binary files a/doc/workflow/add-user/img/add_user_give_permissions.png and b/doc/workflow/add-user/img/add_user_give_permissions.png differ diff --git a/doc/workflow/add-user/img/add_user_import_members_from_another_project.png b/doc/workflow/add-user/img/add_user_import_members_from_another_project.png index 5770d5cf0c4..8dbd73a5bc8 100644 Binary files a/doc/workflow/add-user/img/add_user_import_members_from_another_project.png and b/doc/workflow/add-user/img/add_user_import_members_from_another_project.png differ diff --git a/doc/workflow/add-user/img/add_user_imported_members.png b/doc/workflow/add-user/img/add_user_imported_members.png index dea4b3f40ad..abac1f59c02 100644 Binary files a/doc/workflow/add-user/img/add_user_imported_members.png and b/doc/workflow/add-user/img/add_user_imported_members.png differ diff --git a/doc/workflow/add-user/img/add_user_list_members.png b/doc/workflow/add-user/img/add_user_list_members.png index 7daa6ca7d9e..e17d88c6f5f 100644 Binary files a/doc/workflow/add-user/img/add_user_list_members.png and b/doc/workflow/add-user/img/add_user_list_members.png differ diff --git a/doc/workflow/add-user/img/add_user_members_menu.png b/doc/workflow/add-user/img/add_user_members_menu.png index f1797b95f67..ec5d39f402d 100644 Binary files a/doc/workflow/add-user/img/add_user_members_menu.png and b/doc/workflow/add-user/img/add_user_members_menu.png differ diff --git a/doc/workflow/add-user/img/add_user_search_people.png b/doc/workflow/add-user/img/add_user_search_people.png index 5ac10ce80d4..eaa062376f4 100644 Binary files a/doc/workflow/add-user/img/add_user_search_people.png and b/doc/workflow/add-user/img/add_user_search_people.png differ -- cgit v1.2.1 From 4852acef9256ee60d76564ff7509dc72e016a863 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 16 Jun 2016 23:20:13 +0800 Subject: Use FIXME instead, feedback from: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/4093/diffs#note_12501400 --- app/models/ci/runner.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb index 8149929f492..fa5cf03baec 100644 --- a/app/models/ci/runner.rb +++ b/app/models/ci/runner.rb @@ -27,8 +27,8 @@ module Ci end scope :available_for, ->(project) do - # TODO: That `to_sql` is needed to workaround a weird Rails bug. - # Without that, placeholders would miss one and couldn't match. + # FIXME: That `to_sql` is needed to workaround a weird Rails bug. + # Without that, placeholders would miss one and couldn't match. where(locked: false). where.not("id IN (#{project.runners.select(:id).to_sql})").specific end -- cgit v1.2.1 From ae0e1e402e1f754943ad200958f85bc90ca82b52 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 16 Jun 2016 23:26:49 +0800 Subject: blank line between setup and expectation, feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/4093/diffs#note_12501266 and: https://robots.thoughtbot.com/four-phase-test --- spec/models/ci/runner_spec.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb index c3638bf407f..2b21c3561db 100644 --- a/spec/models/ci/runner_spec.rb +++ b/spec/models/ci/runner_spec.rb @@ -107,6 +107,7 @@ describe Ci::Runner, models: true do it 'cannot handle build with tags' do build.tag_list = ['aa'] + expect(runner.can_pick?(build)).to be_falsey end end @@ -119,11 +120,13 @@ describe Ci::Runner, models: true do shared_examples 'tagged build picker' do it 'can handle build with matching tags' do build.tag_list = ['bb'] + expect(runner.can_pick?(build)).to be_truthy end it 'cannot handle build without matching tags' do build.tag_list = ['aa'] + expect(runner.can_pick?(build)).to be_falsey end end @@ -172,6 +175,7 @@ describe Ci::Runner, models: true do it 'cannot handle it for builds without matching tags' do build.tag_list = ['aa'] + expect(runner.can_pick?(build)).to be_falsey end end -- cgit v1.2.1 From 314befded7e30981bf858e8e4aebd3df7f8d7d54 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 16 Jun 2016 23:31:54 +0800 Subject: Fix typo. It's ivar and the column was called locked Again! For admin. --- app/controllers/admin/runner_projects_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/admin/runner_projects_controller.rb b/app/controllers/admin/runner_projects_controller.rb index 5383afdbd20..20f30e70c8a 100644 --- a/app/controllers/admin/runner_projects_controller.rb +++ b/app/controllers/admin/runner_projects_controller.rb @@ -9,7 +9,7 @@ class Admin::RunnerProjectsController < Admin::ApplicationController def create @runner = Ci::Runner.find(params[:runner_project][:runner_id]) - return head(403) if runner.is_shared? || runner.is_locked? + return head(403) if @runner.is_shared? || @runner.locked? runner_project = @runner.assign_to(@project, current_user) -- cgit v1.2.1 From 8a0aeab846f5c97ba56d34644834e38f2378c7ce Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 16 Jun 2016 23:33:53 +0800 Subject: Use active tense, feedback from: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/4093#note_12501303 --- spec/models/ci/runner_spec.rb | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb index 2b21c3561db..c7248ef1384 100644 --- a/spec/models/ci/runner_spec.rb +++ b/spec/models/ci/runner_spec.rb @@ -20,17 +20,17 @@ describe Ci::Runner, models: true do end describe '#display_name' do - it 'should return the description if it has a value' do + it 'returns the description if it has a value' do runner = FactoryGirl.build(:ci_runner, description: 'Linux/Ruby-1.9.3-p448') expect(runner.display_name).to eq 'Linux/Ruby-1.9.3-p448' end - it 'should return the token if it does not have a description' do + it 'returns the token if it does not have a description' do runner = FactoryGirl.create(:ci_runner) expect(runner.display_name).to eq runner.description end - it 'should return the token if the description is an empty string' do + it 'returns the token if the description is an empty string' do runner = FactoryGirl.build(:ci_runner, description: '', token: 'token') expect(runner.display_name).to eq runner.token end @@ -277,13 +277,13 @@ describe Ci::Runner, models: true do runner.update(is_shared: true) end - context 'should not give owned runner' do + context 'does not give owned runner' do subject { Ci::Runner.available_for(project) } it { is_expected.to be_empty } end - context 'should not give shared runner' do + context 'does not give shared runner' do subject { Ci::Runner.available_for(another_project) } it { is_expected.to be_empty } @@ -291,13 +291,13 @@ describe Ci::Runner, models: true do end context 'with unlocked runner' do - context 'should not give owned runner' do + context 'does not give owned runner' do subject { Ci::Runner.available_for(project) } it { is_expected.to be_empty } end - context 'should give a specific runner' do + context 'does give a specific runner' do subject { Ci::Runner.available_for(another_project) } it { is_expected.to contain_exactly(runner) } @@ -309,13 +309,13 @@ describe Ci::Runner, models: true do runner.update(locked: true) end - context 'should not give owned runner' do + context 'does not give owned runner' do subject { Ci::Runner.available_for(project) } it { is_expected.to be_empty } end - context 'should not give a locked runner' do + context 'does not give a locked runner' do subject { Ci::Runner.available_for(another_project) } it { is_expected.to be_empty } -- cgit v1.2.1 From 4a7816fd297a9f1bd23ead6c0690c6fd0ab6b9c3 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 16 Jun 2016 17:25:18 +0100 Subject: Fixes font weight of commit id on view file button --- app/assets/stylesheets/pages/diff.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/assets/stylesheets/pages/diff.scss b/app/assets/stylesheets/pages/diff.scss index 1a7d5f9666e..927c8d08134 100644 --- a/app/assets/stylesheets/pages/diff.scss +++ b/app/assets/stylesheets/pages/diff.scss @@ -4,6 +4,10 @@ margin-bottom: $gl-padding; border-radius: 3px; + .commit-short-id { + font-weight: 400; + } + .diff-header { position: relative; background: $background-color; -- cgit v1.2.1 From fb2b1ae10973f1befdf234471b25f1d165898480 Mon Sep 17 00:00:00 2001 From: Mark Pundsack Date: Thu, 16 Jun 2016 17:37:31 -0700 Subject: Tweak grammar --- doc/ci/yaml/README.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md index 9c98f9c98c6..4682d88d8bd 100644 --- a/doc/ci/yaml/README.md +++ b/doc/ci/yaml/README.md @@ -530,14 +530,18 @@ The above script will: ### environment >**Note:** -Introduced in GitLab v8.9.0. +Introduced in GitLab 8.9. -`environment` is used to define that job does deployment to specific environment. -This allows to easily track all deployments to your environments straight from GitLab. +`environment` is used to define that a job deploys to a specific environment. +This allows easy tracking of all deployments to your environments straight from +GitLab. -If `environment` is specified and no environment under that name does exist a new one will be created automatically. +If `environment` is specified and no environment under that name exists, a new +one will be created automatically. -The `environment` name must contain only letters, digits, '-' and '_'. +The `environment` name must contain only letters, digits, '-' and '_'. Common +names are `qa`, `staging`, and `production`, but you can use whatever name works +with your workflow. --- @@ -550,7 +554,8 @@ deploy to production: environment: production ``` -The `deploy to production` job will be marked as doing deployment to `production` environment. +The `deploy to production` job will be marked as doing deployment to +`production` environment. ### artifacts -- cgit v1.2.1 From 5f98c9962c46aca62d9872748b6257bbaae01c1f Mon Sep 17 00:00:00 2001 From: Mark Pundsack Date: Thu, 16 Jun 2016 17:37:49 -0700 Subject: Document environments and deployments --- doc/ci/README.md | 1 + doc/ci/environments.md | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 doc/ci/environments.md diff --git a/doc/ci/README.md b/doc/ci/README.md index ef72df97ce6..5a1cb5319c6 100644 --- a/doc/ci/README.md +++ b/doc/ci/README.md @@ -5,6 +5,7 @@ - [Get started with GitLab CI](quick_start/README.md) - [CI examples for various languages](examples/README.md) - [Learn how to enable or disable GitLab CI](enable_or_disable_ci.md) +- [Environments and deployments](environments.md) - [Learn how `.gitlab-ci.yml` works](yaml/README.md) - [Configure a Runner, the application that runs your builds](runners/README.md) - [Use Docker images with GitLab Runner](docker/using_docker_images.md) diff --git a/doc/ci/environments.md b/doc/ci/environments.md new file mode 100644 index 00000000000..ee4c4c6025c --- /dev/null +++ b/doc/ci/environments.md @@ -0,0 +1,59 @@ +# Introduction to environments and deployments + +>**Note:** +Introduced in GitLab 8.9. + +## Environments + +Environments are places where code gets deployed, such as staging or production. +CI/CD [Pipelines] usually have one or more [jobs] that deploy to an environment. +Defining environments in a project's `.gitlab-ci.yml` lets developers track +[deployments] to these environments. + +## Deployments + +Deployments are created when [jobs] deploy versions of code to [environments]. + +## Defining environments + +>**Note:** +You can create and delete environments manually in the web interface, but we +recommend that you define your environments in `.gitlab-ci.yml` first, which +will automatically create environments for you after the first deploy. + +The `environment` is just a hint for GitLab that this job actually deploys to +this environment. Each time the job succeeds, a deployment is recorded, +remembering the git SHA and environment. + +Add something like this to your `.gitlab-ci.yml`: +``` +production: + stage: deploy + script: dpl... + environment: production +``` + +See full [documentation](yaml/README.md#environment). + +## Seeing environment status + +You can find the environment list under **Pipelines > Environments** for your +project. You'll see the git SHA and date of the last deployment to each +environment defined. + +>**Note:** +Only deploys that happen after your `.gitlab-ci.yml` is properly configured will +show up in the environments and deployments lists. + +## Seeing deployment history + +Clicking on an environment will show the history of deployments. + +>**Note:** +Only deploys that happen after your `.gitlab-ci.yml` is properly configured will +show up in the environments and deployments lists. + +[Pipelines]: quick_start/README.md +[jobs]: yaml/README.md#jobs +[environments]: #environments +[deployments]: #deployments -- cgit v1.2.1 From 846c659cda838b8df6b41381735627cba76c2a3e Mon Sep 17 00:00:00 2001 From: Mark Pundsack Date: Thu, 16 Jun 2016 17:39:17 -0700 Subject: Turn note into normal text --- doc/ci/environments.md | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/ci/environments.md b/doc/ci/environments.md index ee4c4c6025c..040379bb381 100644 --- a/doc/ci/environments.md +++ b/doc/ci/environments.md @@ -16,7 +16,6 @@ Deployments are created when [jobs] deploy versions of code to [environments]. ## Defining environments ->**Note:** You can create and delete environments manually in the web interface, but we recommend that you define your environments in `.gitlab-ci.yml` first, which will automatically create environments for you after the first deploy. -- cgit v1.2.1 From c252b52db76841965d7ec7d099bdec3a04a73c22 Mon Sep 17 00:00:00 2001 From: "Luke \"Jared\" Bennett" Date: Thu, 16 Jun 2016 20:59:17 +0100 Subject: Started fixing, not found dropdown button yet.... FINALLY, found it! Fixed --- app/assets/stylesheets/pages/merge_requests.scss | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss index 53bff508c72..4985aa35823 100644 --- a/app/assets/stylesheets/pages/merge_requests.scss +++ b/app/assets/stylesheets/pages/merge_requests.scss @@ -119,7 +119,12 @@ margin-bottom: 0; } - @media (max-width: $screen-sm-max) { + .btn-grouped { + margin-left: 0; + margin-right: 7px; + } + + @media (max-width: $screen-xs-max) { h4 { font-size: 15px; } @@ -131,10 +136,14 @@ .btn, .btn-group, .accept-action { - width: 100%; margin-bottom: 4px; } + .accept-action { + width: 100%; + text-align: center; + } + .accept-control { width: 100%; text-align: center; @@ -282,7 +291,7 @@ margin-bottom: 0; } - @media (min-width: $screen-sm-min) { + @media (min-width: $screen-xs-min) { float: left; width: 50%; margin-bottom: 0; -- cgit v1.2.1 From 1022a1678b2b08fd226a5c88e4c472b8426de1c4 Mon Sep 17 00:00:00 2001 From: Sean McGivern Date: Fri, 17 Jun 2016 08:55:05 +0100 Subject: Limit push email diff size Limit push email diff size to 30 files or 150 KB, whichever comes first. --- CHANGELOG | 1 + lib/gitlab/email/message/repository_push.rb | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 0596ff37856..d43680c4ab2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -48,6 +48,7 @@ v 8.9.0 (unreleased) - Add `sha` parameter to MR merge API, to ensure only reviewed changes are merged - Don't allow MRs to be merged when commits were added since the last review / page load - Add DB index on users.state + - Limit email on push diff size to 30 files / 150 KB - Add rake task 'gitlab:db:configure' for conditionally seeding or migrating the database - Changed the Slack build message to use the singular duration if necessary (Aran Koning) - Fix race condition on merge when build succeeds diff --git a/lib/gitlab/email/message/repository_push.rb b/lib/gitlab/email/message/repository_push.rb index e2fee6b9f3e..047c77c6fc2 100644 --- a/lib/gitlab/email/message/repository_push.rb +++ b/lib/gitlab/email/message/repository_push.rb @@ -37,7 +37,7 @@ module Gitlab end def diffs - @diffs ||= (safe_diff_files(compare.diffs, diff_refs) if compare) + @diffs ||= (safe_diff_files(compare.diffs(max_files: 30), diff_refs) if compare) end def diffs_count -- cgit v1.2.1 From 59b5bfff6d43b949f940cc8ea2b00b7de2cda274 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 17 Jun 2016 10:01:57 +0100 Subject: Uses not when checking for system note --- app/views/projects/notes/_note.html.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml index 57050a87d40..c04d291412c 100644 --- a/app/views/projects/notes/_note.html.haml +++ b/app/views/projects/notes/_note.html.haml @@ -18,9 +18,9 @@ = time_ago_with_tooltip(note.created_at, placement: 'bottom', html_class: 'note-created-ago') .note-actions - access = note.project.team.human_max_access(note.author.id) - - if access and !note.system + - if access and not note.system %span.note-role.hidden-xs= access - - if current_user and !note.system + - if current_user and not note.system = link_to '#', title: 'Award Emoji', class: 'note-action-button note-emoji-button js-add-award js-note-emoji', data: { position: 'right' } do = icon('spinner spin') = icon('smile-o') -- cgit v1.2.1 From cd95389ac3151c9c3eb390f2adfd73678bb558d8 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 17 Jun 2016 10:06:17 +0100 Subject: Fixes font family of commit ID in diffs --- app/assets/stylesheets/pages/diff.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/app/assets/stylesheets/pages/diff.scss b/app/assets/stylesheets/pages/diff.scss index 927c8d08134..5286b73cc50 100644 --- a/app/assets/stylesheets/pages/diff.scss +++ b/app/assets/stylesheets/pages/diff.scss @@ -5,6 +5,7 @@ border-radius: 3px; .commit-short-id { + font-family: $regular_font; font-weight: 400; } -- cgit v1.2.1 From 27d2e12e69c5a7e0226b4b354ff880c939719d49 Mon Sep 17 00:00:00 2001 From: Chris Wright Date: Fri, 17 Jun 2016 09:59:12 +0000 Subject: Add some docs for Docker Registry configuration --- doc/administration/container_registry.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/doc/administration/container_registry.md b/doc/administration/container_registry.md index caf9a5bef2c..d21708d6f55 100644 --- a/doc/administration/container_registry.md +++ b/doc/administration/container_registry.md @@ -84,6 +84,17 @@ GitLab does not ship with a Registry init file. Hence, [restarting GitLab][resta will not restart the Registry should you modify its settings. Read the upstream documentation on how to achieve that. +The Docker Registry configuration will need `container_service` as the service and `https://gitlab.example.com/jwt/auth` as the realm: + +``` +auth: + token: + realm: https://gitlab.example.com/jwt/auth + service: container_registry + issuer: gitlab-issuer + rootcertbundle: /root/certs/certbundle +``` + ## Container Registry domain configuration There are two ways you can configure the Registry's external domain. -- cgit v1.2.1 From 21fd52bc5fed122a867e69f8b36639249ef2d9b0 Mon Sep 17 00:00:00 2001 From: Chris Wright Date: Fri, 17 Jun 2016 10:05:58 +0000 Subject: Oops ... Typo --- doc/administration/container_registry.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/administration/container_registry.md b/doc/administration/container_registry.md index d21708d6f55..39e43acbe2b 100644 --- a/doc/administration/container_registry.md +++ b/doc/administration/container_registry.md @@ -84,7 +84,7 @@ GitLab does not ship with a Registry init file. Hence, [restarting GitLab][resta will not restart the Registry should you modify its settings. Read the upstream documentation on how to achieve that. -The Docker Registry configuration will need `container_service` as the service and `https://gitlab.example.com/jwt/auth` as the realm: +The Docker Registry configuration will need `container_registry` as the service and `https://gitlab.example.com/jwt/auth` as the realm: ``` auth: -- cgit v1.2.1 From 0fd56975ea57c2c646034ab929f6839c6e7a6a02 Mon Sep 17 00:00:00 2001 From: Jacob Schatz Date: Thu, 26 May 2016 10:47:36 -0400 Subject: Initial markdown ez buttons --- app/assets/javascripts/lib/text_utility.js.coffee | 74 ++++++++++++++++++++++ app/assets/stylesheets/pages/note_form.scss | 4 ++ .../projects/merge_requests/_discussion.html.haml | 6 ++ app/views/projects/notes/_hints.html.haml | 9 +++ 4 files changed, 93 insertions(+) create mode 100644 app/assets/javascripts/lib/text_utility.js.coffee diff --git a/app/assets/javascripts/lib/text_utility.js.coffee b/app/assets/javascripts/lib/text_utility.js.coffee new file mode 100644 index 00000000000..830b5d6ec49 --- /dev/null +++ b/app/assets/javascripts/lib/text_utility.js.coffee @@ -0,0 +1,74 @@ +((w) -> + w.gl ?= {} + w.gl.text ?= {} + w.gl.text.undoManager ?= {} + + gl.text.replaceRange = (s, start, end, substitute) -> + s.substring(0, start) + substitute + s.substring(end); + + gl.text.wrap = (textArea, tag) -> + $textArea = $(textArea) + $textArea.focus() + textArea = $textArea.get(0) + selObj = window.getSelection() + selRange = selObj.getRangeAt(0) + text = $textArea.val() + replaceWith = @replaceRange( + text, + textArea.selectionStart, + textArea.selectionEnd, + (tag+selObj.toString()+tag)) + $textArea.data('old-val', text).val(replaceWith); + + gl.text.prepend = (textArea, tag) -> + $textArea = $(textArea) + $textArea.focus() + textArea = $textArea.get(0) + selObj = window.getSelection() + selRange = selObj.getRangeAt(0) + text = $textArea.val() + lineBreak = '\n' if textArea.selectionStart > 0 + console.log(textArea.selectionStart,lineBreak) + replaceWith = @replaceRange( + text, + textArea.selectionStart, + textArea.selectionEnd, + ("#{lineBreak}#{tag} #{selObj.toString()} \n") + ) + $textArea.data('old-val', text).val(replaceWith); + # $textArea.val(replaceWith) + + gl.text.undoManager.undo = () -> + + + gl.text.addListeners = () -> + self = @ + $('.js-md').on 'click', -> + $this = $(@) + if $this.data('md-wrap')? + self.wrap( + $this.closest('.md-area').find('textarea'), + $this.data('md-tag') + ) + else if $this.data('md-prepend')? + self.prepend( + $this.closest('.md-area').find('textarea'), + $this.data('md-tag') + ) + else + self.wrap( + $this.closest('.md-area').find('textarea'), + $this.data('md-tag') + ) + + $(window).on 'keydown', (e) -> + if e.ctrlKey or e.metaKey + if String.fromCharCode(e.which).toLowerCase() is 'z' and !e.shiftKey + e.preventDefault() + else if ((String.fromCharCode(e.which).toLowerCase() is 'z' and e.shiftKey) or (String.fromCharCode(e.which).toLowerCase() is 'y')) + e.preventDefault() + + gl.text.removeListeners = () -> + $('js-md.btn-bold').off() + +) window \ No newline at end of file diff --git a/app/assets/stylesheets/pages/note_form.scss b/app/assets/stylesheets/pages/note_form.scss index 577dddae741..245c07bf106 100644 --- a/app/assets/stylesheets/pages/note_form.scss +++ b/app/assets/stylesheets/pages/note_form.scss @@ -179,6 +179,10 @@ border-top: 1px solid $border-color; } +.md-helper { + padding-top: 10px; +} + .toolbar-button { padding: 0; background: none; diff --git a/app/views/projects/merge_requests/_discussion.html.haml b/app/views/projects/merge_requests/_discussion.html.haml index 393998f15b9..6b9185c4a07 100644 --- a/app/views/projects/merge_requests/_discussion.html.haml +++ b/app/views/projects/merge_requests/_discussion.html.haml @@ -6,3 +6,9 @@ = link_to 'Reopen merge request', merge_request_path(@merge_request, merge_request: {state_event: :reopen }), method: :put, class: "btn btn-nr btn-comment btn-grouped btn-reopen reopen-mr-link js-note-target-reopen", title: "Reopen merge request", data: {original_text: "Reopen merge request", alternative_text: "Comment & reopen merge request"} #notes= render "projects/notes/notes_with_form" + +:javascript + $(function(){ + gl.text.removeListeners(); + gl.text.addListeners(); + }) diff --git a/app/views/projects/notes/_hints.html.haml b/app/views/projects/notes/_hints.html.haml index 0b002043408..f26866468ce 100644 --- a/app/views/projects/notes/_hints.html.haml +++ b/app/views/projects/notes/_hints.html.haml @@ -6,3 +6,12 @@ %button.toolbar-button.markdown-selector{ type: 'button', tabindex: '-1' } = icon('file-image-o', class: 'toolbar-button-icon') Attach a file +.md-helper + %a.btn.btn-xs.js-md{ 'data-md-tag' => '**' } + =icon('bold fw') + %a.btn.btn-xs.js-md{ 'data-md-tag' => '*' } + =icon('italic fw') + %a.btn.btn-xs.js-md.js-list{ 'data-md-tag' => '*', 'data-md-prepend' => true } + =icon('list-ul fw') + %a.btn.btn-xs.js-md.js-list{ 'data-md-tag' => '1.', 'data-md-prepend' => true } + =icon('list-ol fw') \ No newline at end of file -- cgit v1.2.1 From 3d5b1c35d30542b7344dac426d1c2acaeabd9aca Mon Sep 17 00:00:00 2001 From: Jacob Schatz Date: Thu, 26 May 2016 10:47:36 -0400 Subject: Initial markdown ez buttons --- app/views/shared/issuable/_form.html.haml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml index c30bdb0ae91..974ccb6fadc 100644 --- a/app/views/shared/issuable/_form.html.haml +++ b/app/views/shared/issuable/_form.html.haml @@ -147,5 +147,4 @@ .pull-right - if current_user.can?(:"destroy_#{issuable.to_ability_name}", @project) = link_to 'Delete', polymorphic_path([@project.namespace.becomes(Namespace), @project, issuable]), data: { confirm: "#{issuable.class.name.titleize} will be removed! Are you sure?" }, - method: :delete, class: 'btn btn-danger btn-grouped' - = link_to 'Cancel', polymorphic_path([@project.namespace.becomes(Namespace), @project, issuable]), class: 'btn btn-grouped btn-cancel' + = link_to 'Cancel', polymorphic_path([@project.namespace.becomes(Namespace), @project, issuable]), class: 'btn btn-grouped btn-cancel' \ No newline at end of file -- cgit v1.2.1 From 3e7770aae17e30c4b6b89d3b1add2fa439ac97ac Mon Sep 17 00:00:00 2001 From: Jacob Schatz Date: Thu, 26 May 2016 22:10:01 -0400 Subject: Overwrite undo history --- app/assets/javascripts/lib/text_utility.js.coffee | 48 ++++++++++++++++++++-- app/views/projects/issues/_discussion.html.haml | 6 +++ .../projects/merge_requests/_discussion.html.haml | 2 +- 3 files changed, 51 insertions(+), 5 deletions(-) diff --git a/app/assets/javascripts/lib/text_utility.js.coffee b/app/assets/javascripts/lib/text_utility.js.coffee index 830b5d6ec49..7a115a6d8b5 100644 --- a/app/assets/javascripts/lib/text_utility.js.coffee +++ b/app/assets/javascripts/lib/text_utility.js.coffee @@ -3,11 +3,14 @@ w.gl.text ?= {} w.gl.text.undoManager ?= {} + gl.text.randomString = -> Math.random().toString(36).substring(7) + gl.text.replaceRange = (s, start, end, substitute) -> s.substring(0, start) + substitute + s.substring(end); gl.text.wrap = (textArea, tag) -> $textArea = $(textArea) + oldVal = $textArea.val() $textArea.focus() textArea = $textArea.get(0) selObj = window.getSelection() @@ -18,10 +21,12 @@ textArea.selectionStart, textArea.selectionEnd, (tag+selObj.toString()+tag)) - $textArea.data('old-val', text).val(replaceWith); + $textArea.data('old-val', text).val(replaceWith) + gl.text.undoManager.addUndo(oldVal, $textArea.val()) gl.text.prepend = (textArea, tag) -> $textArea = $(textArea) + oldVal = $textArea.val() $textArea.focus() textArea = $textArea.get(0) selObj = window.getSelection() @@ -36,12 +41,45 @@ ("#{lineBreak}#{tag} #{selObj.toString()} \n") ) $textArea.data('old-val', text).val(replaceWith); - # $textArea.val(replaceWith) + gl.text.undoManager.addUndo(oldVal, $textArea.val()) + + gl.text.undoManager.history = {} + gl.text.undoManager.undoHistory = {} + + gl.text.undoManager.addUniqueIfNotExists = ($ta) -> + unique = $ta.attr('data-unique') + if not unique? + unique = gl.text.randomString() + $ta.attr('data-unique', unique) + gl.text.undoManager.history[unique] = [] + gl.text.undoManager.undoHistory[unique] = [] + unique + + gl.text.undoManager.addUndo = (oldVal, newVal) -> + $thisTextarea = $('textarea:focus') + unique = gl.text.undoManager.addUniqueIfNotExists($thisTextarea) + gl.text.undoManager.history[unique].push({ + oldVal: oldVal, + newVal: newVal + }) gl.text.undoManager.undo = () -> - + $thisTextarea = $('textarea:focus') + unique = gl.text.undoManager.addUniqueIfNotExists($thisTextarea) + if not gl.text.undoManager.history[unique].length + return + latestChange = gl.text.undoManager.history[unique].pop() + gl.text.undoManager.undoHistory[unique].push(latestChange) + $thisTextarea.val(latestChange.oldVal) + + gl.text.undoManager.redo = () -> + $thisTextarea = $('textarea:focus') + unique = gl.text.undoManager.addUniqueIfNotExists($thisTextarea) + if not gl.text.undoManager.undoHistory[unique].length + return gl.text.addListeners = () -> + console.log('addListeners') self = @ $('.js-md').on 'click', -> $this = $(@) @@ -61,12 +99,14 @@ $this.data('md-tag') ) - $(window).on 'keydown', (e) -> + $(window).on 'keydown', (e) => if e.ctrlKey or e.metaKey if String.fromCharCode(e.which).toLowerCase() is 'z' and !e.shiftKey e.preventDefault() + self.undoManager.undo() else if ((String.fromCharCode(e.which).toLowerCase() is 'z' and e.shiftKey) or (String.fromCharCode(e.which).toLowerCase() is 'y')) e.preventDefault() + self.undoManager.redo() gl.text.removeListeners = () -> $('js-md.btn-bold').off() diff --git a/app/views/projects/issues/_discussion.html.haml b/app/views/projects/issues/_discussion.html.haml index b151393abab..8ed0e3d7e1d 100644 --- a/app/views/projects/issues/_discussion.html.haml +++ b/app/views/projects/issues/_discussion.html.haml @@ -5,3 +5,9 @@ #notes = render 'projects/notes/notes_with_form' + +:javascript + $(function(){ + gl.text.removeListeners(); + gl.text.addListeners(); + }) \ No newline at end of file diff --git a/app/views/projects/merge_requests/_discussion.html.haml b/app/views/projects/merge_requests/_discussion.html.haml index 6b9185c4a07..c8b6a25952b 100644 --- a/app/views/projects/merge_requests/_discussion.html.haml +++ b/app/views/projects/merge_requests/_discussion.html.haml @@ -11,4 +11,4 @@ $(function(){ gl.text.removeListeners(); gl.text.addListeners(); - }) + }) \ No newline at end of file -- cgit v1.2.1 From ad1d55eb9c7cbf70d5a3613259c9738d8e591110 Mon Sep 17 00:00:00 2001 From: Jacob Schatz Date: Thu, 26 May 2016 22:12:05 -0400 Subject: Add redo state --- app/assets/javascripts/lib/text_utility.js.coffee | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/assets/javascripts/lib/text_utility.js.coffee b/app/assets/javascripts/lib/text_utility.js.coffee index 7a115a6d8b5..75e398ddaeb 100644 --- a/app/assets/javascripts/lib/text_utility.js.coffee +++ b/app/assets/javascripts/lib/text_utility.js.coffee @@ -77,6 +77,9 @@ unique = gl.text.undoManager.addUniqueIfNotExists($thisTextarea) if not gl.text.undoManager.undoHistory[unique].length return + latestUndo = gl.text.undoManager.undoHistory[unique].pop() + gl.text.undoManager.history[unique].push(latestUndo) + $thisTextarea.val(latestUndo.newVal) gl.text.addListeners = () -> console.log('addListeners') -- cgit v1.2.1 From 4ba2632c812a961970aae31f11bf8276d5e8fb39 Mon Sep 17 00:00:00 2001 From: Jacob Schatz Date: Thu, 26 May 2016 22:24:08 -0400 Subject: Add undo history once they click the enter or backspace key --- app/assets/javascripts/lib/text_utility.js.coffee | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/lib/text_utility.js.coffee b/app/assets/javascripts/lib/text_utility.js.coffee index 75e398ddaeb..86488d735ef 100644 --- a/app/assets/javascripts/lib/text_utility.js.coffee +++ b/app/assets/javascripts/lib/text_utility.js.coffee @@ -1,4 +1,4 @@ -((w) -> +((w) -> w.gl ?= {} w.gl.text ?= {} w.gl.text.undoManager ?= {} @@ -102,7 +102,10 @@ $this.data('md-tag') ) + gl.text._previousState = null + $(window).on 'keydown', (e) => + $thisTextarea = $('textarea:focus') if e.ctrlKey or e.metaKey if String.fromCharCode(e.which).toLowerCase() is 'z' and !e.shiftKey e.preventDefault() @@ -110,6 +113,14 @@ else if ((String.fromCharCode(e.which).toLowerCase() is 'z' and e.shiftKey) or (String.fromCharCode(e.which).toLowerCase() is 'y')) e.preventDefault() self.undoManager.redo() + else if e.which is 13 or e.which is 8 # enter key or backspace key has been pressed + if gl.text._previousState? + gl.text.undoManager.addUndo( + gl.text._previousState, + $thisTextarea.val() + ) + + gl.text._previousState = $thisTextarea.val() gl.text.removeListeners = () -> $('js-md.btn-bold').off() -- cgit v1.2.1 From 118a42ce7f1d04720b57a6ab4c89939cfb640a7b Mon Sep 17 00:00:00 2001 From: Jacob Schatz Date: Thu, 26 May 2016 22:32:12 -0400 Subject: Remove console.log --- app/assets/javascripts/lib/text_utility.js.coffee | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/lib/text_utility.js.coffee b/app/assets/javascripts/lib/text_utility.js.coffee index 86488d735ef..933df1b0d50 100644 --- a/app/assets/javascripts/lib/text_utility.js.coffee +++ b/app/assets/javascripts/lib/text_utility.js.coffee @@ -32,8 +32,11 @@ selObj = window.getSelection() selRange = selObj.getRangeAt(0) text = $textArea.val() - lineBreak = '\n' if textArea.selectionStart > 0 - console.log(textArea.selectionStart,lineBreak) + if textArea.selectionStart > 0 + lineBreak = '\n' + else + lineBreak = '' + replaceWith = @replaceRange( text, textArea.selectionStart, @@ -82,7 +85,6 @@ $thisTextarea.val(latestUndo.newVal) gl.text.addListeners = () -> - console.log('addListeners') self = @ $('.js-md').on 'click', -> $this = $(@) @@ -119,7 +121,6 @@ gl.text._previousState, $thisTextarea.val() ) - gl.text._previousState = $thisTextarea.val() gl.text.removeListeners = () -> -- cgit v1.2.1 From 1c3da0f72e86b80d14f59e4b2596513e06622100 Mon Sep 17 00:00:00 2001 From: Jacob Schatz Date: Thu, 26 May 2016 22:55:44 -0400 Subject: No need to add bold for the class selector for removing events --- app/assets/javascripts/lib/text_utility.js.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/lib/text_utility.js.coffee b/app/assets/javascripts/lib/text_utility.js.coffee index 933df1b0d50..2d0860ea3c7 100644 --- a/app/assets/javascripts/lib/text_utility.js.coffee +++ b/app/assets/javascripts/lib/text_utility.js.coffee @@ -124,6 +124,6 @@ gl.text._previousState = $thisTextarea.val() gl.text.removeListeners = () -> - $('js-md.btn-bold').off() + $('js-md').off() ) window \ No newline at end of file -- cgit v1.2.1 From 5eeccafca43839d50f228b98346c03bd169136bc Mon Sep 17 00:00:00 2001 From: Jacob Schatz Date: Thu, 26 May 2016 22:56:14 -0400 Subject: Proper class jquery selector for `off`. --- app/assets/javascripts/lib/text_utility.js.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/lib/text_utility.js.coffee b/app/assets/javascripts/lib/text_utility.js.coffee index 2d0860ea3c7..3dcc5b24548 100644 --- a/app/assets/javascripts/lib/text_utility.js.coffee +++ b/app/assets/javascripts/lib/text_utility.js.coffee @@ -124,6 +124,6 @@ gl.text._previousState = $thisTextarea.val() gl.text.removeListeners = () -> - $('js-md').off() + $('.js-md').off() ) window \ No newline at end of file -- cgit v1.2.1 From 92ed066ff59d02b070a2a80d9845e019be764f6f Mon Sep 17 00:00:00 2001 From: Jacob Schatz Date: Fri, 27 May 2016 08:04:05 -0400 Subject: Fix syntax error. Remove whitespace --- app/views/shared/issuable/_form.html.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml index 974ccb6fadc..1f364be5b1c 100644 --- a/app/views/shared/issuable/_form.html.haml +++ b/app/views/shared/issuable/_form.html.haml @@ -146,5 +146,5 @@ - else .pull-right - if current_user.can?(:"destroy_#{issuable.to_ability_name}", @project) - = link_to 'Delete', polymorphic_path([@project.namespace.becomes(Namespace), @project, issuable]), data: { confirm: "#{issuable.class.name.titleize} will be removed! Are you sure?" }, - = link_to 'Cancel', polymorphic_path([@project.namespace.becomes(Namespace), @project, issuable]), class: 'btn btn-grouped btn-cancel' \ No newline at end of file + = link_to 'Delete', polymorphic_path([@project.namespace.becomes(Namespace), @project, issuable]), data: { confirm: "#{issuable.class.name.titleize} will be removed! Are you sure?" }, method: :delete, class: 'btn btn-danger btn-grouped' + = link_to 'Cancel', polymorphic_path([@project.namespace.becomes(Namespace), @project, issuable]), class: 'btn btn-grouped btn-cancel' \ No newline at end of file -- cgit v1.2.1 From 07d6edc15ba3db1f76b1b87c51d507f4dc654e1c Mon Sep 17 00:00:00 2001 From: Jacob Schatz Date: Fri, 27 May 2016 09:27:16 -0400 Subject: Revert _form file --- app/views/shared/issuable/_form.html.haml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml index 1f364be5b1c..c30bdb0ae91 100644 --- a/app/views/shared/issuable/_form.html.haml +++ b/app/views/shared/issuable/_form.html.haml @@ -146,5 +146,6 @@ - else .pull-right - if current_user.can?(:"destroy_#{issuable.to_ability_name}", @project) - = link_to 'Delete', polymorphic_path([@project.namespace.becomes(Namespace), @project, issuable]), data: { confirm: "#{issuable.class.name.titleize} will be removed! Are you sure?" }, method: :delete, class: 'btn btn-danger btn-grouped' - = link_to 'Cancel', polymorphic_path([@project.namespace.becomes(Namespace), @project, issuable]), class: 'btn btn-grouped btn-cancel' \ No newline at end of file + = link_to 'Delete', polymorphic_path([@project.namespace.becomes(Namespace), @project, issuable]), data: { confirm: "#{issuable.class.name.titleize} will be removed! Are you sure?" }, + method: :delete, class: 'btn btn-danger btn-grouped' + = link_to 'Cancel', polymorphic_path([@project.namespace.becomes(Namespace), @project, issuable]), class: 'btn btn-grouped btn-cancel' -- cgit v1.2.1 From 7717cb727fba74fcb9eee11559f9e97558795707 Mon Sep 17 00:00:00 2001 From: Jacob Schatz Date: Fri, 27 May 2016 17:30:01 -0400 Subject: Move buttons to upper right. --- app/assets/javascripts/lib/text_utility.js.coffee | 2 +- .../stylesheets/framework/markdown_area.scss | 5 +++++ app/views/projects/_md_preview.html.haml | 25 ++++++++++++++++++++-- app/views/projects/notes/_hints.html.haml | 11 +--------- 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/app/assets/javascripts/lib/text_utility.js.coffee b/app/assets/javascripts/lib/text_utility.js.coffee index 3dcc5b24548..0a4ebb8381e 100644 --- a/app/assets/javascripts/lib/text_utility.js.coffee +++ b/app/assets/javascripts/lib/text_utility.js.coffee @@ -41,7 +41,7 @@ text, textArea.selectionStart, textArea.selectionEnd, - ("#{lineBreak}#{tag} #{selObj.toString()} \n") + ("#{lineBreak}#{tag}#{selObj.toString()} \n") ) $textArea.data('old-val', text).val(replaceWith); gl.text.undoManager.addUndo(oldVal, $textArea.val()) diff --git a/app/assets/stylesheets/framework/markdown_area.scss b/app/assets/stylesheets/framework/markdown_area.scss index fd885b38680..0b45691aae9 100644 --- a/app/assets/stylesheets/framework/markdown_area.scss +++ b/app/assets/stylesheets/framework/markdown_area.scss @@ -65,6 +65,11 @@ a { padding-top: 0; line-height: 1; + border-bottom: 1px solid $border-color; + + &.btn.btn-xs { + padding: 2px 5px; + } } } } diff --git a/app/views/projects/_md_preview.html.haml b/app/views/projects/_md_preview.html.haml index 28a28282fd3..9c242828c12 100644 --- a/app/views/projects/_md_preview.html.haml +++ b/app/views/projects/_md_preview.html.haml @@ -14,8 +14,29 @@ %span This is a confidential issue. Your comment will not be visible to the public. %li.pull-right - %button.zen-control.zen-control-full.js-zen-enter{ type: 'button', tabindex: -1 } - Go full screen + + %a.btn.btn-xs.js-md{ 'data-md-tag' => '**' } + =icon('bold fw') + %a.btn.btn-xs.js-md{ 'data-md-tag' => '*' } + =icon('italic fw') + %a.btn.btn-xs.js-md{ 'data-md-tag' => '`' } + =icon('code fw') + %a.btn.btn-xs.js-md.js-list{ 'data-md-tag' => '* ', 'data-md-prepend' => true } + =icon('list-ul fw') + %a.btn.btn-xs.js-md.js-list.hidden-xs{ 'data-md-tag' => '1. ', 'data-md-prepend' => true } + =icon('list-ol fw') + %a.btn.btn-xs.js-md.js-list.hidden-xs{ 'data-md-tag' => '* [ ] ', 'data-md-prepend' => true } + =icon('check-square-o fw') + %a.btn.btn-xs.js-md.js-list.hidden-xs{ 'data-md-tag' => '> ', 'data-md-prepend' => true } + =icon('quote-right fw') + + %a.btn.btn-xs.js-md.js-list.hidden-xs{ 'data-md-tag' => '!', 'data-md-prepend' => true } + =icon('tasks fw') + %a.btn.btn-xs.js-md.js-list.hidden-xs{ 'data-md-tag' => '#', 'data-md-prepend' => true } + =icon('exclamation-circle fw') + + %a.btn.btn-xs.js-zen-enter.hidden-xs + =icon('arrows-alt fw') .md-write-holder = yield diff --git a/app/views/projects/notes/_hints.html.haml b/app/views/projects/notes/_hints.html.haml index f26866468ce..7d1cbc62e86 100644 --- a/app/views/projects/notes/_hints.html.haml +++ b/app/views/projects/notes/_hints.html.haml @@ -5,13 +5,4 @@ is supported %button.toolbar-button.markdown-selector{ type: 'button', tabindex: '-1' } = icon('file-image-o', class: 'toolbar-button-icon') - Attach a file -.md-helper - %a.btn.btn-xs.js-md{ 'data-md-tag' => '**' } - =icon('bold fw') - %a.btn.btn-xs.js-md{ 'data-md-tag' => '*' } - =icon('italic fw') - %a.btn.btn-xs.js-md.js-list{ 'data-md-tag' => '*', 'data-md-prepend' => true } - =icon('list-ul fw') - %a.btn.btn-xs.js-md.js-list{ 'data-md-tag' => '1.', 'data-md-prepend' => true } - =icon('list-ol fw') \ No newline at end of file + Attach a file \ No newline at end of file -- cgit v1.2.1 From 3ff1b4c98e7a70328846576c540109b0027c7f99 Mon Sep 17 00:00:00 2001 From: Jacob Schatz Date: Fri, 27 May 2016 19:35:10 -0400 Subject: Fix spec issue --- spec/features/issues_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb index c3cb3379440..f4ed0f26d68 100644 --- a/spec/features/issues_spec.rb +++ b/spec/features/issues_spec.rb @@ -22,7 +22,7 @@ describe 'Issues', feature: true do before do visit edit_namespace_project_issue_path(project.namespace, project, issue) - click_button "Go full screen" + first('.js-zen-enter:first').click end it 'should open new issue popup' do -- cgit v1.2.1 From 05dcec95aa246640e69d0f484f94289c3e8a6160 Mon Sep 17 00:00:00 2001 From: Jacob Schatz Date: Fri, 27 May 2016 21:23:15 -0400 Subject: Make tests pass. --- spec/features/issues_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb index f4ed0f26d68..5065dfb849c 100644 --- a/spec/features/issues_spec.rb +++ b/spec/features/issues_spec.rb @@ -22,7 +22,7 @@ describe 'Issues', feature: true do before do visit edit_namespace_project_issue_path(project.namespace, project, issue) - first('.js-zen-enter:first').click + find('.js-zen-enter').click end it 'should open new issue popup' do -- cgit v1.2.1 From 14d08d1400376a0bbae18890a54ff2b961062a32 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 3 Jun 2016 15:14:04 +0100 Subject: Updated design of markdown buttons --- .../stylesheets/framework/markdown_area.scss | 23 ++++++++++++++ app/helpers/gitlab_markdown_helper.rb | 13 ++++++++ app/views/projects/_md_preview.html.haml | 36 ++++++++-------------- 3 files changed, 48 insertions(+), 24 deletions(-) diff --git a/app/assets/stylesheets/framework/markdown_area.scss b/app/assets/stylesheets/framework/markdown_area.scss index 0b45691aae9..25f9c50258e 100644 --- a/app/assets/stylesheets/framework/markdown_area.scss +++ b/app/assets/stylesheets/framework/markdown_area.scss @@ -104,3 +104,26 @@ } } } + +.toolbar-group { + float: left; + margin-right: -5px; + margin-left: $gl-padding; + + &:first-child { + margin-left: 0; + } +} + +.toolbar-btn { + float: left; + padding: 0 5px; + color: #959494; + background: transparent; + border: 0; + outline: 0; + + &:hover { + color: $gl-link-color; + } +} diff --git a/app/helpers/gitlab_markdown_helper.rb b/app/helpers/gitlab_markdown_helper.rb index 067a00660aa..a0dafc52622 100644 --- a/app/helpers/gitlab_markdown_helper.rb +++ b/app/helpers/gitlab_markdown_helper.rb @@ -185,4 +185,17 @@ module GitlabMarkdownHelper '' end end + + def markdown_toolbar_button(options = {}) + data = options[:data].merge({ container: "body" }) + content_tag :button, + type: "button", + class: "toolbar-btn js-md has-tooltip hidden-xs", + tabindex: -1, + data: data, + title: options[:title], + aria: { label: options[:title] } do + icon(options[:icon]) + end + end end diff --git a/app/views/projects/_md_preview.html.haml b/app/views/projects/_md_preview.html.haml index 9c242828c12..ca6714ef42b 100644 --- a/app/views/projects/_md_preview.html.haml +++ b/app/views/projects/_md_preview.html.haml @@ -14,29 +14,17 @@ %span This is a confidential issue. Your comment will not be visible to the public. %li.pull-right - - %a.btn.btn-xs.js-md{ 'data-md-tag' => '**' } - =icon('bold fw') - %a.btn.btn-xs.js-md{ 'data-md-tag' => '*' } - =icon('italic fw') - %a.btn.btn-xs.js-md{ 'data-md-tag' => '`' } - =icon('code fw') - %a.btn.btn-xs.js-md.js-list{ 'data-md-tag' => '* ', 'data-md-prepend' => true } - =icon('list-ul fw') - %a.btn.btn-xs.js-md.js-list.hidden-xs{ 'data-md-tag' => '1. ', 'data-md-prepend' => true } - =icon('list-ol fw') - %a.btn.btn-xs.js-md.js-list.hidden-xs{ 'data-md-tag' => '* [ ] ', 'data-md-prepend' => true } - =icon('check-square-o fw') - %a.btn.btn-xs.js-md.js-list.hidden-xs{ 'data-md-tag' => '> ', 'data-md-prepend' => true } - =icon('quote-right fw') - - %a.btn.btn-xs.js-md.js-list.hidden-xs{ 'data-md-tag' => '!', 'data-md-prepend' => true } - =icon('tasks fw') - %a.btn.btn-xs.js-md.js-list.hidden-xs{ 'data-md-tag' => '#', 'data-md-prepend' => true } - =icon('exclamation-circle fw') - - %a.btn.btn-xs.js-zen-enter.hidden-xs - =icon('arrows-alt fw') + .toolbar-group + = markdown_toolbar_button({icon: "bold fw", data: { "md-tag" => "**" }, title: "Add bold text" }) + = markdown_toolbar_button({icon: "italic fw", data: { "md-tag" => "*" }, title: "Add italic text" }) + = markdown_toolbar_button({icon: "quote-right fw", data: { "md-tag" => "> ", "md-prepend" => true }, title: "Insert a quote" }) + = markdown_toolbar_button({icon: "code fw", data: { "md-tag" => "`" }, title: "Insert code" }) + = markdown_toolbar_button({icon: "list-ul fw", data: { "md-tag" => "* ", "md-prepend" => true }, title: "Add a bullet list" }) + = markdown_toolbar_button({icon: "list-ol fw", data: { "md-tag" => "1. ", "md-prepend" => true }, title: "Add a numbered list" }) + = markdown_toolbar_button({icon: "check-square-o fw", data: { "md-tag" => "* [ ] ", "md-prepend" => true }, title: "Add a task list" }) + .toolbar-group + %button.toolbar-btn.js-zen-enter.has-tooltip.hidden-xs{ type: "button", tabindex: -1, aria: { label: "Go full screen" }, title: "Go full screen", data: { container: "body" } } + =icon("arrows-alt fw") .md-write-holder = yield @@ -45,7 +33,7 @@ - if defined?(referenced_users) && referenced_users %div.referenced-users.hide %span - = icon('exclamation-triangle') + = icon("exclamation-triangle") You are about to add %strong %span.js-referenced-users-count 0 -- cgit v1.2.1 From d5b331b76bb6838e121e54cdf50122023932576c Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Mon, 6 Jun 2016 08:25:43 +0100 Subject: Improved design Updated JS to remove undo manager - instead let the browser handle it all --- app/assets/javascripts/lib/text_utility.js.coffee | 148 +++++++--------------- 1 file changed, 43 insertions(+), 105 deletions(-) diff --git a/app/assets/javascripts/lib/text_utility.js.coffee b/app/assets/javascripts/lib/text_utility.js.coffee index 0a4ebb8381e..52ef001894c 100644 --- a/app/assets/javascripts/lib/text_utility.js.coffee +++ b/app/assets/javascripts/lib/text_utility.js.coffee @@ -1,129 +1,67 @@ ((w) -> w.gl ?= {} w.gl.text ?= {} - w.gl.text.undoManager ?= {} gl.text.randomString = -> Math.random().toString(36).substring(7) gl.text.replaceRange = (s, start, end, substitute) -> s.substring(0, start) + substitute + s.substring(end); - gl.text.wrap = (textArea, tag) -> - $textArea = $(textArea) - oldVal = $textArea.val() - $textArea.focus() - textArea = $textArea.get(0) - selObj = window.getSelection() - selRange = selObj.getRangeAt(0) - text = $textArea.val() - replaceWith = @replaceRange( - text, - textArea.selectionStart, - textArea.selectionEnd, - (tag+selObj.toString()+tag)) - $textArea.data('old-val', text).val(replaceWith) - gl.text.undoManager.addUndo(oldVal, $textArea.val()) + gl.text.selectedText = (text, textarea) -> + text.substring(textarea.selectionStart, textarea.selectionEnd) - gl.text.prepend = (textArea, tag) -> - $textArea = $(textArea) - oldVal = $textArea.val() - $textArea.focus() - textArea = $textArea.get(0) - selObj = window.getSelection() - selRange = selObj.getRangeAt(0) - text = $textArea.val() - if textArea.selectionStart > 0 - lineBreak = '\n' + gl.text.insertText = (textArea, text, tag, selected, wrap) -> + startChar = if not wrap and textArea.selectionStart > 0 then '\n' else '' + insertText = "#{startChar}#{tag}#{selected}#{if wrap then tag else ' '}" + + if document.queryCommandSupported('insertText') + document.execCommand 'insertText', false, insertText else - lineBreak = '' + try + document.execCommand("ms-beginUndoUnit") - replaceWith = @replaceRange( - text, - textArea.selectionStart, - textArea.selectionEnd, - ("#{lineBreak}#{tag}#{selObj.toString()} \n") - ) - $textArea.data('old-val', text).val(replaceWith); - gl.text.undoManager.addUndo(oldVal, $textArea.val()) + textArea.value = @replaceRange( + text, + textArea.selectionStart, + textArea.selectionEnd, + insertText) + try + document.execCommand("ms-endUndoUnit") - gl.text.undoManager.history = {} - gl.text.undoManager.undoHistory = {} + @moveCursor(textArea, tag, wrap) - gl.text.undoManager.addUniqueIfNotExists = ($ta) -> - unique = $ta.attr('data-unique') - if not unique? - unique = gl.text.randomString() - $ta.attr('data-unique', unique) - gl.text.undoManager.history[unique] = [] - gl.text.undoManager.undoHistory[unique] = [] - unique + gl.text.moveCursor = (textArea, tag, wrapped) -> + return unless textArea.setSelectionRange - gl.text.undoManager.addUndo = (oldVal, newVal) -> - $thisTextarea = $('textarea:focus') - unique = gl.text.undoManager.addUniqueIfNotExists($thisTextarea) - gl.text.undoManager.history[unique].push({ - oldVal: oldVal, - newVal: newVal - }) + if textArea.selectionStart is textArea.selectionEnd + if wrapped + pos = textArea.selectionStart - tag.length + else + pos = textArea.selectionStart + + textArea.setSelectionRange pos, pos - gl.text.undoManager.undo = () -> - $thisTextarea = $('textarea:focus') - unique = gl.text.undoManager.addUniqueIfNotExists($thisTextarea) - if not gl.text.undoManager.history[unique].length - return - latestChange = gl.text.undoManager.history[unique].pop() - gl.text.undoManager.undoHistory[unique].push(latestChange) - $thisTextarea.val(latestChange.oldVal) + gl.text.updateText = (textArea, tag, wrap) -> + $textArea = $(textArea) + oldVal = $textArea.val() + textArea = $textArea.get(0) + text = $textArea.val() + selected = @selectedText(text, textArea) + $textArea.focus() - gl.text.undoManager.redo = () -> - $thisTextarea = $('textarea:focus') - unique = gl.text.undoManager.addUniqueIfNotExists($thisTextarea) - if not gl.text.undoManager.undoHistory[unique].length - return - latestUndo = gl.text.undoManager.undoHistory[unique].pop() - gl.text.undoManager.history[unique].push(latestUndo) - $thisTextarea.val(latestUndo.newVal) + @insertText(textArea, text, tag, selected, wrap) - gl.text.addListeners = () -> + gl.text.addListeners = -> self = @ $('.js-md').on 'click', -> $this = $(@) - if $this.data('md-wrap')? - self.wrap( - $this.closest('.md-area').find('textarea'), - $this.data('md-tag') - ) - else if $this.data('md-prepend')? - self.prepend( - $this.closest('.md-area').find('textarea'), - $this.data('md-tag') - ) - else - self.wrap( - $this.closest('.md-area').find('textarea'), - $this.data('md-tag') - ) - - gl.text._previousState = null - - $(window).on 'keydown', (e) => - $thisTextarea = $('textarea:focus') - if e.ctrlKey or e.metaKey - if String.fromCharCode(e.which).toLowerCase() is 'z' and !e.shiftKey - e.preventDefault() - self.undoManager.undo() - else if ((String.fromCharCode(e.which).toLowerCase() is 'z' and e.shiftKey) or (String.fromCharCode(e.which).toLowerCase() is 'y')) - e.preventDefault() - self.undoManager.redo() - else if e.which is 13 or e.which is 8 # enter key or backspace key has been pressed - if gl.text._previousState? - gl.text.undoManager.addUndo( - gl.text._previousState, - $thisTextarea.val() - ) - gl.text._previousState = $thisTextarea.val() + self.updateText( + $this.closest('.md-area').find('textarea'), + $this.data('md-tag'), + not $this.data('md-prepend') + ) - gl.text.removeListeners = () -> + gl.text.removeListeners = -> $('.js-md').off() -) window \ No newline at end of file +) window -- cgit v1.2.1 From 4140c4622f07d8a1793a77ecdf810fbc628568c7 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Mon, 6 Jun 2016 11:59:59 +0100 Subject: Made markdown buttons work on all markdown textareas Selecting multiple rows & a list correctly creates the selected text into a list --- app/assets/javascripts/gl_form.js.coffee | 3 ++ app/assets/javascripts/lib/text_utility.js.coffee | 36 ++++++++++++++-------- app/views/projects/issues/_discussion.html.haml | 6 ---- .../projects/merge_requests/_discussion.html.haml | 6 ---- 4 files changed, 27 insertions(+), 24 deletions(-) diff --git a/app/assets/javascripts/gl_form.js.coffee b/app/assets/javascripts/gl_form.js.coffee index d540cc4dc46..77512d187c9 100644 --- a/app/assets/javascripts/gl_form.js.coffee +++ b/app/assets/javascripts/gl_form.js.coffee @@ -34,6 +34,8 @@ class @GLForm # form and textarea event listeners @addEventListeners() + gl.text.init(@form) + # hide discard button @form.find('.js-note-discard').hide() @@ -42,6 +44,7 @@ class @GLForm clearEventListeners: -> @textarea.off 'focus' @textarea.off 'blur' + gl.text.removeListeners(@form) addEventListeners: -> @textarea.on 'focus', -> diff --git a/app/assets/javascripts/lib/text_utility.js.coffee b/app/assets/javascripts/lib/text_utility.js.coffee index 52ef001894c..bb2772dfed2 100644 --- a/app/assets/javascripts/lib/text_utility.js.coffee +++ b/app/assets/javascripts/lib/text_utility.js.coffee @@ -11,8 +11,18 @@ text.substring(textarea.selectionStart, textarea.selectionEnd) gl.text.insertText = (textArea, text, tag, selected, wrap) -> + selectedSplit = selected.split('\n') startChar = if not wrap and textArea.selectionStart > 0 then '\n' else '' - insertText = "#{startChar}#{tag}#{selected}#{if wrap then tag else ' '}" + + if selectedSplit.length > 1 and not wrap + insertText = selectedSplit.map((val) -> + if val.indexOf(tag) is 0 + "#{val.replace(tag, '')}" + else + "#{tag}#{val}" + ).join('\n') + else + insertText = "#{startChar}#{tag}#{selected}#{if wrap then tag else ' '}" if document.queryCommandSupported('insertText') document.execCommand 'insertText', false, insertText @@ -51,17 +61,19 @@ @insertText(textArea, text, tag, selected, wrap) - gl.text.addListeners = -> + gl.text.init = (form) -> self = @ - $('.js-md').on 'click', -> - $this = $(@) - self.updateText( - $this.closest('.md-area').find('textarea'), - $this.data('md-tag'), - not $this.data('md-prepend') - ) - - gl.text.removeListeners = -> - $('.js-md').off() + $('.js-md', form) + .off 'click' + .on 'click', -> + $this = $(@) + self.updateText( + $this.closest('.md-area').find('textarea'), + $this.data('md-tag'), + not $this.data('md-prepend') + ) + + gl.text.removeListeners = (form) -> + $('.js-md', form).off() ) window diff --git a/app/views/projects/issues/_discussion.html.haml b/app/views/projects/issues/_discussion.html.haml index 8ed0e3d7e1d..b151393abab 100644 --- a/app/views/projects/issues/_discussion.html.haml +++ b/app/views/projects/issues/_discussion.html.haml @@ -5,9 +5,3 @@ #notes = render 'projects/notes/notes_with_form' - -:javascript - $(function(){ - gl.text.removeListeners(); - gl.text.addListeners(); - }) \ No newline at end of file diff --git a/app/views/projects/merge_requests/_discussion.html.haml b/app/views/projects/merge_requests/_discussion.html.haml index c8b6a25952b..393998f15b9 100644 --- a/app/views/projects/merge_requests/_discussion.html.haml +++ b/app/views/projects/merge_requests/_discussion.html.haml @@ -6,9 +6,3 @@ = link_to 'Reopen merge request', merge_request_path(@merge_request, merge_request: {state_event: :reopen }), method: :put, class: "btn btn-nr btn-comment btn-grouped btn-reopen reopen-mr-link js-note-target-reopen", title: "Reopen merge request", data: {original_text: "Reopen merge request", alternative_text: "Comment & reopen merge request"} #notes= render "projects/notes/notes_with_form" - -:javascript - $(function(){ - gl.text.removeListeners(); - gl.text.addListeners(); - }) \ No newline at end of file -- cgit v1.2.1 From dbd534a8537ba02b93dcf673aee0b62d51bf129d Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Fri, 17 Jun 2016 21:04:09 +0800 Subject: Admin::RunnerProjectsController#index is not used --- app/controllers/admin/runner_projects_controller.rb | 5 ----- config/routes.rb | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/app/controllers/admin/runner_projects_controller.rb b/app/controllers/admin/runner_projects_controller.rb index 20f30e70c8a..bf20c5305a7 100644 --- a/app/controllers/admin/runner_projects_controller.rb +++ b/app/controllers/admin/runner_projects_controller.rb @@ -1,11 +1,6 @@ class Admin::RunnerProjectsController < Admin::ApplicationController before_action :project, only: [:create] - def index - @runner_projects = project.runner_projects.all - @runner_project = project.runner_projects.new - end - def create @runner = Ci::Runner.find(params[:runner_project][:runner_id]) diff --git a/config/routes.rb b/config/routes.rb index d52cbb22428..cdfbafbd730 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -283,7 +283,7 @@ Rails.application.routes.draw do post :repository_check end - resources :runner_projects + resources :runner_projects, only: [:create, :destroy] end end -- cgit v1.2.1 From 045dad3cf17f7e5562dde847ae6d9e9118cfa5ba Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Fri, 17 Jun 2016 22:17:20 +0800 Subject: Test for enabling/disabling runners from admin runner page --- app/views/admin/runners/show.html.haml | 4 ++-- spec/features/admin/admin_runners_spec.rb | 34 +++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/app/views/admin/runners/show.html.haml b/app/views/admin/runners/show.html.haml index e049b40bfab..61abfc6ecbe 100644 --- a/app/views/admin/runners/show.html.haml +++ b/app/views/admin/runners/show.html.haml @@ -28,7 +28,7 @@ .col-md-6 %h4 Restrict projects for this runner - if @runner.projects.any? - %table.table + %table.table.assigned-projects %thead %tr %th Assigned projects @@ -44,7 +44,7 @@ .pull-right = link_to 'Disable', [:admin, project.namespace.becomes(Namespace), project, runner_project], method: :delete, class: 'btn btn-danger btn-xs' - %table.table + %table.table.unassigned-projects %thead %tr %th Project diff --git a/spec/features/admin/admin_runners_spec.rb b/spec/features/admin/admin_runners_spec.rb index 9499cd4e025..2d297776cb0 100644 --- a/spec/features/admin/admin_runners_spec.rb +++ b/spec/features/admin/admin_runners_spec.rb @@ -60,6 +60,40 @@ describe "Admin Runners" do it { expect(page).to have_content(@project1.name_with_namespace) } it { expect(page).not_to have_content(@project2.name_with_namespace) } end + + describe 'enable/create' do + before do + @project1.runners << runner + visit admin_runner_path(runner) + end + + it 'enables specific runner for project' do + within '.unassigned-projects' do + click_on 'Enable' + end + + assigned_project = page.find('.assigned-projects') + + expect(assigned_project).to have_content(@project2.path) + end + end + + describe 'disable/destroy' do + before do + @project1.runners << runner + visit admin_runner_path(runner) + end + + it 'enables specific runner for project' do + within '.assigned-projects' do + click_on 'Disable' + end + + new_runner_project = page.find('.unassigned-projects') + + expect(new_runner_project).to have_content(@project1.path) + end + end end describe 'runners registration token' do -- cgit v1.2.1 From 46f659b8ccdfa7f322784a2b782018abaee0832f Mon Sep 17 00:00:00 2001 From: "Luke \"Jared\" Bennett" Date: Mon, 13 Jun 2016 14:35:31 +0100 Subject: Corrected top area css media query params corrected button spacing --- app/assets/stylesheets/framework/nav.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/assets/stylesheets/framework/nav.scss b/app/assets/stylesheets/framework/nav.scss index a55918f8711..5c68f90e343 100644 --- a/app/assets/stylesheets/framework/nav.scss +++ b/app/assets/stylesheets/framework/nav.scss @@ -136,7 +136,7 @@ } /* Small devices (phones, tablets, 768px and lower) */ - @media (max-width: $screen-sm-max) { + @media (max-width: $screen-xs-max) { width: 100%; } } @@ -220,6 +220,7 @@ form { display: block; height: auto; + margin-bottom: 14px; input { width: 100%; -- cgit v1.2.1 From e7221ad66efeb0f7d263ead7ed523d194243fb09 Mon Sep 17 00:00:00 2001 From: "Luke \"Jared\" Bennett" Date: Thu, 9 Jun 2016 16:24:16 +0100 Subject: Added shortcut to help shortcuts view Updated shortcuts.png for docs Updated CHANGELOG Moved CHANGELOG entry updated shortcut docs --- CHANGELOG | 1 + app/views/help/_shortcuts.html.haml | 6 +++++- doc/workflow/shortcuts.png | Bin 90936 -> 108255 bytes 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index b12ba9f31b1..fbbccf75112 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -72,6 +72,7 @@ v 8.9.0 (unreleased) - Projects pending deletion will render a 404 page - Measure queue duration between gitlab-workhorse and Rails - Added Gfm autocomplete for labels + - Added edit note 'up' shortcut documentation to the help panel and docs screenshot #18114 - Make Omniauth providers specs to not modify global configuration - Remove unused JiraIssue class and replace references with ExternalIssue. !4659 (Ilan Shamir) - Make authentication service for Container Registry to be compatible with < Docker 1.11 diff --git a/app/views/help/_shortcuts.html.haml b/app/views/help/_shortcuts.html.haml index 01648047ce2..8cc0b59edeb 100644 --- a/app/views/help/_shortcuts.html.haml +++ b/app/views/help/_shortcuts.html.haml @@ -28,8 +28,12 @@ .key ⌘ shift p - else .key ctrl shift p - %td Toggle Markdown preview + %tr + %td.shortcut + .key + %i.fa.fa-arrow-up + %td Edit last comment (when focused on an empty textarea) %tbody %tr %th diff --git a/doc/workflow/shortcuts.png b/doc/workflow/shortcuts.png index beb6c53ec77..16be0413b64 100644 Binary files a/doc/workflow/shortcuts.png and b/doc/workflow/shortcuts.png differ -- cgit v1.2.1 From 00ac4b8e57980607bea9949ae8febaf9f5decdca Mon Sep 17 00:00:00 2001 From: barthc Date: Fri, 17 Jun 2016 18:17:06 +0100 Subject: using request dot path instead --- app/views/dashboard/_projects_head.html.haml | 2 +- app/views/groups/show.html.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/dashboard/_projects_head.html.haml b/app/views/dashboard/_projects_head.html.haml index 8a98d119ec5..f7abad54286 100644 --- a/app/views/dashboard/_projects_head.html.haml +++ b/app/views/dashboard/_projects_head.html.haml @@ -13,7 +13,7 @@ Explore Projects .nav-controls - = form_tag request.original_url.split('?').first, method: :get, class: 'project-filter-form', id: 'project-filter-form' do |f| + = form_tag request.path, method: :get, class: 'project-filter-form', id: 'project-filter-form' do |f| = search_field_tag :filter_projects, params[:filter_projects], placeholder: 'Filter by name...', class: 'project-filter-form-field form-control input-short projects-list-filter', spellcheck: false, id: 'project-filter-form-field', tabindex: "2" = render 'shared/projects/dropdown' - if current_user.can_create_project? diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml index 62ebd69485c..aecefbc6e8f 100644 --- a/app/views/groups/show.html.haml +++ b/app/views/groups/show.html.haml @@ -33,7 +33,7 @@ = link_to "#shared", 'data-toggle' => 'tab' do Shared Projects .nav-controls - = form_tag request.original_url, method: :get, class: 'project-filter-form', id: 'project-filter-form' do |f| + = form_tag request.path, method: :get, class: 'project-filter-form', id: 'project-filter-form' do |f| = search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'projects-list-filter form-control', spellcheck: false = render 'shared/projects/dropdown' - if can? current_user, :create_projects, @group -- cgit v1.2.1 From 544ad086da7dd27dbb2f6ba750065f63b2e126e0 Mon Sep 17 00:00:00 2001 From: "Luke \"Jared\" Bennett" Date: Thu, 9 Jun 2016 17:34:03 +0100 Subject: restricted note edit shortcut to only up key Updated CHANGELOG Removed CHANGELOG entry Moved conditional to helper method --- app/assets/javascripts/notes.js.coffee | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/notes.js.coffee b/app/assets/javascripts/notes.js.coffee index e2d3241437b..17f7e180127 100644 --- a/app/assets/javascripts/notes.js.coffee +++ b/app/assets/javascripts/notes.js.coffee @@ -102,12 +102,15 @@ class @Notes keydownNoteText: (e) -> $this = $(this) - if $this.val() is '' and e.which is 38 #aka the up key + if $this.val() is '' and e.which is 38 and not isMetaKey e myLastNote = $("li.note[data-author-id='#{gon.current_user_id}'][data-editable]:last") if myLastNote.length myLastNoteEditBtn = myLastNote.find('.js-note-edit') myLastNoteEditBtn.trigger('click', [true, myLastNote]) + isMetaKey = (e) -> + (e.metaKey or e.ctrlKey or e.altKey or e.shiftKey) + initRefresh: -> clearInterval(Notes.interval) Notes.interval = setInterval => -- cgit v1.2.1 From 22ea25ae1a7e300d44945571256f5cd78696cf1b Mon Sep 17 00:00:00 2001 From: Alfredo Sumaran Date: Fri, 17 Jun 2016 13:32:40 -0500 Subject: Make lists looks the same when preview mode and published --- app/assets/stylesheets/framework/markdown_area.scss | 2 ++ app/assets/stylesheets/framework/mixins.scss | 14 ++++++++++++++ app/assets/stylesheets/pages/notes.scss | 16 +++------------- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/app/assets/stylesheets/framework/markdown_area.scss b/app/assets/stylesheets/framework/markdown_area.scss index fd885b38680..fc89eaa09d3 100644 --- a/app/assets/stylesheets/framework/markdown_area.scss +++ b/app/assets/stylesheets/framework/markdown_area.scss @@ -97,5 +97,7 @@ white-space: pre-wrap; word-break: keep-all; } + + @include bulleted-list; } } diff --git a/app/assets/stylesheets/framework/mixins.scss b/app/assets/stylesheets/framework/mixins.scss index 828e7224231..5ec5a96a597 100644 --- a/app/assets/stylesheets/framework/mixins.scss +++ b/app/assets/stylesheets/framework/mixins.scss @@ -110,3 +110,17 @@ font-size: 16px; line-height: 24px; } + +@mixin bulleted-list { + > ul { + list-style-type: disc; + + ul { + list-style-type: circle; + + ul { + list-style-type: square; + } + } + } +} \ No newline at end of file diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss index 35d728aec83..f0c40ae8779 100644 --- a/app/assets/stylesheets/pages/notes.scss +++ b/app/assets/stylesheets/pages/notes.scss @@ -84,24 +84,14 @@ ul.notes { word-wrap: break-word; @include md-typography; + // Reset ul style types since we're nested inside a ul already + @include bulleted-list; + // On diffs code should wrap nicely and not overflow code { white-space: pre-wrap; } - // Reset ul style types since we're nested inside a ul already - & > ul { - list-style-type: disc; - - ul { - list-style-type: circle; - - ul { - list-style-type: square; - } - } - } - ul.task-list { ul:not(.task-list) { padding-left: 1.3em; -- cgit v1.2.1 From ec444e09f57e4b0e552ba77f1e678993d5ed9587 Mon Sep 17 00:00:00 2001 From: Mark Pundsack Date: Thu, 16 Jun 2016 13:15:50 -0700 Subject: Add GIT_STRATEGY and GIT_DEPTH --- doc/ci/yaml/README.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md index 9c98f9c98c6..51c6f814c00 100644 --- a/doc/ci/yaml/README.md +++ b/doc/ci/yaml/README.md @@ -814,6 +814,43 @@ job: - execute this after my script ``` +## Git Strategy + +>**Note:** +Introduced in GitLab 8.9 as an experimental feature + +You can set the `GIT_STRATEGY` used for getting recent application code. `clone` +is slower, but makes sure you have a clean directory before every build. `fetch` +is faster. If specified, it will override the project settings in the web UI. + +``` +variables: + GIT_STRATEGY: clone +``` + +or + +``` +variables: + GIT_STRATEGY: fetch +``` + +## Shallow cloning + +>**Note:** +Introduced in GitLab 8.9 as an experimental feature + +You can specify the depth of fetching and cloning using `GIT_DEPTH`. This allows +shallow cloning of the repository. The value is passed to `git fetch` and `git +clone`. If set while cloning, it will imply `--shallow-modules`, which means +submodules will be cloned with a depth of 1 regardless of the value of +`GIT_DEPTH`. + +``` +variables: + GIT_DEPTH: "1" +``` + ## Hidden jobs >**Note:** -- cgit v1.2.1 From da6d148c3ff43c5b74f7d30896483b2708ccb8cd Mon Sep 17 00:00:00 2001 From: Mark Pundsack Date: Thu, 16 Jun 2016 13:55:23 -0700 Subject: Add to TOC --- doc/ci/yaml/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md index 51c6f814c00..6a64d48e703 100644 --- a/doc/ci/yaml/README.md +++ b/doc/ci/yaml/README.md @@ -35,6 +35,8 @@ If you want a quick introduction to GitLab CI, follow our - [artifacts:expire_in](#artifacts-expire_in) - [dependencies](#dependencies) - [before_script and after_script](#before_script-and-after_script) +- [Git Strategy](#git-strategy) +- [Shallow cloning](#shallow-cloning) - [Hidden jobs](#hidden-jobs) - [Special YAML features](#special-yaml-features) - [Anchors](#anchors) -- cgit v1.2.1 From 4e0f9eeba77d295ac3b2f8c2ef122ff7945bfcce Mon Sep 17 00:00:00 2001 From: Mark Pundsack Date: Thu, 16 Jun 2016 14:04:10 -0700 Subject: Clean up TOC --- doc/ci/yaml/README.md | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md index 6a64d48e703..4ab587b293b 100644 --- a/doc/ci/yaml/README.md +++ b/doc/ci/yaml/README.md @@ -13,34 +13,34 @@ If you want a quick introduction to GitLab CI, follow our **Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* - [.gitlab-ci.yml](#gitlab-ci-yml) - - [image and services](#image-and-services) - - [before_script](#before_script) - - [after_script](#after_script) - - [stages](#stages) - - [types](#types) - - [variables](#variables) - - [cache](#cache) - - [cache:key](#cache-key) + - [image and services](#image-and-services) + - [before_script](#before_script) + - [after_script](#after_script) + - [stages](#stages) + - [types](#types) + - [variables](#variables) + - [cache](#cache) + - [cache:key](#cache-key) - [Jobs](#jobs) - - [script](#script) - - [stage](#stage) - - [job variables](#job-variables) - - [only and except](#only-and-except) - - [tags](#tags) - - [when](#when) - - [environment](#environment) - - [artifacts](#artifacts) - - [artifacts:name](#artifacts-name) - - [artifacts:when](#artifacts-when) - - [artifacts:expire_in](#artifacts-expire_in) - - [dependencies](#dependencies) - - [before_script and after_script](#before_script-and-after_script) + - [script](#script) + - [stage](#stage) + - [only and except](#only-and-except) + - [job variables](#job-variables) + - [tags](#tags) + - [when](#when) + - [environment](#environment) + - [artifacts](#artifacts) + - [artifacts:name](#artifactsname) + - [artifacts:when](#artifactswhen) + - [artifacts:expire_in](#artifactsexpire_in) + - [dependencies](#dependencies) + - [before_script and after_script](#before_script-and-after_script) - [Git Strategy](#git-strategy) - [Shallow cloning](#shallow-cloning) - [Hidden jobs](#hidden-jobs) - [Special YAML features](#special-yaml-features) - - [Anchors](#anchors) -- [Validate the .gitlab-ci.yml](#validate-the-gitlab-ci-yml) + - [Anchors](#anchors) +- [Validate the .gitlab-ci.yml](#validate-the-gitlab-ciyml) - [Skipping builds](#skipping-builds) - [Examples](#examples) -- cgit v1.2.1 From 5de95d4e7088a0e1d94c7991d95ddd92a2345459 Mon Sep 17 00:00:00 2001 From: Mark Pundsack Date: Fri, 17 Jun 2016 15:25:32 -0700 Subject: Update GIT_DEPTH wording --- doc/ci/yaml/README.md | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md index 4ab587b293b..7d2afe4c3fa 100644 --- a/doc/ci/yaml/README.md +++ b/doc/ci/yaml/README.md @@ -819,11 +819,14 @@ job: ## Git Strategy >**Note:** -Introduced in GitLab 8.9 as an experimental feature +Introduced in GitLab 8.9 as an experimental feature. May change in future +releases or be removed completely. You can set the `GIT_STRATEGY` used for getting recent application code. `clone` is slower, but makes sure you have a clean directory before every build. `fetch` -is faster. If specified, it will override the project settings in the web UI. +is faster. `GIT_STRATEGY` can be specified in the global `variables` section or +in the `variables` section for individual jobs. If it's not specified, then the +default from project settings will be used. ``` variables: @@ -840,17 +843,32 @@ variables: ## Shallow cloning >**Note:** -Introduced in GitLab 8.9 as an experimental feature +Introduced in GitLab 8.9 as an experimental feature. May change in future +releases or be removed completely. You can specify the depth of fetching and cloning using `GIT_DEPTH`. This allows -shallow cloning of the repository. The value is passed to `git fetch` and `git -clone`. If set while cloning, it will imply `--shallow-modules`, which means -submodules will be cloned with a depth of 1 regardless of the value of -`GIT_DEPTH`. +shallow cloning of the repository which can significantly speed up cloning for +repositories with a large number of commits or old, large binaries. The value is +passed to `git fetch` and `git clone`. +>**Note:** +If you use a depth of 1 and have a queue of builds or retry +builds, jobs may fail. + +Since Git fetching and cloning is based on a ref, such as a branch name, runners +can't clone a specific commit SHA. If there are multiple builds in the queue, or +you are retrying an old build, the commit to be tested needs to be within the +git history that is cloned. Setting too small a value for `GIT_DEPTH` can make +it impossible to run these old commits. You will see `unresolved reference` in +build logs. You should then reconsider changing `GIT_DEPTH` to a higher value. + +Builds that rely on `git describe` may not work correctly when `GIT_DEPTH` is +set since only part of the git history is present. + +To fetch or clone only the last 3 commits: ``` variables: - GIT_DEPTH: "1" + GIT_DEPTH: "3" ``` ## Hidden jobs -- cgit v1.2.1 From 20a06798aeb7523541a3dff83f7f0905491f67f9 Mon Sep 17 00:00:00 2001 From: Mark Pundsack Date: Tue, 14 Jun 2016 14:21:27 -0700 Subject: Tweak grammar --- doc/ci/yaml/README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md index 9c98f9c98c6..85e64f57ff0 100644 --- a/doc/ci/yaml/README.md +++ b/doc/ci/yaml/README.md @@ -167,7 +167,7 @@ There are also two edge cases worth mentioning: 1. If no `stages` is defined in `.gitlab-ci.yml`, then by default the `build`, `test` and `deploy` are allowed to be used as job's stage by default. -2. If a job doesn't specify `stage`, the job is assigned the `test` stage. +2. If a job doesn't specify a `stage`, the job is assigned the `test` stage. ### types @@ -178,9 +178,9 @@ Alias for [stages](#stages). >**Note:** Introduced in GitLab Runner v0.5.0. -GitLab CI allows you to add to `.gitlab-ci.yml` variables that are set in build -environment. The variables are stored in the git repository and are meant to -store non-sensitive project configuration, for example: +GitLab CI allows you to add variables to `.gitlab-ci.yml` that are set in the +build environment. The variables are stored in the git repository and are meant +to store non-sensitive project configuration, for example: ```yaml variables: @@ -253,8 +253,8 @@ rspec: - binaries/ ``` -The cache is provided on best effort basis, so don't expect that cache will be -always present. For implementation details please check GitLab Runner. +The cache is provided on a best-effort basis, so don't expect that the cache +will be always present. For implementation details, please check GitLab Runner. #### cache:key -- cgit v1.2.1 From e45372b7b2dbb51cc313162cf1b1ce6d16fb087e Mon Sep 17 00:00:00 2001 From: Mark Pundsack Date: Tue, 14 Jun 2016 14:43:55 -0700 Subject: Grammar and typographic changes to artifacts documentation --- doc/ci/yaml/README.md | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md index 85e64f57ff0..6053bf14536 100644 --- a/doc/ci/yaml/README.md +++ b/doc/ci/yaml/README.md @@ -479,10 +479,10 @@ failure. `when` can be set to one of the following values: 1. `on_success` - execute build only when all builds from prior stages - succeeded. This is the default. + succeed. This is the default. 1. `on_failure` - execute build only when at least one build from prior stages - failed. -1. `always` - execute build despite the status of builds from prior stages. + fails. +1. `always` - execute build regardless of the status of builds from prior stages. For example: @@ -559,10 +559,10 @@ The `deploy to production` job will be marked as doing deployment to `production > - Introduced in GitLab Runner v0.7.0 for non-Windows platforms. > - Windows support was added in GitLab Runner v.1.0.0. > - Currently not all executors are supported. -> - Build artifacts are only collected for successful builds. +> - Build artifacts are only collected for successful builds by default. -`artifacts` is used to specify list of files and directories which should be -attached to build after success. To pass artifacts between different builds, +`artifacts` is used to specify a list of files and directories which should be +attached to the build after success. To pass artifacts between different builds, see [dependencies](#dependencies). Below are some examples. @@ -690,9 +690,9 @@ failure. `artifacts:when` can be set to one of the following values: -1. `on_success` - upload artifacts only when build succeeds. This is the default -1. `on_failure` - upload artifacts only when build fails -1. `always` - upload artifacts despite the build status +1. `on_success` - upload artifacts only when the build succeeds. This is the default. +1. `on_failure` - upload artifacts only when the build fails. +1. `always` - upload artifacts regardless of the build status. --- @@ -711,16 +711,18 @@ job: >**Note:** Introduced in GitLab 8.9 and GitLab Runner v1.3.0. -`artifacts:expire_in` is used to remove uploaded artifacts after specified time. -By default artifacts are stored on GitLab forver. -`expire_in` allows to specify after what time the artifacts should be removed. -The artifacts will expire counting from the moment when they are uploaded and stored on GitLab. +`artifacts:expire_in` is used to delete uploaded artifacts after the specified +time. By default, artifacts are stored on GitLab forever. `expire_in` allows you +to specify how long artifacts should live before they expire, counting from the +time they are uploaded and stored on GitLab. -After artifacts uploading you can use the **Keep** button on build page to keep the artifacts forever. +You can use the **Keep** button on the build page to override expiration and +keep artifacts forever. -Artifacts are removed every hour, but they are not accessible after expire date. +By default, artifacts are deleted hourly (via a cron job), but they are not +accessible after expiry. -The value of `expire_in` is a elapsed time. The example of parsable values: +The value of `expire_in` is an elapsed time. Examples of parseable values: - '3 mins 4 sec' - '2 hrs 20 min' - '2h20min' @@ -732,7 +734,7 @@ The value of `expire_in` is a elapsed time. The example of parsable values: **Example configurations** -To expire artifacts after 1 week from the moment that they are uploaded: +To expire artifacts 1 week after being uploaded: ```yaml job: -- cgit v1.2.1 From 4652489f40a4ff2b749f9ad495986a7a17448243 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Fri, 17 Jun 2016 14:06:55 +0200 Subject: New Members::DestroyService MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is to ensure we don't send unwanted notifications when deleting a project. In other words, stop abusing AR callbacks and use services. Signed-off-by: Rémy Coutable --- app/controllers/concerns/membership_actions.rb | 6 ++-- app/models/member.rb | 7 +---- app/models/members/group_member.rb | 12 ------- app/models/members/project_member.rb | 12 ------- app/services/members/destroy_service.rb | 33 ++++++++++++++++++++ app/services/notification_service.rb | 21 +++++-------- spec/models/member_spec.rb | 12 ------- spec/models/members/group_member_spec.rb | 10 ------ spec/models/members/project_member_spec.rb | 10 ------ spec/services/members/destroy_service_spec.rb | 43 ++++++++++++++++++++++++++ 10 files changed, 88 insertions(+), 78 deletions(-) create mode 100644 app/services/members/destroy_service.rb create mode 100644 spec/services/members/destroy_service_spec.rb diff --git a/app/controllers/concerns/membership_actions.rb b/app/controllers/concerns/membership_actions.rb index a24273fad0b..b1343576b3c 100644 --- a/app/controllers/concerns/membership_actions.rb +++ b/app/controllers/concerns/membership_actions.rb @@ -23,22 +23,24 @@ module MembershipActions @member = membershipable.members.find_by(user_id: current_user) return render_403 unless @member + @member = Members::DestroyService.new(@member, current_user).execute + source_type = @member.real_source_type.humanize(capitalize: false) - if can?(current_user, action_member_permission(:destroy, @member), @member) + if @member.destroyed? notice = if @member.request? "Your access request to the #{source_type} has been withdrawn." else "You left the \"#{@member.source.human_name}\" #{source_type}." end - @member.destroy redirect_to [:dashboard, @member.real_source_type.tableize], notice: notice else if cannot_leave? alert = "You can not leave the \"#{@member.source.human_name}\" #{source_type}." alert << " Transfer or delete the #{source_type}." + redirect_to polymorphic_url(membershipable), alert: alert else render_403 diff --git a/app/models/member.rb b/app/models/member.rb index 4ee3f1bb5c2..c74a16367db 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -48,7 +48,6 @@ class Member < ActiveRecord::Base after_create :post_create_hook, unless: [:pending?, :importing?] after_update :post_update_hook, unless: [:pending?, :importing?] after_destroy :post_destroy_hook, unless: :pending? - after_destroy :post_decline_request, if: :request? delegate :name, :username, :email, to: :user, prefix: true @@ -188,7 +187,7 @@ class Member < ActiveRecord::Base end def send_request - # override in subclass + notification_service.new_access_request(self) end def post_create_hook @@ -215,10 +214,6 @@ class Member < ActiveRecord::Base post_create_hook end - def post_decline_request - # override in subclass - end - def system_hook_service SystemHooksService.new end diff --git a/app/models/members/group_member.rb b/app/models/members/group_member.rb index 363db877968..2f13d339c89 100644 --- a/app/models/members/group_member.rb +++ b/app/models/members/group_member.rb @@ -33,12 +33,6 @@ class GroupMember < Member super end - def send_request - notification_service.new_group_access_request(self) - - super - end - def post_create_hook notification_service.new_group_member(self) @@ -64,10 +58,4 @@ class GroupMember < Member super end - - def post_decline_request - notification_service.decline_group_access_request(self) - - super - end end diff --git a/app/models/members/project_member.rb b/app/models/members/project_member.rb index 250ee04fd1d..e9d3a82ba15 100644 --- a/app/models/members/project_member.rb +++ b/app/models/members/project_member.rb @@ -111,12 +111,6 @@ class ProjectMember < Member super end - def send_request - notification_service.new_project_access_request(self) - - super - end - def post_create_hook unless owner? event_service.join_project(self.project, self.user) @@ -152,12 +146,6 @@ class ProjectMember < Member super end - def post_decline_request - notification_service.decline_project_access_request(self) - - super - end - def event_service EventCreateService.new end diff --git a/app/services/members/destroy_service.rb b/app/services/members/destroy_service.rb new file mode 100644 index 00000000000..e32eb47b846 --- /dev/null +++ b/app/services/members/destroy_service.rb @@ -0,0 +1,33 @@ +module Members + class DestroyService < BaseService + attr_accessor :member, :current_user + + def initialize(member, user) + @member, @current_user = member, user + end + + def execute + if can?(current_user, "destroy_#{member.type.underscore}".to_sym, member) + member.destroy + + notification_service.decline_access_request(member) if member.request? + end + + member + end + + private + + def abilities + Ability.abilities + end + + def can?(object, action, subject) + abilities.allowed?(object, action, subject) + end + + def notification_service + NotificationService.new + end + end +end diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index 19832a19b2b..590350a11e5 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -181,15 +181,16 @@ class NotificationService end end - # Project access request - def new_project_access_request(project_member) - mailer.member_access_requested_email(project_member.real_source_type, project_member.id).deliver_later + # Members + def new_access_request(member) + mailer.member_access_requested_email(member.real_source_type, member.id).deliver_later end - def decline_project_access_request(project_member) - mailer.member_access_denied_email(project_member.real_source_type, project_member.project.id, project_member.user.id).deliver_later + def decline_access_request(member) + mailer.member_access_denied_email(member.real_source_type, member.source_id, member.user_id).deliver_later end + # Project invite def invite_project_member(project_member, token) mailer.member_invited_email(project_member.real_source_type, project_member.id, token).deliver_later end @@ -216,15 +217,7 @@ class NotificationService mailer.member_access_granted_email(project_member.real_source_type, project_member.id).deliver_later end - # Group access request - def new_group_access_request(group_member) - mailer.member_access_requested_email(group_member.real_source_type, group_member.id).deliver_later - end - - def decline_group_access_request(group_member) - mailer.member_access_denied_email(group_member.real_source_type, group_member.group.id, group_member.user.id).deliver_later - end - + # Group invite def invite_group_member(group_member, token) mailer.member_invited_email(group_member.real_source_type, group_member.id, token).deliver_later end diff --git a/spec/models/member_spec.rb b/spec/models/member_spec.rb index 3ed3202ac6c..e9134a3d283 100644 --- a/spec/models/member_spec.rb +++ b/spec/models/member_spec.rb @@ -134,18 +134,6 @@ describe Member, models: true do it { is_expected.to respond_to(:user_email) } end - describe 'Callbacks' do - describe 'after_destroy :post_decline_request, if: :request?' do - let(:member) { create(:project_member, requested_at: Time.now.utc) } - - it 'calls #post_decline_request' do - expect(member).to receive(:post_decline_request) - - member.destroy - end - end - end - describe ".add_user" do let!(:user) { create(:user) } let(:project) { create(:project) } diff --git a/spec/models/members/group_member_spec.rb b/spec/models/members/group_member_spec.rb index eeb74a462ac..18439cac2a4 100644 --- a/spec/models/members/group_member_spec.rb +++ b/spec/models/members/group_member_spec.rb @@ -61,16 +61,6 @@ describe GroupMember, models: true do end end - describe '#post_decline_request' do - it 'calls NotificationService.decline_group_access_request' do - member = create(:group_member, user: build_stubbed(:user), requested_at: Time.now) - - expect_any_instance_of(NotificationService).to receive(:decline_group_access_request) - - member.__send__(:post_decline_request) - end - end - describe '#real_source_type' do subject { create(:group_member).real_source_type } diff --git a/spec/models/members/project_member_spec.rb b/spec/models/members/project_member_spec.rb index 1e466f9c620..bbf65edb27c 100644 --- a/spec/models/members/project_member_spec.rb +++ b/spec/models/members/project_member_spec.rb @@ -152,15 +152,5 @@ describe ProjectMember, models: true do member.__send__(:after_accept_request) end end - - describe '#post_decline_request' do - it 'calls NotificationService.decline_project_access_request' do - member = create(:project_member, user: build_stubbed(:user), requested_at: Time.now) - - expect_any_instance_of(NotificationService).to receive(:decline_project_access_request) - - member.__send__(:post_decline_request) - end - end end end diff --git a/spec/services/members/destroy_service_spec.rb b/spec/services/members/destroy_service_spec.rb new file mode 100644 index 00000000000..aa002b4bd22 --- /dev/null +++ b/spec/services/members/destroy_service_spec.rb @@ -0,0 +1,43 @@ +require 'spec_helper' + +describe Members::DestroyService, services: true do + let(:user) { create(:user) } + let(:project) { create(:project) } + let!(:member) { create(:project_member, source: project) } + + context 'when current user cannot destroy the given member' do + before do + project.team << [user, :developer] + end + + it 'does not destroy the member' do + expect(destroy_member(member, user)).not_to be_destroyed + end + end + + context 'when current user can destroy the given member' do + before do + project.team << [user, :master] + end + + it 'destroys the member' do + expect(destroy_member(member, user)).to be_destroyed + end + + context 'when the given member is a requester' do + before do + member.update_column(:requested_at, Time.now) + end + + it 'calls Member#after_decline_request' do + expect_any_instance_of(NotificationService).to receive(:decline_access_request).with(member) + + destroy_member(member, user) + end + end + end + + def destroy_member(member, user) + Members::DestroyService.new(member, user).execute + end +end -- cgit v1.2.1 From 6c5b2377f769185f562578791139a13939867b73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Fri, 17 Jun 2016 14:08:02 +0200 Subject: Use the new Members::DestroyService in group/project member controllers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémy Coutable --- app/controllers/groups/group_members_controller.rb | 2 +- app/controllers/projects/project_members_controller.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/groups/group_members_controller.rb b/app/controllers/groups/group_members_controller.rb index d0f2e2949f0..c3929ded6dd 100644 --- a/app/controllers/groups/group_members_controller.rb +++ b/app/controllers/groups/group_members_controller.rb @@ -38,7 +38,7 @@ class Groups::GroupMembersController < Groups::ApplicationController return render_403 unless can?(current_user, :destroy_group_member, @group_member) - @group_member.destroy + Members::DestroyService.new(@group_member, current_user).execute respond_to do |format| format.html { redirect_to group_group_members_path(@group), notice: 'User was successfully removed from group.' } diff --git a/app/controllers/projects/project_members_controller.rb b/app/controllers/projects/project_members_controller.rb index 35d067cd029..ff0ac115f55 100644 --- a/app/controllers/projects/project_members_controller.rb +++ b/app/controllers/projects/project_members_controller.rb @@ -52,7 +52,7 @@ class Projects::ProjectMembersController < Projects::ApplicationController return render_403 unless can?(current_user, :destroy_project_member, @project_member) - @project_member.destroy + Members::DestroyService.new(@project_member, current_user).execute respond_to do |format| format.html do -- cgit v1.2.1 From 724f986fb2cf8fee3606bffd01da9842634400ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Fri, 17 Jun 2016 16:33:10 +0200 Subject: Redirect to the member's source on request withdrawal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémy Coutable --- app/controllers/concerns/membership_actions.rb | 3 ++- spec/controllers/groups/group_members_controller_spec.rb | 2 +- spec/controllers/projects/project_members_controller_spec.rb | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/controllers/concerns/membership_actions.rb b/app/controllers/concerns/membership_actions.rb index b1343576b3c..7e6b83bcc37 100644 --- a/app/controllers/concerns/membership_actions.rb +++ b/app/controllers/concerns/membership_actions.rb @@ -34,8 +34,9 @@ module MembershipActions else "You left the \"#{@member.source.human_name}\" #{source_type}." end + redirect_path = @member.request? ? @member.source : [:dashboard, @member.real_source_type.tableize] - redirect_to [:dashboard, @member.real_source_type.tableize], notice: notice + redirect_to redirect_path, notice: notice else if cannot_leave? alert = "You can not leave the \"#{@member.source.human_name}\" #{source_type}." diff --git a/spec/controllers/groups/group_members_controller_spec.rb b/spec/controllers/groups/group_members_controller_spec.rb index 89c2c26a367..8798d709f30 100644 --- a/spec/controllers/groups/group_members_controller_spec.rb +++ b/spec/controllers/groups/group_members_controller_spec.rb @@ -134,7 +134,7 @@ describe Groups::GroupMembersController do delete :leave, group_id: group expect(response).to set_flash.to 'Your access request to the group has been withdrawn.' - expect(response).to redirect_to(dashboard_groups_path) + expect(response).to redirect_to(group_path(group)) expect(group.members.request).to be_empty expect(group.users).not_to include user end diff --git a/spec/controllers/projects/project_members_controller_spec.rb b/spec/controllers/projects/project_members_controller_spec.rb index fc5f458e795..0a8fe5e04c3 100644 --- a/spec/controllers/projects/project_members_controller_spec.rb +++ b/spec/controllers/projects/project_members_controller_spec.rb @@ -190,7 +190,7 @@ describe Projects::ProjectMembersController do project_id: project expect(response).to set_flash.to 'Your access request to the project has been withdrawn.' - expect(response).to redirect_to(dashboard_projects_path) + expect(response).to redirect_to(namespace_project_path(project.namespace, project)) expect(project.members.request).to be_empty expect(project.users).not_to include user end -- cgit v1.2.1 From a08a26ac814d7fd9f7523e22847fab0cc25ceb78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Fri, 17 Jun 2016 16:33:37 +0200 Subject: Don't send the "access declined" email on access request withdrawal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémy Coutable --- app/services/members/destroy_service.rb | 4 +++- spec/services/members/destroy_service_spec.rb | 8 ++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/app/services/members/destroy_service.rb b/app/services/members/destroy_service.rb index e32eb47b846..59a55e42e38 100644 --- a/app/services/members/destroy_service.rb +++ b/app/services/members/destroy_service.rb @@ -10,7 +10,9 @@ module Members if can?(current_user, "destroy_#{member.type.underscore}".to_sym, member) member.destroy - notification_service.decline_access_request(member) if member.request? + if member.request? && member.user != current_user + notification_service.decline_access_request(member) + end end member diff --git a/spec/services/members/destroy_service_spec.rb b/spec/services/members/destroy_service_spec.rb index aa002b4bd22..04c2782c125 100644 --- a/spec/services/members/destroy_service_spec.rb +++ b/spec/services/members/destroy_service_spec.rb @@ -34,6 +34,14 @@ describe Members::DestroyService, services: true do destroy_member(member, user) end + + context 'when current user is the member' do + it 'does not call Member#after_decline_request' do + expect_any_instance_of(NotificationService).not_to receive(:decline_access_request).with(member) + + destroy_member(member, member.user) + end + end end end -- cgit v1.2.1 From 654565c9dc734a597c525a75c8f72dd63235604b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Fri, 17 Jun 2016 18:59:33 +0200 Subject: Raise a new Gitlab::Access::AccessDeniedError when permission is not enough to destroy a member MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a try for a new approach to put the access checks at the service level. Signed-off-by: Rémy Coutable --- app/controllers/application_controller.rb | 4 +++ app/controllers/concerns/membership_actions.rb | 34 +++++----------------- app/controllers/groups/group_members_controller.rb | 6 ---- .../projects/project_members_controller.rb | 6 ---- app/services/members/destroy_service.rb | 26 ++++------------- lib/gitlab/access.rb | 2 ++ spec/services/members/destroy_service_spec.rb | 24 +++++++++++++-- 7 files changed, 42 insertions(+), 60 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index dd1bc6f5d52..9cc31620d9f 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -36,6 +36,10 @@ class ApplicationController < ActionController::Base render_404 end + rescue_from Gitlab::Access::AccessDeniedError do |exception| + render_403 + end + def redirect_back_or_default(default: root_path, options: {}) redirect_to request.referer.present? ? :back : default, options end diff --git a/app/controllers/concerns/membership_actions.rb b/app/controllers/concerns/membership_actions.rb index 7e6b83bcc37..52dc396af6a 100644 --- a/app/controllers/concerns/membership_actions.rb +++ b/app/controllers/concerns/membership_actions.rb @@ -21,32 +21,18 @@ module MembershipActions def leave @member = membershipable.members.find_by(user_id: current_user) - return render_403 unless @member - - @member = Members::DestroyService.new(@member, current_user).execute + Members::DestroyService.new(@member, current_user).execute source_type = @member.real_source_type.humanize(capitalize: false) - - if @member.destroyed? - notice = - if @member.request? - "Your access request to the #{source_type} has been withdrawn." - else - "You left the \"#{@member.source.human_name}\" #{source_type}." - end - redirect_path = @member.request? ? @member.source : [:dashboard, @member.real_source_type.tableize] - - redirect_to redirect_path, notice: notice - else - if cannot_leave? - alert = "You can not leave the \"#{@member.source.human_name}\" #{source_type}." - alert << " Transfer or delete the #{source_type}." - - redirect_to polymorphic_url(membershipable), alert: alert + notice = + if @member.request? + "Your access request to the #{source_type} has been withdrawn." else - render_403 + "You left the \"#{@member.source.human_name}\" #{source_type}." end - end + redirect_path = @member.request? ? @member.source : [:dashboard, @member.real_source_type.tableize] + + redirect_to redirect_path, notice: notice end protected @@ -54,8 +40,4 @@ module MembershipActions def membershipable raise NotImplementedError end - - def cannot_leave? - raise NotImplementedError - end end diff --git a/app/controllers/groups/group_members_controller.rb b/app/controllers/groups/group_members_controller.rb index c3929ded6dd..2c49fe3833e 100644 --- a/app/controllers/groups/group_members_controller.rb +++ b/app/controllers/groups/group_members_controller.rb @@ -36,8 +36,6 @@ class Groups::GroupMembersController < Groups::ApplicationController def destroy @group_member = @group.group_members.find(params[:id]) - return render_403 unless can?(current_user, :destroy_group_member, @group_member) - Members::DestroyService.new(@group_member, current_user).execute respond_to do |format| @@ -68,8 +66,4 @@ class Groups::GroupMembersController < Groups::ApplicationController # MembershipActions concern alias_method :membershipable, :group - - def cannot_leave? - @group.last_owner?(current_user) - end end diff --git a/app/controllers/projects/project_members_controller.rb b/app/controllers/projects/project_members_controller.rb index ff0ac115f55..6ba32d33403 100644 --- a/app/controllers/projects/project_members_controller.rb +++ b/app/controllers/projects/project_members_controller.rb @@ -50,8 +50,6 @@ class Projects::ProjectMembersController < Projects::ApplicationController def destroy @project_member = @project.project_members.find(params[:id]) - return render_403 unless can?(current_user, :destroy_project_member, @project_member) - Members::DestroyService.new(@project_member, current_user).execute respond_to do |format| @@ -98,8 +96,4 @@ class Projects::ProjectMembersController < Projects::ApplicationController # MembershipActions concern alias_method :membershipable, :project - - def cannot_leave? - current_user == @project.owner - end end diff --git a/app/services/members/destroy_service.rb b/app/services/members/destroy_service.rb index 59a55e42e38..15358f80208 100644 --- a/app/services/members/destroy_service.rb +++ b/app/services/members/destroy_service.rb @@ -7,29 +7,15 @@ module Members end def execute - if can?(current_user, "destroy_#{member.type.underscore}".to_sym, member) - member.destroy - - if member.request? && member.user != current_user - notification_service.decline_access_request(member) - end + unless member && can?(current_user, "destroy_#{member.type.underscore}".to_sym, member) + raise Gitlab::Access::AccessDeniedError end - member - end - - private - - def abilities - Ability.abilities - end - - def can?(object, action, subject) - abilities.allowed?(object, action, subject) - end + member.destroy - def notification_service - NotificationService.new + if member.request? && member.user != current_user + notification_service.decline_access_request(member) + end end end end diff --git a/lib/gitlab/access.rb b/lib/gitlab/access.rb index 6d0e30e916f..831f1e635ba 100644 --- a/lib/gitlab/access.rb +++ b/lib/gitlab/access.rb @@ -5,6 +5,8 @@ # module Gitlab module Access + class AccessDeniedError < StandardError; end + GUEST = 10 REPORTER = 20 DEVELOPER = 30 diff --git a/spec/services/members/destroy_service_spec.rb b/spec/services/members/destroy_service_spec.rb index 04c2782c125..2395445e7fd 100644 --- a/spec/services/members/destroy_service_spec.rb +++ b/spec/services/members/destroy_service_spec.rb @@ -5,13 +5,23 @@ describe Members::DestroyService, services: true do let(:project) { create(:project) } let!(:member) { create(:project_member, source: project) } + context 'when member is nil' do + before do + project.team << [user, :developer] + end + + it 'does not destroy the member' do + expect { destroy_member(nil, user) }.to raise_error(Gitlab::Access::AccessDeniedError) + end + end + context 'when current user cannot destroy the given member' do before do project.team << [user, :developer] end it 'does not destroy the member' do - expect(destroy_member(member, user)).not_to be_destroyed + expect { destroy_member(member, user) }.to raise_error(Gitlab::Access::AccessDeniedError) end end @@ -21,7 +31,9 @@ describe Members::DestroyService, services: true do end it 'destroys the member' do - expect(destroy_member(member, user)).to be_destroyed + destroy_member(member, user) + + expect(member).to be_destroyed end context 'when the given member is a requester' do @@ -42,6 +54,14 @@ describe Members::DestroyService, services: true do destroy_member(member, member.user) end end + + context 'when current user is the member and ' do + it 'does not call Member#after_decline_request' do + expect_any_instance_of(NotificationService).not_to receive(:decline_access_request).with(member) + + destroy_member(member, member.user) + end + end end end -- cgit v1.2.1 From bceee987134ad578b3d6f89c9bc61bef8e0c6066 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Sat, 18 Jun 2016 05:44:15 +0200 Subject: Show 'Leave project' only if member can actually leave the project MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémy Coutable --- app/views/layouts/nav/_project.html.haml | 11 ++++++----- app/views/layouts/nav/_project_settings.html.haml | 2 +- .../projects/members/member_leaves_project_spec.rb | 19 +++++++++++++++++++ .../members/owner_cannot_leave_project_spec.rb | 16 ++++++++++++++++ .../projects/members/user_requests_access_spec.rb | 1 + 5 files changed, 43 insertions(+), 6 deletions(-) create mode 100644 spec/features/projects/members/member_leaves_project_spec.rb create mode 100644 spec/features/projects/members/owner_cannot_leave_project_spec.rb diff --git a/app/views/layouts/nav/_project.html.haml b/app/views/layouts/nav/_project.html.haml index 39ea4920ccc..a9289a8552a 100644 --- a/app/views/layouts/nav/_project.html.haml +++ b/app/views/layouts/nav/_project.html.haml @@ -5,19 +5,20 @@ = icon('cog') = icon('caret-down') %ul.dropdown-menu.dropdown-menu-align-right - - is_project_member = @project.users.exists?(current_user.id) - - access = @project.team.max_member_access(current_user.id) - can_edit = can?(current_user, :admin_project, @project) + -# We don't use @project.team.find_member because it searches for group members too... + - member = @project.members.non_request.find_by(user_id: current_user.id) + - can_leave = member && can?(current_user, :destroy_project_member, member) - = render 'layouts/nav/project_settings', access: access, can_edit: can_edit + = render 'layouts/nav/project_settings', can_edit: can_edit - - if can_edit || is_project_member + - if can_edit || can_leave %li.divider - if can_edit %li = link_to edit_project_path(@project) do Edit Project - - if is_project_member + - if can_leave %li = link_to polymorphic_path([:leave, @project, :members]), data: { confirm: leave_confirmation_message(@project) }, method: :delete, title: 'Leave project' do diff --git a/app/views/layouts/nav/_project_settings.html.haml b/app/views/layouts/nav/_project_settings.html.haml index 13d32bd1354..51a54b4f262 100644 --- a/app/views/layouts/nav/_project_settings.html.haml +++ b/app/views/layouts/nav/_project_settings.html.haml @@ -3,7 +3,7 @@ = link_to namespace_project_project_members_path(@project.namespace, @project), title: 'Members', class: 'team-tab tab' do %span Members -- if access && can_edit +- if can_edit - if @project.allowed_to_share_with_group? = nav_link(controller: :group_links) do = link_to namespace_project_group_links_path(@project.namespace, @project), title: "Groups" do diff --git a/spec/features/projects/members/member_leaves_project_spec.rb b/spec/features/projects/members/member_leaves_project_spec.rb new file mode 100644 index 00000000000..79dec442818 --- /dev/null +++ b/spec/features/projects/members/member_leaves_project_spec.rb @@ -0,0 +1,19 @@ +require 'spec_helper' + +feature 'Projects > Members > Member leaves project', feature: true do + let(:user) { create(:user) } + let(:project) { create(:project) } + + background do + project.team << [user, :developer] + login_as(user) + visit namespace_project_path(project.namespace, project) + end + + scenario 'user leaves project' do + click_link 'Leave Project' + + expect(current_path).to eq(dashboard_projects_path) + expect(project.users.exists?(user.id)).to be_falsey + end +end diff --git a/spec/features/projects/members/owner_cannot_leave_project_spec.rb b/spec/features/projects/members/owner_cannot_leave_project_spec.rb new file mode 100644 index 00000000000..67811b1048e --- /dev/null +++ b/spec/features/projects/members/owner_cannot_leave_project_spec.rb @@ -0,0 +1,16 @@ +require 'spec_helper' + +feature 'Projects > Members > Owner cannot leave project', feature: true do + let(:owner) { create(:user) } + let(:project) { create(:project) } + + background do + project.team << [owner, :owner] + login_as(owner) + visit namespace_project_path(project.namespace, project) + end + + scenario 'user does not see a "Leave Project" link' do + expect(page).not_to have_content 'Leave Project' + end +end diff --git a/spec/features/projects/members/user_requests_access_spec.rb b/spec/features/projects/members/user_requests_access_spec.rb index fd92a3a2f0c..af420c170ef 100644 --- a/spec/features/projects/members/user_requests_access_spec.rb +++ b/spec/features/projects/members/user_requests_access_spec.rb @@ -21,6 +21,7 @@ feature 'Projects > Members > User requests access', feature: true do expect(page).to have_content 'Your request for access has been queued for review.' expect(page).to have_content 'Withdraw Access Request' + expect(page).not_to have_content 'Leave Project' end scenario 'user is not listed in the project members page' do -- cgit v1.2.1 From bf05ca88eefb38bb52fb6e31622f9c1a795965e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Sat, 18 Jun 2016 05:45:52 +0200 Subject: Add 'Leave Group' link MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The link was removed in !3798, probably by mistake. Signed-off-by: Rémy Coutable --- app/views/layouts/nav/_group_settings.html.haml | 36 +++++++++++++--------- .../members/last_owner_cannot_leave_group_spec.rb | 16 ++++++++++ .../groups/members/member_leaves_group_spec.rb | 22 +++++++++++++ .../groups/members/user_requests_access_spec.rb | 1 + 4 files changed, 60 insertions(+), 15 deletions(-) create mode 100644 spec/features/groups/members/last_owner_cannot_leave_group_spec.rb create mode 100644 spec/features/groups/members/member_leaves_group_spec.rb diff --git a/app/views/layouts/nav/_group_settings.html.haml b/app/views/layouts/nav/_group_settings.html.haml index dac46648b9f..3a24b09ab7e 100644 --- a/app/views/layouts/nav/_group_settings.html.haml +++ b/app/views/layouts/nav/_group_settings.html.haml @@ -1,16 +1,22 @@ - if current_user - - if access = @group.users.find_by(id: current_user.id) - .controls - .dropdown.group-settings-dropdown - %a.dropdown-new.btn.btn-default#group-settings-button{href: '#', 'data-toggle' => 'dropdown'} - = icon('cog') - = icon('caret-down') - %ul.dropdown-menu.dropdown-menu-align-right - - if can?(current_user, :admin_group, @group) - = nav_link(path: 'groups#projects') do - = link_to projects_group_path(@group), title: 'Projects' do - Projects - %li.divider - %li - = link_to edit_group_path(@group) do - Edit Group + - can_edit = can?(current_user, :admin_group, @group) + - member = @group.members.non_request.find_by(user_id: current_user.id) + - can_leave = member && can?(current_user, :destroy_group_member, member) + + .controls + .dropdown.group-settings-dropdown + %a.dropdown-new.btn.btn-default#group-settings-button{href: '#', 'data-toggle' => 'dropdown'} + = icon('cog') + = icon('caret-down') + %ul.dropdown-menu.dropdown-menu-align-right + = nav_link(path: 'groups#projects') do + = link_to 'Projects', projects_group_path(@group), title: 'Projects' + %li.divider + - if can_edit + %li + = link_to 'Edit Group', edit_group_path(@group) + - if can_leave + %li + = link_to polymorphic_path([:leave, @group, :members]), + data: { confirm: leave_confirmation_message(@group) }, method: :delete, title: 'Leave group' do + Leave Group diff --git a/spec/features/groups/members/last_owner_cannot_leave_group_spec.rb b/spec/features/groups/members/last_owner_cannot_leave_group_spec.rb new file mode 100644 index 00000000000..33bf6d3752f --- /dev/null +++ b/spec/features/groups/members/last_owner_cannot_leave_group_spec.rb @@ -0,0 +1,16 @@ +require 'spec_helper' + +feature 'Groups > Members > Last owner cannot leave group', feature: true do + let(:owner) { create(:user) } + let(:group) { create(:group) } + + background do + group.add_owner(owner) + login_as(owner) + visit group_path(group) + end + + scenario 'user does not see a "Leave Group" link' do + expect(page).not_to have_content 'Leave Group' + end +end diff --git a/spec/features/groups/members/member_leaves_group_spec.rb b/spec/features/groups/members/member_leaves_group_spec.rb new file mode 100644 index 00000000000..04dfb22db49 --- /dev/null +++ b/spec/features/groups/members/member_leaves_group_spec.rb @@ -0,0 +1,22 @@ +require 'spec_helper' + +feature 'Groups > Members > Member leaves group', feature: true do + let(:user) { create(:user) } + let(:owner) { create(:user) } + let(:group) { create(:group, :public) } + + background do + group.add_owner(owner) + group.add_developer(user) + login_as(user) + visit group_path(group) + end + + scenario 'user leaves group' do + # find('#group-settings-button').click + click_link 'Leave Group' + + expect(current_path).to eq(dashboard_groups_path) + expect(group.users.exists?(user.id)).to be_falsey + end +end diff --git a/spec/features/groups/members/user_requests_access_spec.rb b/spec/features/groups/members/user_requests_access_spec.rb index a878a96b6ee..1ea607cbca0 100644 --- a/spec/features/groups/members/user_requests_access_spec.rb +++ b/spec/features/groups/members/user_requests_access_spec.rb @@ -21,6 +21,7 @@ feature 'Groups > Members > User requests access', feature: true do expect(page).to have_content 'Your request for access has been queued for review.' expect(page).to have_content 'Withdraw Access Request' + expect(page).not_to have_content 'Leave Group' end scenario 'user is not listed in the group members page' do -- cgit v1.2.1 From 11f37a9302515d0a26af00f49eadf25b496a0a90 Mon Sep 17 00:00:00 2001 From: Paco Guzman Date: Fri, 17 Jun 2016 10:17:36 +0200 Subject: Remove explicit Gitlab::Metrics.action assignments, are already automatic. --- CHANGELOG | 1 + lib/api/internal.rb | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 362b5bd580a..9c430c5c1a4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -126,6 +126,7 @@ v 8.9.0 (unreleased) - Various associations are now eager loaded when parsing issue references to reduce the number of queries executed - Set inverse_of for Project/Service association to reduce the number of queries - Update tanuki logo highlight/loading colors + - Remove explicit Gitlab::Metrics.action assignments, are already automatic. - Use Git cached counters for branches and tags on project page - Filter parameters for request_uri value on instrumented transactions. - Cache user todo counts from TodoService diff --git a/lib/api/internal.rb b/lib/api/internal.rb index 3ac7b50c4ce..1d361569d59 100644 --- a/lib/api/internal.rb +++ b/lib/api/internal.rb @@ -23,8 +23,6 @@ module API end post "/allowed" do - Gitlab::Metrics.action = 'Grape#/internal/allowed' - status 200 actor = -- cgit v1.2.1 From 55982c3dbb148aa3303a67c965ee5ef773c8efdb Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Sat, 18 Jun 2016 21:40:59 +0100 Subject: Fixed placement of close button on merge requests --- app/views/projects/merge_requests/_discussion.html.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/projects/merge_requests/_discussion.html.haml b/app/views/projects/merge_requests/_discussion.html.haml index 393998f15b9..53dd300c35c 100644 --- a/app/views/projects/merge_requests/_discussion.html.haml +++ b/app/views/projects/merge_requests/_discussion.html.haml @@ -1,8 +1,8 @@ - content_for :note_actions do - if can?(current_user, :update_merge_request, @merge_request) - if @merge_request.open? - = link_to 'Close merge request', merge_request_path(@merge_request, merge_request: {state_event: :close }), method: :put, class: "btn btn-nr btn-comment btn-grouped btn-close close-mr-link js-note-target-close", title: "Close merge request", data: {original_text: "Close merge request", alternative_text: "Comment & close merge request"} + = link_to 'Close merge request', merge_request_path(@merge_request, merge_request: {state_event: :close }), method: :put, class: "btn btn-nr btn-comment btn-close close-mr-link js-note-target-close", title: "Close merge request", data: {original_text: "Close merge request", alternative_text: "Comment & close merge request"} - if @merge_request.closed? - = link_to 'Reopen merge request', merge_request_path(@merge_request, merge_request: {state_event: :reopen }), method: :put, class: "btn btn-nr btn-comment btn-grouped btn-reopen reopen-mr-link js-note-target-reopen", title: "Reopen merge request", data: {original_text: "Reopen merge request", alternative_text: "Comment & reopen merge request"} + = link_to 'Reopen merge request', merge_request_path(@merge_request, merge_request: {state_event: :reopen }), method: :put, class: "btn btn-nr btn-comment btn-reopen reopen-mr-link js-note-target-reopen", title: "Reopen merge request", data: {original_text: "Reopen merge request", alternative_text: "Comment & reopen merge request"} #notes= render "projects/notes/notes_with_form" -- cgit v1.2.1 From deca5ef200a0b6d5d965214ad71d13e359b03e77 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Tue, 7 Jun 2016 14:40:21 +0100 Subject: Refs dropdown is now loaded async --- app/assets/javascripts/gl_dropdown.js.coffee | 12 +++++---- app/assets/javascripts/project.js.coffee | 35 +++++++++++++++++++++++++++ app/assets/stylesheets/framework/selects.scss | 5 ---- app/assets/stylesheets/pages/projects.scss | 6 +++++ app/controllers/projects_controller.rb | 16 ++++++++++++ app/views/shared/_ref_switcher.html.haml | 9 ++++++- config/routes.rb | 1 + 7 files changed, 73 insertions(+), 11 deletions(-) diff --git a/app/assets/javascripts/gl_dropdown.js.coffee b/app/assets/javascripts/gl_dropdown.js.coffee index 2a8a1f05b35..f8a2db6d42c 100644 --- a/app/assets/javascripts/gl_dropdown.js.coffee +++ b/app/assets/javascripts/gl_dropdown.js.coffee @@ -58,7 +58,7 @@ class GitLabDropdownFilter filter: (search_text) -> data = @options.data() - if data? + if data? and not @options.filterByText results = data if search_text isnt '' @@ -102,10 +102,11 @@ class GitLabDropdownFilter $el = $(@) matches = fuzzaldrinPlus.match($el.text().trim(), search_text) - if matches.length - $el.show() - else - $el.hide() + if $el.is(':not(.dropdown-header)') + if matches.length + $el.show() + else + $el.hide() else elements.show() @@ -191,6 +192,7 @@ class GitLabDropdown if @options.filterable @filter = new GitLabDropdownFilter @filterInput, filterInputBlur: @filterInputBlur + filterByText: @options.filterByText remote: @options.filterRemote query: @options.data keys: searchFields diff --git a/app/assets/javascripts/project.js.coffee b/app/assets/javascripts/project.js.coffee index d12bad97a05..3ef5fcc636c 100644 --- a/app/assets/javascripts/project.js.coffee +++ b/app/assets/javascripts/project.js.coffee @@ -19,6 +19,7 @@ class @Project $('.clone').text(url) # Ref switcher + @initRefSwitcher() $('.project-refs-select').on 'change', -> $(@).parents('form').submit() @@ -50,3 +51,37 @@ class @Project changeProject: (url) -> window.location = url + + initRefSwitcher: -> + $('.js-project-refs-dropdown').each -> + $dropdown = $(@) + selected = $dropdown.data('selected') + + $dropdown.glDropdown( + data: (term, callback) -> + $.ajax( + url: $dropdown.data('refs-url') + ).done (refs) -> + callback(refs) + selectable: true + filterable: true + filterByText: true + fieldName: 'ref' + renderRow: (ref) -> + if ref.header? + "" + else + isActiveClass = if ref is selected then 'is-active' else '' + + "
  • + + #{ref} + +
  • " + id: (obj, $el) -> + $el.data('ref') + toggleLabel: (obj, $el) -> + $el.text().trim() + clicked: (e) -> + $dropdown.closest('form').submit() + ) diff --git a/app/assets/stylesheets/framework/selects.scss b/app/assets/stylesheets/framework/selects.scss index f242706ebe4..21d87cc9d34 100644 --- a/app/assets/stylesheets/framework/selects.scss +++ b/app/assets/stylesheets/framework/selects.scss @@ -165,11 +165,6 @@ background-size: 16px 16px !important; } -/** Branch/tag selector **/ -.project-refs-form .select2-container { - width: 160px !important; -} - .select2-results .select2-no-results, .select2-results .select2-searching, .select2-results .select2-ajax-error, diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss index f138a2f5387..093d5e18516 100644 --- a/app/assets/stylesheets/pages/projects.scss +++ b/app/assets/stylesheets/pages/projects.scss @@ -616,3 +616,9 @@ pre.light-well { color: $gl-text-green; } } + +.project-refs-form { + .dropdown-menu { + width: 300px; + } +} diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 8044c637825..0391d4a2442 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -251,6 +251,22 @@ class ProjectsController < Projects::ApplicationController } end + def refs + repository = @project.repository + + options = { + 'Branches' => repository.branch_names, + 'Tags' => VersionSorter.rsort(repository.tag_names) + } + + # If reference is commit id - we should add it to branch/tag selectbox + if @ref && !options.flatten.include?(@ref) && @ref =~ /\A[0-9a-zA-Z]{6,52}\z/ + options << {'Commits' => @ref} + end + + render json: options.to_json + end + private def determine_layout diff --git a/app/views/shared/_ref_switcher.html.haml b/app/views/shared/_ref_switcher.html.haml index eb2e1919e19..a84e53ea642 100644 --- a/app/views/shared/_ref_switcher.html.haml +++ b/app/views/shared/_ref_switcher.html.haml @@ -1,7 +1,14 @@ = form_tag switch_namespace_project_refs_path(@project.namespace, @project), method: :get, class: "project-refs-form" do - = select_tag "ref", grouped_options_refs, class: "project-refs-select select2 select2-sm" = hidden_field_tag :destination, destination - if defined?(path) = hidden_field_tag :path, path - @options && @options.each do |key, value| = hidden_field_tag key, value, id: nil + .dropdown + = dropdown_toggle @ref || @project.default_branch, { toggle: "dropdown", selected: @ref || @project.default_branch, refs_url: refs_namespace_project_path(@project.namespace, @project) }, { toggle_class: "js-project-refs-dropdown" } + .dropdown-menu.dropdown-menu-selectable + = dropdown_title "Switch branch/tag" + = dropdown_filter "Search branches and tags" + = dropdown_content + = dropdown_loading + -# = select_tag "ref", grouped_options_refs, class: "project-refs-select select2 select2-sm" diff --git a/config/routes.rb b/config/routes.rb index de6094fa0ed..a22559ebabc 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -479,6 +479,7 @@ Rails.application.routes.draw do get :download_export get :autocomplete_sources get :activity + get :refs end scope module: :projects do -- cgit v1.2.1 From d2362e2edf2b23318c6913535fe0ec3ea122d57e Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Wed, 8 Jun 2016 11:38:19 +0100 Subject: Tests fix for ref switcher --- app/assets/stylesheets/framework/panels.scss | 4 ++++ app/controllers/projects_controller.rb | 2 +- app/views/projects/badges/index.html.haml | 2 +- app/views/shared/_ref_switcher.html.haml | 3 +-- features/steps/project/network_graph.rb | 20 ++++++++++++++------ features/steps/project/source/browse_files.rb | 14 +++++++++++--- spec/features/projects/badges/list_spec.rb | 8 +++++--- 7 files changed, 37 insertions(+), 16 deletions(-) diff --git a/app/assets/stylesheets/framework/panels.scss b/app/assets/stylesheets/framework/panels.scss index ae7bdf14c40..874416e1007 100644 --- a/app/assets/stylesheets/framework/panels.scss +++ b/app/assets/stylesheets/framework/panels.scss @@ -9,6 +9,10 @@ margin-top: -2px; float: right; } + + .dropdown-menu-toggle { + line-height: 20px; + } } .panel-body { diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 0391d4a2442..aaa4e49eb42 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -261,7 +261,7 @@ class ProjectsController < Projects::ApplicationController # If reference is commit id - we should add it to branch/tag selectbox if @ref && !options.flatten.include?(@ref) && @ref =~ /\A[0-9a-zA-Z]{6,52}\z/ - options << {'Commits' => @ref} + options << { 'Commits' => @ref } end render json: options.to_json diff --git a/app/views/projects/badges/index.html.haml b/app/views/projects/badges/index.html.haml index ee63bc55a30..ac80951dd4f 100644 --- a/app/views/projects/badges/index.html.haml +++ b/app/views/projects/badges/index.html.haml @@ -7,7 +7,7 @@ %b Builds badge · = @build_badge.to_html .pull-right - = render 'shared/ref_switcher', destination: 'badges' + = render 'shared/ref_switcher', destination: 'badges', align_right: true .panel-body .row .col-md-2.text-center diff --git a/app/views/shared/_ref_switcher.html.haml b/app/views/shared/_ref_switcher.html.haml index a84e53ea642..b474ed00777 100644 --- a/app/views/shared/_ref_switcher.html.haml +++ b/app/views/shared/_ref_switcher.html.haml @@ -6,9 +6,8 @@ = hidden_field_tag key, value, id: nil .dropdown = dropdown_toggle @ref || @project.default_branch, { toggle: "dropdown", selected: @ref || @project.default_branch, refs_url: refs_namespace_project_path(@project.namespace, @project) }, { toggle_class: "js-project-refs-dropdown" } - .dropdown-menu.dropdown-menu-selectable + .dropdown-menu.dropdown-menu-selectable{ class: ("dropdown-menu-align-right" if local_assigns[:align_right]) } = dropdown_title "Switch branch/tag" = dropdown_filter "Search branches and tags" = dropdown_content = dropdown_loading - -# = select_tag "ref", grouped_options_refs, class: "project-refs-select select2 select2-sm" diff --git a/features/steps/project/network_graph.rb b/features/steps/project/network_graph.rb index 9b59b682676..019b3124a86 100644 --- a/features/steps/project/network_graph.rb +++ b/features/steps/project/network_graph.rb @@ -20,11 +20,11 @@ class Spinach::Features::ProjectNetworkGraph < Spinach::FeatureSteps end step 'page should select "master" in select box' do - expect(page).to have_selector '.select2-chosen', text: "master" + expect(page).to have_selector '.dropdown-menu-toggle', text: "master" end step 'page should select "v1.0.0" in select box' do - expect(page).to have_selector '.select2-chosen', text: "v1.0.0" + expect(page).to have_selector '.dropdown-menu-toggle', text: "v1.0.0" end step 'page should have "master" on graph' do @@ -40,11 +40,19 @@ class Spinach::Features::ProjectNetworkGraph < Spinach::FeatureSteps end When 'I switch ref to "feature"' do - select 'feature', from: 'ref' + first('.js-project-refs-dropdown').click + + page.within '.project-refs-form' do + click_link 'feature' + end end When 'I switch ref to "v1.0.0"' do - select 'v1.0.0', from: 'ref' + first('.js-project-refs-dropdown').click + + page.within '.project-refs-form' do + click_link 'v1.0.0' + end end When 'click "Show only selected branch" checkbox' do @@ -68,11 +76,11 @@ class Spinach::Features::ProjectNetworkGraph < Spinach::FeatureSteps end step 'page should select "feature" in select box' do - expect(page).to have_selector '.select2-chosen', text: "feature" + expect(page).to have_selector '.dropdown-menu-toggle', text: "feature" end step 'page should select "v1.0.0" in select box' do - expect(page).to have_selector '.select2-chosen', text: "v1.0.0" + expect(page).to have_selector '.dropdown-menu-toggle', text: "v1.0.0" end step 'page should have "feature" on graph' do diff --git a/features/steps/project/source/browse_files.rb b/features/steps/project/source/browse_files.rb index 79a3ed8197e..1c2567dae73 100644 --- a/features/steps/project/source/browse_files.rb +++ b/features/steps/project/source/browse_files.rb @@ -290,15 +290,23 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps end step "I switch ref to 'test'" do - select "'test'", from: 'ref' + first('.js-project-refs-dropdown').click + + page.within '.project-refs-form' do + click_link 'test' + end end step "I switch ref to fix" do - select "fix", from: 'ref' + first('.js-project-refs-dropdown').click + + page.within '.project-refs-form' do + click_link 'fix' + end end step "I see the ref 'test' has been selected" do - expect(page).to have_selector '.select2-chosen', text: "'test'" + expect(page).to have_selector '.dropdown-toggle', text: "'test'" end step "I visit the 'test' tree" do diff --git a/spec/features/projects/badges/list_spec.rb b/spec/features/projects/badges/list_spec.rb index 51be81d634c..01e90618a98 100644 --- a/spec/features/projects/badges/list_spec.rb +++ b/spec/features/projects/badges/list_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' feature 'list of badges' do - include Select2Helper - background do user = create(:user) project = create(:project) @@ -24,7 +22,11 @@ feature 'list of badges' do end scenario 'user changes current ref on badges list page', js: true do - select2('improve/awesome', from: '#ref') + first('.js-project-refs-dropdown').click + + page.within '.project-refs-form' do + click_link 'improve/awesome' + end expect(page).to have_content 'badges/improve/awesome/build.svg' end -- cgit v1.2.1 From ed0f26c223b5182fa2cb7a54bfd8ce155948deb2 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Wed, 8 Jun 2016 12:53:40 +0100 Subject: Escapes branch names before appending to dom --- app/assets/javascripts/project.js.coffee | 2 +- features/steps/project/source/browse_files.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/project.js.coffee b/app/assets/javascripts/project.js.coffee index 3ef5fcc636c..3b608cbd2a0 100644 --- a/app/assets/javascripts/project.js.coffee +++ b/app/assets/javascripts/project.js.coffee @@ -74,7 +74,7 @@ class @Project isActiveClass = if ref is selected then 'is-active' else '' "
  • - + #{ref}
  • " diff --git a/features/steps/project/source/browse_files.rb b/features/steps/project/source/browse_files.rb index 1c2567dae73..0fe046dcbf6 100644 --- a/features/steps/project/source/browse_files.rb +++ b/features/steps/project/source/browse_files.rb @@ -306,7 +306,7 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps end step "I see the ref 'test' has been selected" do - expect(page).to have_selector '.dropdown-toggle', text: "'test'" + expect(page).to have_selector '.dropdown-toggle-text', text: "'test'" end step "I visit the 'test' tree" do -- cgit v1.2.1 From 3c8c9129654d49281024bfb444d95e5d7c35bcbd Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Wed, 8 Jun 2016 13:29:18 +0100 Subject: Pulls back tags if any exist --- app/controllers/projects_controller.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index aaa4e49eb42..5155ae1b104 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -253,15 +253,19 @@ class ProjectsController < Projects::ApplicationController def refs repository = @project.repository + tags = VersionSorter.rsort(repository.tag_names) options = { 'Branches' => repository.branch_names, - 'Tags' => VersionSorter.rsort(repository.tag_names) } + if tags.any? + options['Tags'] = tags + end + # If reference is commit id - we should add it to branch/tag selectbox if @ref && !options.flatten.include?(@ref) && @ref =~ /\A[0-9a-zA-Z]{6,52}\z/ - options << { 'Commits' => @ref } + options['Commits'] = @ref end render json: options.to_json -- cgit v1.2.1 From 68c9981013b1aa87dde7421ffe5db0a342d55ee8 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 16 Jun 2016 12:53:58 +0100 Subject: Correctly adds commit ID into dropdown Removes un-used method Fixes other Ruby issues --- app/assets/javascripts/project.js.coffee | 2 ++ app/controllers/projects_controller.rb | 14 +++++----- app/helpers/application_helper.rb | 16 ------------ app/views/shared/_ref_switcher.html.haml | 3 ++- spec/helpers/application_helper_spec.rb | 45 -------------------------------- 5 files changed, 10 insertions(+), 70 deletions(-) diff --git a/app/assets/javascripts/project.js.coffee b/app/assets/javascripts/project.js.coffee index 3b608cbd2a0..54c539d5f9b 100644 --- a/app/assets/javascripts/project.js.coffee +++ b/app/assets/javascripts/project.js.coffee @@ -61,6 +61,8 @@ class @Project data: (term, callback) -> $.ajax( url: $dropdown.data('refs-url') + data: + ref: $dropdown.data('ref') ).done (refs) -> callback(refs) selectable: true diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 5155ae1b104..e2311971f70 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -252,20 +252,18 @@ class ProjectsController < Projects::ApplicationController end def refs - repository = @project.repository - tags = VersionSorter.rsort(repository.tag_names) - options = { - 'Branches' => repository.branch_names, + 'Branches' => @repository.branch_names, } - if tags.any? - options['Tags'] = tags + unless @repository.tag_count.zero? + options['Tags'] = VersionSorter.rsort(@repository.tag_names) end # If reference is commit id - we should add it to branch/tag selectbox - if @ref && !options.flatten.include?(@ref) && @ref =~ /\A[0-9a-zA-Z]{6,52}\z/ - options['Commits'] = @ref + ref = params[:ref] + if ref && !options.flatten.include?(ref) && ref =~ /\A[0-9a-zA-Z]{6,52}\z/ + options['Commits'] = [ref] end render json: options.to_json diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 439b015b3b8..82421d74de9 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -101,22 +101,6 @@ module ApplicationHelper 'Never' end - def grouped_options_refs - repository = @project.repository - - options = [ - ['Branches', repository.branch_names], - ['Tags', VersionSorter.rsort(repository.tag_names)] - ] - - # If reference is commit id - we should add it to branch/tag selectbox - if @ref && !options.flatten.include?(@ref) && @ref =~ /\A[0-9a-zA-Z]{6,52}\z/ - options << ['Commit', [@ref]] - end - - grouped_options_for_select(options, @ref || @project.default_branch) - end - # Define whenever show last push event # with suggestion to create MR def show_last_push_widget?(event) diff --git a/app/views/shared/_ref_switcher.html.haml b/app/views/shared/_ref_switcher.html.haml index b474ed00777..947968074e1 100644 --- a/app/views/shared/_ref_switcher.html.haml +++ b/app/views/shared/_ref_switcher.html.haml @@ -1,3 +1,4 @@ +- dropdown_toggle_text = @ref || @project.default_branch = form_tag switch_namespace_project_refs_path(@project.namespace, @project), method: :get, class: "project-refs-form" do = hidden_field_tag :destination, destination - if defined?(path) @@ -5,7 +6,7 @@ - @options && @options.each do |key, value| = hidden_field_tag key, value, id: nil .dropdown - = dropdown_toggle @ref || @project.default_branch, { toggle: "dropdown", selected: @ref || @project.default_branch, refs_url: refs_namespace_project_path(@project.namespace, @project) }, { toggle_class: "js-project-refs-dropdown" } + = dropdown_toggle dropdown_toggle_text, { toggle: "dropdown", selected: @ref || @project.default_branch, ref: @ref, refs_url: refs_namespace_project_path(@project.namespace, @project) }, { toggle_class: "js-project-refs-dropdown" } .dropdown-menu.dropdown-menu-selectable{ class: ("dropdown-menu-align-right" if local_assigns[:align_right]) } = dropdown_title "Switch branch/tag" = dropdown_filter "Search branches and tags" diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index f6c1005d265..bb28866f010 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -174,51 +174,6 @@ describe ApplicationHelper do end end - describe 'grouped_options_refs' do - let(:options) { helper.grouped_options_refs } - let(:project) { create(:project) } - - before do - assign(:project, project) - - # Override Rails' grouped_options_for_select helper to just return the - # first argument (`options`), since it's easier to work with than the - # generated HTML. - allow(helper).to receive(:grouped_options_for_select). - and_wrap_original { |_, *args| args.first } - end - - it 'includes a list of branch names' do - expect(options[0][0]).to eq('Branches') - expect(options[0][1]).to include('master', 'feature') - end - - it 'includes a list of tag names' do - expect(options[1][0]).to eq('Tags') - expect(options[1][1]).to include('v1.0.0', 'v1.1.0') - end - - it 'includes a specific commit ref if defined' do - # Must be an instance variable - ref = '2ed06dc41dbb5936af845b87d79e05bbf24c73b8' - assign(:ref, ref) - - expect(options[2][0]).to eq('Commit') - expect(options[2][1]).to eq([ref]) - end - - it 'sorts tags in a natural order' do - # Stub repository.tag_names to make sure we get some valid testing data - expect(project.repository).to receive(:tag_names). - and_return(['v1.0.9', 'v1.0.10', 'v2.0', 'v3.1.4.2', 'v2.0rc1¿', - 'v1.0.9a', 'v2.0-rc1', 'v2.0rc2']) - - expect(options[1][1]). - to eq(['v3.1.4.2', 'v2.0', 'v2.0rc2', 'v2.0rc1¿', 'v2.0-rc1', 'v1.0.10', - 'v1.0.9', 'v1.0.9a']) - end - end - describe 'simple_sanitize' do let(:a_tag) { 'Foo' } -- cgit v1.2.1 From c240cad59a84e090e12d7ce6db94983405aa1813 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 16 Jun 2016 14:23:10 +0100 Subject: Fixed Ruby to use exclude --- app/controllers/projects_controller.rb | 2 +- app/views/shared/_ref_switcher.html.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index e2311971f70..b65730b37c9 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -262,7 +262,7 @@ class ProjectsController < Projects::ApplicationController # If reference is commit id - we should add it to branch/tag selectbox ref = params[:ref] - if ref && !options.flatten.include?(ref) && ref =~ /\A[0-9a-zA-Z]{6,52}\z/ + if ref && options.flatten.exclude?(ref) && ref =~ /\A[0-9a-zA-Z]{6,52}\z/ options['Commits'] = [ref] end diff --git a/app/views/shared/_ref_switcher.html.haml b/app/views/shared/_ref_switcher.html.haml index 947968074e1..ea7162d4d63 100644 --- a/app/views/shared/_ref_switcher.html.haml +++ b/app/views/shared/_ref_switcher.html.haml @@ -6,7 +6,7 @@ - @options && @options.each do |key, value| = hidden_field_tag key, value, id: nil .dropdown - = dropdown_toggle dropdown_toggle_text, { toggle: "dropdown", selected: @ref || @project.default_branch, ref: @ref, refs_url: refs_namespace_project_path(@project.namespace, @project) }, { toggle_class: "js-project-refs-dropdown" } + = dropdown_toggle dropdown_toggle_text, { toggle: "dropdown", selected: dropdown_toggle_text, ref: @ref, refs_url: refs_namespace_project_path(@project.namespace, @project) }, { toggle_class: "js-project-refs-dropdown" } .dropdown-menu.dropdown-menu-selectable{ class: ("dropdown-menu-align-right" if local_assigns[:align_right]) } = dropdown_title "Switch branch/tag" = dropdown_filter "Search branches and tags" -- cgit v1.2.1 From 8685b3f80a9a653849776a83b7a968725a8ae1f0 Mon Sep 17 00:00:00 2001 From: Connor Shea Date: Tue, 14 Jun 2016 12:15:21 -0600 Subject: Add borders to images in issues, MRs, and Help. --- CHANGELOG | 1 + app/assets/stylesheets/pages/help.scss | 7 +++++++ app/assets/stylesheets/pages/issuable.scss | 7 +++++++ app/assets/stylesheets/pages/notes.scss | 7 +++++++ 4 files changed, 22 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 44e6a194745..a0c681f520d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -18,6 +18,7 @@ v 8.9.0 (unreleased) - Redesign all Devise emails. !4297 - Don't show 'Leave Project' to group members - Fix wiki page events' webhook to point to the wiki repository + - Add a border around images to differentiate them from the background. - Don't show tags for revert and cherry-pick operations - Fix issue todo not remove when leave project !4150 (Long Nguyen) - Allow customisable text on the 'nearly there' page after a user signs up diff --git a/app/assets/stylesheets/pages/help.scss b/app/assets/stylesheets/pages/help.scss index 4a95b7b852e..204c0eea487 100644 --- a/app/assets/stylesheets/pages/help.scss +++ b/app/assets/stylesheets/pages/help.scss @@ -57,4 +57,11 @@ .documentation { padding: 7px; + + // Border around images in the help pages. + img { + border: 1px solid $table-border-gray; + padding: 5px; + margin: 5px; + } } diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss index 687117233f6..bf6f44161df 100644 --- a/app/assets/stylesheets/pages/issuable.scss +++ b/app/assets/stylesheets/pages/issuable.scss @@ -4,6 +4,13 @@ margin-right: 1px; } } + + // Border around images in issue and MR descriptions. + .description img { + border: 1px solid $table-border-gray; + padding: 5px; + margin: 5px; + } } .issuable-filter-count { diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss index 35d728aec83..44db5b156ce 100644 --- a/app/assets/stylesheets/pages/notes.scss +++ b/app/assets/stylesheets/pages/notes.scss @@ -117,6 +117,13 @@ ul.notes { code { word-break: keep-all; } + + // Border around images in issue and MR comments. + img { + border: 1px solid $table-border-gray; + padding: 5px; + margin: 5px 0; + } } } -- cgit v1.2.1 From b118fccb0dec94f4463f93de1d4483855dba2b14 Mon Sep 17 00:00:00 2001 From: Connor Shea Date: Thu, 16 Jun 2016 12:59:07 -0600 Subject: Fix regressions in the design of the project statistics bar. Fix #18734. --- app/assets/stylesheets/pages/projects.scss | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss index f138a2f5387..2223489c812 100644 --- a/app/assets/stylesheets/pages/projects.scss +++ b/app/assets/stylesheets/pages/projects.scss @@ -373,7 +373,7 @@ a.deploy-project-label { .project-stats { margin-top: $gl-padding; margin-bottom: 0; - padding: 16px 0; + padding: 0; background-color: $white-light; font-size: 0; @@ -382,13 +382,14 @@ a.deploy-project-label { } .nav li { - display: inline; + display: inline-block; + margin: 16px 0; + margin-right: 16px; } .nav > li > a { background-color: transparent; - margin-right: 12px; - padding: 0 10px; + padding: 5px 10px; font-size: 15px; color: $notes-light-color; } @@ -402,9 +403,14 @@ a.deploy-project-label { font-size: 17px; } - li.missing a { - color: #5a6069; + li.missing { border: 1px dashed #dce0e5; + border-radius: 2px; + + a { + color: #5a6069; + display: block; + } &:hover { background-color: #f0f2f5; -- cgit v1.2.1 From 0997a3c9c559942b324b5c5641afd017cbed761e Mon Sep 17 00:00:00 2001 From: Connor Shea Date: Sun, 19 Jun 2016 17:52:19 -0600 Subject: Use existing color variables. --- app/assets/stylesheets/pages/projects.scss | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss index 2223489c812..76cc2ebe21d 100644 --- a/app/assets/stylesheets/pages/projects.scss +++ b/app/assets/stylesheets/pages/projects.scss @@ -404,16 +404,16 @@ a.deploy-project-label { } li.missing { - border: 1px dashed #dce0e5; - border-radius: 2px; + border: 1px dashed $border-gray-light; + border-radius: $border-radius-default; a { - color: #5a6069; + color: $notes-light-color; display: block; } &:hover { - background-color: #f0f2f5; + background-color: $gray-normal; } } -- cgit v1.2.1 From 15789e8eb507cef40f7c156c1920821d0ca9c352 Mon Sep 17 00:00:00 2001 From: Connor Shea Date: Sun, 19 Jun 2016 18:31:29 -0600 Subject: Emoji shouldn't have borders. #EmojiWithoutBorders --- app/assets/stylesheets/pages/help.scss | 2 +- app/assets/stylesheets/pages/issuable.scss | 2 +- app/assets/stylesheets/pages/notes.scss | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/assets/stylesheets/pages/help.scss b/app/assets/stylesheets/pages/help.scss index 204c0eea487..0b710ef168b 100644 --- a/app/assets/stylesheets/pages/help.scss +++ b/app/assets/stylesheets/pages/help.scss @@ -59,7 +59,7 @@ padding: 7px; // Border around images in the help pages. - img { + img:not(.emoji) { border: 1px solid $table-border-gray; padding: 5px; margin: 5px; diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss index bf6f44161df..21ff6ab71f0 100644 --- a/app/assets/stylesheets/pages/issuable.scss +++ b/app/assets/stylesheets/pages/issuable.scss @@ -6,7 +6,7 @@ } // Border around images in issue and MR descriptions. - .description img { + .description img:not(.emoji) { border: 1px solid $table-border-gray; padding: 5px; margin: 5px; diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss index 44db5b156ce..df0c241bbf1 100644 --- a/app/assets/stylesheets/pages/notes.scss +++ b/app/assets/stylesheets/pages/notes.scss @@ -119,7 +119,7 @@ ul.notes { } // Border around images in issue and MR comments. - img { + img:not(.emoji) { border: 1px solid $table-border-gray; padding: 5px; margin: 5px 0; -- cgit v1.2.1 From a0173bc46fdb18861fc65fe538b87499d5679c92 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Mon, 20 Jun 2016 08:35:50 +0100 Subject: Set path for pinned nav cookie --- app/assets/javascripts/application.js.coffee | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/application.js.coffee b/app/assets/javascripts/application.js.coffee index 2f9f6c3ef5b..4529c514555 100644 --- a/app/assets/javascripts/application.js.coffee +++ b/app/assets/javascripts/application.js.coffee @@ -257,7 +257,7 @@ $ -> # Sidenav pinning if $(window).width() < 1440 and $.cookie('pin_nav') is 'true' - $.cookie('pin_nav', 'false') + $.cookie('pin_nav', 'false', { path: '/' }) $('.page-with-sidebar') .toggleClass('page-sidebar-collapsed page-sidebar-expanded') .removeClass('page-sidebar-pinned') @@ -271,7 +271,7 @@ $ -> $(this).toggleClass 'is-active' if $.cookie('pin_nav') is 'true' - $.cookie 'pin_nav', 'false' + $.cookie 'pin_nav', 'false', { path: '/' } $('.page-with-sidebar') .removeClass('page-sidebar-pinned') .toggleClass('page-sidebar-collapsed page-sidebar-expanded') @@ -279,6 +279,6 @@ $ -> .removeClass('header-pinned-nav') .toggleClass('header-collapsed header-expanded') else - $.cookie 'pin_nav', 'true' + $.cookie 'pin_nav', 'true', { path: '/' } $('.page-with-sidebar').addClass('page-sidebar-pinned') $('.navbar-fixed-top').addClass('header-pinned-nav') -- cgit v1.2.1 From 657aaca36369c347afae5b1c73e1065817f0f0c5 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Mon, 20 Jun 2016 08:47:38 +0100 Subject: Fixed mobile styling --- app/assets/stylesheets/pages/note_form.scss | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/app/assets/stylesheets/pages/note_form.scss b/app/assets/stylesheets/pages/note_form.scss index 577dddae741..de5ccbe2b6c 100644 --- a/app/assets/stylesheets/pages/note_form.scss +++ b/app/assets/stylesheets/pages/note_form.scss @@ -219,3 +219,16 @@ float: left; } } + +.note-form-actions { + @media (max-width: $screen-xs-max) { + .btn { + float: none; + width: 100%; + + &:not(:last-child) { + margin-bottom: 10px; + } + } + } +} -- cgit v1.2.1 From b543a96e1c71c9233f9425cee2435cd0497adc4c Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Mon, 20 Jun 2016 08:54:57 +0100 Subject: Added text_utility to JS tests --- spec/javascripts/issue_spec.js.coffee | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/spec/javascripts/issue_spec.js.coffee b/spec/javascripts/issue_spec.js.coffee index ea27f36e9b5..71f0c1076c5 100644 --- a/spec/javascripts/issue_spec.js.coffee +++ b/spec/javascripts/issue_spec.js.coffee @@ -1,3 +1,4 @@ +#= require lib/text_utility #= require issue describe 'Issue', -> @@ -38,7 +39,7 @@ describe 'reopen/close issue', -> expect(typeof $btnClose.prop('disabled')).toBe('undefined') $btnClose.trigger('click') - + expect($btnReopen).toBeVisible() expect($btnClose).toBeHidden() expect($('div.status-box-closed')).toBeVisible() @@ -50,7 +51,7 @@ describe 'reopen/close issue', -> expect(req.type).toBe('PUT') expect(req.url).toBe('http://goesnowhere.nothing/whereami') req.success saved: false - + $btnClose = $('a.btn-close') $btnReopen = $('a.btn-reopen') $btnClose.attr('href','http://goesnowhere.nothing/whereami') @@ -59,7 +60,7 @@ describe 'reopen/close issue', -> expect(typeof $btnClose.prop('disabled')).toBe('undefined') $btnClose.trigger('click') - + expect($btnReopen).toBeHidden() expect($btnClose).toBeVisible() expect($('div.status-box-closed')).toBeHidden() @@ -73,7 +74,7 @@ describe 'reopen/close issue', -> expect(req.type).toBe('PUT') expect(req.url).toBe('http://goesnowhere.nothing/whereami') req.error() - + $btnClose = $('a.btn-close') $btnReopen = $('a.btn-reopen') $btnClose.attr('href','http://goesnowhere.nothing/whereami') @@ -82,7 +83,7 @@ describe 'reopen/close issue', -> expect(typeof $btnClose.prop('disabled')).toBe('undefined') $btnClose.trigger('click') - + expect($btnReopen).toBeHidden() expect($btnClose).toBeVisible() expect($('div.status-box-closed')).toBeHidden() @@ -105,4 +106,4 @@ describe 'reopen/close issue', -> expect($btnReopen).toBeHidden() expect($btnClose).toBeVisible() expect($('div.status-box-open')).toBeVisible() - expect($('div.status-box-closed')).toBeHidden() \ No newline at end of file + expect($('div.status-box-closed')).toBeHidden() -- cgit v1.2.1 From 60ef0dd20c91fd8d8f04ec139edaa07dbab86d1b Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Mon, 20 Jun 2016 16:03:52 +0800 Subject: Use .has-tooltip as suggested at: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/4093#note_12533926 --- app/views/projects/runners/_runner.html.haml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/views/projects/runners/_runner.html.haml b/app/views/projects/runners/_runner.html.haml index fbd94c34591..13113f9b88f 100644 --- a/app/views/projects/runners/_runner.html.haml +++ b/app/views/projects/runners/_runner.html.haml @@ -5,8 +5,7 @@ - if @runners.include?(runner) = link_to runner.short_sha, runner_path(runner) - if runner.locked? - %small{title: 'Exclusive to this project'} - = icon('lock') + = icon('lock', class: 'has-tooltip', title: 'Exclusive to this project') %small = link_to edit_namespace_project_runner_path(@project.namespace, @project, runner) do %i.fa.fa-edit.btn -- cgit v1.2.1 From 34e313920d8dc57dfdc92e3740fb30f0a32ebd71 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Mon, 20 Jun 2016 09:47:43 +0100 Subject: Fixed hover of date picker calendar --- app/assets/stylesheets/framework/dropdowns.scss | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss index d4d579a083d..00111dfa706 100644 --- a/app/assets/stylesheets/framework/dropdowns.scss +++ b/app/assets/stylesheets/framework/dropdowns.scss @@ -461,10 +461,12 @@ } } - .ui-state-active, - .ui-state-hover { - color: $md-link-color; - background-color: $calendar-hover-bg; + .ui-datepicker-calendar { + .ui-state-hover, + .ui-state-active { + color: #fff; + border: 0; + } } .ui-datepicker-prev, -- cgit v1.2.1 From 4efc1c4a68538126bc4cfad6d9b60710bee36f14 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Mon, 20 Jun 2016 16:52:05 +0800 Subject: Rename according to: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/4093#note_12563922 For clarification and consistency --- app/controllers/projects/runners_controller.rb | 6 +++--- app/models/ci/runner.rb | 6 +++--- app/views/projects/runners/_runner.html.haml | 4 ++-- app/views/projects/runners/_specific_runners.html.haml | 10 +++++----- spec/models/ci/runner_spec.rb | 14 +++++++------- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/app/controllers/projects/runners_controller.rb b/app/controllers/projects/runners_controller.rb index 798d668f251..53c36635efe 100644 --- a/app/controllers/projects/runners_controller.rb +++ b/app/controllers/projects/runners_controller.rb @@ -5,9 +5,9 @@ class Projects::RunnersController < Projects::ApplicationController layout 'project_settings' def index - @runners = project.runners.ordered - @specific_runners = current_user.ci_authorized_runners. - available_for(project).ordered.page(params[:page]).per(20) + @project_runners = project.runners.ordered + @assignable_runners = current_user.ci_authorized_runners. + assignable_for(project).ordered.page(params[:page]).per(20) @shared_runners = Ci::Runner.shared.active @shared_runners_count = @shared_runners.count(:all) end diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb index fa5cf03baec..b64ec79ec2b 100644 --- a/app/models/ci/runner.rb +++ b/app/models/ci/runner.rb @@ -26,7 +26,7 @@ module Ci .where("ci_runner_projects.gl_project_id = :project_id OR ci_runners.is_shared = true", project_id: project_id) end - scope :available_for, ->(project) do + scope :assignable_for, ->(project) do # FIXME: That `to_sql` is needed to workaround a weird Rails bug. # Without that, placeholders would miss one and couldn't match. where(locked: false). @@ -99,7 +99,7 @@ module Ci end def can_pick?(build) - available_for?(build.project) && accepting_tags?(build) + assignable_for?(build.project) && accepting_tags?(build) end def only_for?(project) @@ -123,7 +123,7 @@ module Ci end end - def available_for?(project) + def assignable_for?(project) !locked? || projects.exists?(id: project.id) end diff --git a/app/views/projects/runners/_runner.html.haml b/app/views/projects/runners/_runner.html.haml index 13113f9b88f..3cf66bbcb4a 100644 --- a/app/views/projects/runners/_runner.html.haml +++ b/app/views/projects/runners/_runner.html.haml @@ -2,7 +2,7 @@ %h4 = runner_status_icon(runner) %span.monospace - - if @runners.include?(runner) + - if @project_runners.include?(runner) = link_to runner.short_sha, runner_path(runner) - if runner.locked? = icon('lock', class: 'has-tooltip', title: 'Exclusive to this project') @@ -13,7 +13,7 @@ = runner.short_sha .pull-right - - if @runners.include?(runner) + - if @project_runners.include?(runner) - if runner.belongs_to_one_project? = link_to 'Remove runner', runner_path(runner), data: { confirm: "Are you sure?" }, method: :delete, class: 'btn btn-danger btn-sm' - else diff --git a/app/views/projects/runners/_specific_runners.html.haml b/app/views/projects/runners/_specific_runners.html.haml index 8ae9f0d95f7..d469dda5b81 100644 --- a/app/views/projects/runners/_specific_runners.html.haml +++ b/app/views/projects/runners/_specific_runners.html.haml @@ -17,13 +17,13 @@ Start runner! -- if @runners.any? +- if @project_runners.any? %h4.underlined-title Runners activated for this project %ul.bordered-list.activated-specific-runners - = render partial: 'runner', collection: @runners, as: :runner + = render partial: 'runner', collection: @project_runners, as: :runner -- if @specific_runners.any? +- if @assignable_runners.any? %h4.underlined-title Available specific runners %ul.bordered-list.available-specific-runners - = render partial: 'runner', collection: @specific_runners, as: :runner - = paginate @specific_runners + = render partial: 'runner', collection: @assignable_runners, as: :runner + = paginate @assignable_runners diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb index c7248ef1384..ef65eb99328 100644 --- a/spec/models/ci/runner_spec.rb +++ b/spec/models/ci/runner_spec.rb @@ -263,7 +263,7 @@ describe Ci::Runner, models: true do end end - describe '.available_for' do + describe '.assignable_for' do let(:runner) { create(:ci_runner) } let(:project) { create(:project) } let(:another_project) { create(:project) } @@ -278,13 +278,13 @@ describe Ci::Runner, models: true do end context 'does not give owned runner' do - subject { Ci::Runner.available_for(project) } + subject { Ci::Runner.assignable_for(project) } it { is_expected.to be_empty } end context 'does not give shared runner' do - subject { Ci::Runner.available_for(another_project) } + subject { Ci::Runner.assignable_for(another_project) } it { is_expected.to be_empty } end @@ -292,13 +292,13 @@ describe Ci::Runner, models: true do context 'with unlocked runner' do context 'does not give owned runner' do - subject { Ci::Runner.available_for(project) } + subject { Ci::Runner.assignable_for(project) } it { is_expected.to be_empty } end context 'does give a specific runner' do - subject { Ci::Runner.available_for(another_project) } + subject { Ci::Runner.assignable_for(another_project) } it { is_expected.to contain_exactly(runner) } end @@ -310,13 +310,13 @@ describe Ci::Runner, models: true do end context 'does not give owned runner' do - subject { Ci::Runner.available_for(project) } + subject { Ci::Runner.assignable_for(project) } it { is_expected.to be_empty } end context 'does not give a locked runner' do - subject { Ci::Runner.available_for(another_project) } + subject { Ci::Runner.assignable_for(another_project) } it { is_expected.to be_empty } end -- cgit v1.2.1 From 73d431731f9f749557aa755848af3aa4e1c4cc9f Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 20 Jun 2016 12:43:40 +0300 Subject: Move appearance settings as sub tab to application settings Signed-off-by: Dmitriy Zaporozhets --- app/views/admin/appearances/show.html.haml | 10 +++++----- app/views/admin/application_settings/_head.html.haml | 11 +++++++++++ app/views/admin/application_settings/show.html.haml | 9 ++++++--- app/views/layouts/nav/_admin.html.haml | 7 +------ 4 files changed, 23 insertions(+), 14 deletions(-) create mode 100644 app/views/admin/application_settings/_head.html.haml diff --git a/app/views/admin/appearances/show.html.haml b/app/views/admin/appearances/show.html.haml index 089e8e4cb7a..e220f4956cb 100644 --- a/app/views/admin/appearances/show.html.haml +++ b/app/views/admin/appearances/show.html.haml @@ -1,7 +1,7 @@ +- @no_container = true - page_title "Appearance" -%h3.page-title - Appearance settings -%p.light - You can modify the look and feel of GitLab here += render "admin/application_settings/head" -= render 'form' +%div{ class: (container_class) } + .prepend-top-default + = render 'form' diff --git a/app/views/admin/application_settings/_head.html.haml b/app/views/admin/application_settings/_head.html.haml new file mode 100644 index 00000000000..de919b298c1 --- /dev/null +++ b/app/views/admin/application_settings/_head.html.haml @@ -0,0 +1,11 @@ +.nav-links.sub-nav + %ul{ class: (container_class) } + = nav_link(controller: :application_settings) do + = link_to admin_application_settings_path, title: 'Settings' do + %span + General + + = nav_link(controller: :appearances) do + = link_to admin_appearances_path, title: 'Appearances' do + %span + Appearance diff --git a/app/views/admin/application_settings/show.html.haml b/app/views/admin/application_settings/show.html.haml index e9c7ca9d5aa..82588c275d0 100644 --- a/app/views/admin/application_settings/show.html.haml +++ b/app/views/admin/application_settings/show.html.haml @@ -1,4 +1,7 @@ +- @no_container = true - page_title "Settings" -%h3.page-title Settings -%hr -= render 'form' += render "admin/application_settings/head" + +%div{ class: (container_class) } + .prepend-top-default + = render 'form' diff --git a/app/views/layouts/nav/_admin.html.haml b/app/views/layouts/nav/_admin.html.haml index f02ac949699..c6d8b17a1e5 100644 --- a/app/views/layouts/nav/_admin.html.haml +++ b/app/views/layouts/nav/_admin.html.haml @@ -21,11 +21,6 @@ %span Hooks - = nav_link(controller: :appearances) do - = link_to admin_appearances_path, title: 'Appearances' do - %span - Appearance - = nav_link(controller: :applications) do = link_to admin_applications_path, title: 'Applications' do %span @@ -53,7 +48,7 @@ %span Spam Logs - = nav_link(controller: :application_settings, html_options: { class: 'separate-item'}) do + = nav_link(controller: [:application_settings, :appearances]) do = link_to admin_application_settings_path, title: 'Settings' do %span Settings -- cgit v1.2.1 From b31c5052f9acf5d9118b2b81b556199279e7ca30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Mon, 20 Jun 2016 12:10:37 +0200 Subject: Fallback to group's owners/masters when a project has none MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A project in a group can have no explicit owners/masters, in that case we fallbacks to the group's owners/masters. Signed-off-by: Rémy Coutable --- app/mailers/emails/members.rb | 5 ++++ spec/mailers/notify_spec.rb | 61 +++++++++++++++++++++++++++++++++---------- 2 files changed, 52 insertions(+), 14 deletions(-) diff --git a/app/mailers/emails/members.rb b/app/mailers/emails/members.rb index 6dde2e9847d..45311690293 100644 --- a/app/mailers/emails/members.rb +++ b/app/mailers/emails/members.rb @@ -12,6 +12,11 @@ module Emails @member_id = member_id admins = member_source.members.owners_and_masters.includes(:user).pluck(:notification_email) + # A project in a group can have no explicit owners/masters, in that case + # we fallbacks to the group's owners/masters. + if admins.empty? && member_source.respond_to?(:group) && member_source.group + admins = member_source.group.members.owners_and_masters.includes(:user).pluck(:notification_email) + end mail(to: admins, subject: subject("Request to join the #{member_source.human_name} #{member_source.model_name.singular}")) diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb index 1e6eb20ab39..ae55a01ebea 100644 --- a/spec/mailers/notify_spec.rb +++ b/spec/mailers/notify_spec.rb @@ -401,23 +401,56 @@ describe Notify do end describe 'project access requested' do - let(:project) { create(:project) } - let(:user) { create(:user) } - let(:project_member) do - project.request_access(user) - project.members.request.find_by(user_id: user.id) + context 'for a project in a user namespace' do + let(:project) { create(:project).tap { |p| p.team << [p.owner, :master, p.owner] } } + let(:user) { create(:user) } + let(:project_member) do + project.request_access(user) + project.members.request.find_by(user_id: user.id) + end + subject { Notify.member_access_requested_email('project', project_member.id) } + + it_behaves_like 'an email sent from GitLab' + it_behaves_like 'it should not have Gmail Actions links' + it_behaves_like "a user cannot unsubscribe through footer link" + + it 'contains all the useful information' do + to_emails = subject.header[:to].addrs + expect(to_emails.size).to eq(1) + expect(to_emails[0].address).to eq(project.members.owners_and_masters.first.user.notification_email) + + is_expected.to have_subject "Request to join the #{project.name_with_namespace} project" + is_expected.to have_body_text /#{project.name_with_namespace}/ + is_expected.to have_body_text /#{namespace_project_project_members_url(project.namespace, project)}/ + is_expected.to have_body_text /#{project_member.human_access}/ + end end - subject { Notify.member_access_requested_email('project', project_member.id) } - it_behaves_like 'an email sent from GitLab' - it_behaves_like 'it should not have Gmail Actions links' - it_behaves_like "a user cannot unsubscribe through footer link" + context 'for a project in a group' do + let(:group_owner) { create(:user) } + let(:group) { create(:group).tap { |g| g.add_owner(group_owner) } } + let(:project) { create(:project, namespace: group) } + let(:user) { create(:user) } + let(:project_member) do + project.request_access(user) + project.members.request.find_by(user_id: user.id) + end + subject { Notify.member_access_requested_email('project', project_member.id) } - it 'contains all the useful information' do - is_expected.to have_subject "Request to join the #{project.name_with_namespace} project" - is_expected.to have_body_text /#{project.name_with_namespace}/ - is_expected.to have_body_text /#{namespace_project_project_members_url(project.namespace, project)}/ - is_expected.to have_body_text /#{project_member.human_access}/ + it_behaves_like 'an email sent from GitLab' + it_behaves_like 'it should not have Gmail Actions links' + it_behaves_like "a user cannot unsubscribe through footer link" + + it 'contains all the useful information' do + to_emails = subject.header[:to].addrs + expect(to_emails.size).to eq(1) + expect(to_emails[0].address).to eq(group.members.owners_and_masters.first.user.notification_email) + + is_expected.to have_subject "Request to join the #{project.name_with_namespace} project" + is_expected.to have_body_text /#{project.name_with_namespace}/ + is_expected.to have_body_text /#{namespace_project_project_members_url(project.namespace, project)}/ + is_expected.to have_body_text /#{project_member.human_access}/ + end end end -- cgit v1.2.1 From 608271626d44c950fffc96ab54ecdaf60bc5f490 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 20 Jun 2016 12:50:36 +0300 Subject: Fix admin appearance settings preview Signed-off-by: Dmitriy Zaporozhets --- app/controllers/admin/appearances_controller.rb | 1 + app/views/admin/appearances/_form.html.haml | 2 +- app/views/admin/appearances/preview.html.haml | 34 +++++-------------------- 3 files changed, 9 insertions(+), 28 deletions(-) diff --git a/app/controllers/admin/appearances_controller.rb b/app/controllers/admin/appearances_controller.rb index 26cf74e4849..4b0ec54b3f4 100644 --- a/app/controllers/admin/appearances_controller.rb +++ b/app/controllers/admin/appearances_controller.rb @@ -5,6 +5,7 @@ class Admin::AppearancesController < Admin::ApplicationController end def preview + render 'preview', layout: 'devise' end def create diff --git a/app/views/admin/appearances/_form.html.haml b/app/views/admin/appearances/_form.html.haml index d88f3ad314d..dc083e50178 100644 --- a/app/views/admin/appearances/_form.html.haml +++ b/app/views/admin/appearances/_form.html.haml @@ -46,7 +46,7 @@ Maximum file size is 1MB. Pages are optimized for a 72x72 px header logo .form-actions - = f.submit 'Save', class: 'btn btn-save' + = f.submit 'Save', class: 'btn btn-save append-right-10' - if @appearance.persisted? = link_to 'Preview last save', preview_admin_appearances_path, class: 'btn', target: '_blank' diff --git a/app/views/admin/appearances/preview.html.haml b/app/views/admin/appearances/preview.html.haml index dd4a64e80bc..6c51639b840 100644 --- a/app/views/admin/appearances/preview.html.haml +++ b/app/views/admin/appearances/preview.html.haml @@ -1,29 +1,9 @@ - page_title "Preview | Appearance" -%h3.page-title - Appearance settings - Preview -%hr +.login-box + .login-heading + %h3 Existing user? Sign in + %form + = text_field_tag :login, nil, class: "form-control top", placeholder: "Username or Email" + = password_field_tag :password, nil, class: "form-control bottom", placeholder: "Password" + = button_tag "Sign in", class: "btn-create btn" -.ui-box - .title - Sign-in page - %div - .login-page - .container - .content - .login-title - %h1= brand_title - %hr - .container - .content - .row - .col-sm-7 - .brand-image - = brand_image - .brand_text - = brand_text - .col-sm-4 - .login-box - %h3.page-title Sign in - = text_field_tag :login, nil, class: "form-control top", placeholder: "Username or Email" - = password_field_tag :password, nil, class: "form-control bottom", placeholder: "Password" - = button_tag "Sign in", class: "btn-create btn" -- cgit v1.2.1 From 909a0ff3ace1eb82a4296764777a552779c39839 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Mon, 20 Jun 2016 12:36:59 +0200 Subject: Fix and remove duplicate specs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémy Coutable --- features/dashboard/group.feature | 44 ---------------------- features/steps/dashboard/group.rb | 42 --------------------- .../groups/group_members_controller_spec.rb | 4 +- .../projects/project_members_controller_spec.rb | 6 +-- .../groups/members/member_leaves_group_spec.rb | 1 - spec/features/projects_spec.rb | 16 -------- 6 files changed, 2 insertions(+), 111 deletions(-) diff --git a/features/dashboard/group.feature b/features/dashboard/group.feature index e3c01db2ebb..3ae2c679dc1 100644 --- a/features/dashboard/group.feature +++ b/features/dashboard/group.feature @@ -5,53 +5,9 @@ Feature: Dashboard Group And "John Doe" is owner of group "Owned" And "John Doe" is guest of group "Guest" - # Leave groups - - @javascript - Scenario: Owner should be able to leave from group if he is not the last owner - Given "Mary Jane" is owner of group "Owned" - When I visit dashboard groups page - Then I should see group "Owned" in group list - Then I should see group "Guest" in group list - When I click on the "Leave" button for group "Owned" - And I visit dashboard groups page - Then I should not see group "Owned" in group list - Then I should see group "Guest" in group list - - @javascript - Scenario: Owner should not be able to leave from group if he is the last owner - Given "Mary Jane" is guest of group "Owned" - When I visit dashboard groups page - Then I should see group "Owned" in group list - Then I should see group "Guest" in group list - When I click on the "Leave" button for group "Owned" - Then I should see the "Can not leave message" - - @javascript - Scenario: Guest should be able to leave from group - Given "Mary Jane" is guest of group "Guest" - When I visit dashboard groups page - Then I should see group "Owned" in group list - Then I should see group "Guest" in group list - When I click on the "Leave" button for group "Guest" - When I visit dashboard groups page - Then I should see group "Owned" in group list - Then I should not see group "Guest" in group list - - @javascript - Scenario: Guest should be able to leave from group even if he is the only user in the group - When I visit dashboard groups page - Then I should see group "Owned" in group list - Then I should see group "Guest" in group list - When I click on the "Leave" button for group "Guest" - When I visit dashboard groups page - Then I should see group "Owned" in group list - Then I should not see group "Guest" in group list - Scenario: Create a group from dasboard And I visit dashboard groups page And I click new group link And submit form with new group "Samurai" info Then I should be redirected to group "Samurai" page And I should see newly created group "Samurai" - diff --git a/features/steps/dashboard/group.rb b/features/steps/dashboard/group.rb index 9b79a3be49b..cf679fea530 100644 --- a/features/steps/dashboard/group.rb +++ b/features/steps/dashboard/group.rb @@ -4,44 +4,6 @@ class Spinach::Features::DashboardGroup < Spinach::FeatureSteps include SharedPaths include SharedUser - # Leave - - step 'I click on the "Leave" button for group "Owned"' do - find(:css, 'li', text: "Owner").find(:css, 'i.fa.fa-sign-out').click - # poltergeist always confirms popups. - end - - step 'I click on the "Leave" button for group "Guest"' do - find(:css, 'li', text: "Guest").find(:css, 'i.fa.fa-sign-out').click - # poltergeist always confirms popups. - end - - step 'I should not see the "Leave" button for group "Owned"' do - expect(find(:css, 'li', text: "Owner")).not_to have_selector(:css, 'i.fa.fa-sign-out') - # poltergeist always confirms popups. - end - - step 'I should not see the "Leave" button for groupr "Guest"' do - expect(find(:css, 'li', text: "Guest")).not_to have_selector(:css, 'i.fa.fa-sign-out') - # poltergeist always confirms popups. - end - - step 'I should see group "Owned" in group list' do - expect(page).to have_content("Owned") - end - - step 'I should not see group "Owned" in group list' do - expect(page).not_to have_content("Owned") - end - - step 'I should see group "Guest" in group list' do - expect(page).to have_content("Guest") - end - - step 'I should not see group "Guest" in group list' do - expect(page).not_to have_content("Guest") - end - step 'I click new group link' do click_link "New Group" end @@ -60,8 +22,4 @@ class Spinach::Features::DashboardGroup < Spinach::FeatureSteps expect(page).to have_content "Samurai" expect(page).to have_content "Tokugawa Shogunate" end - - step 'I should see the "Can not leave message"' do - expect(page).to have_content "You can not leave the \"Owned\" group." - end end diff --git a/spec/controllers/groups/group_members_controller_spec.rb b/spec/controllers/groups/group_members_controller_spec.rb index 8798d709f30..c8601341d54 100644 --- a/spec/controllers/groups/group_members_controller_spec.rb +++ b/spec/controllers/groups/group_members_controller_spec.rb @@ -118,9 +118,7 @@ describe Groups::GroupMembersController do it 'cannot removes himself from the group' do delete :leave, group_id: group - expect(response).to redirect_to(group_path(group)) - expect(response).to set_flash[:alert].to "You can not leave the \"#{group.name}\" group. Transfer or delete the group." - expect(group.users).to include user + expect(response.status).to eq(403) end end diff --git a/spec/controllers/projects/project_members_controller_spec.rb b/spec/controllers/projects/project_members_controller_spec.rb index 0a8fe5e04c3..e5e750c855f 100644 --- a/spec/controllers/projects/project_members_controller_spec.rb +++ b/spec/controllers/projects/project_members_controller_spec.rb @@ -171,11 +171,7 @@ describe Projects::ProjectMembersController do delete :leave, namespace_id: project.namespace, project_id: project - expect(response).to redirect_to( - namespace_project_path(project.namespace, project) - ) - expect(response).to set_flash[:alert].to "You can not leave the \"#{project.human_name}\" project. Transfer or delete the project." - expect(project.users).to include user + expect(response.status).to eq(403) end end diff --git a/spec/features/groups/members/member_leaves_group_spec.rb b/spec/features/groups/members/member_leaves_group_spec.rb index 04dfb22db49..3185ff924b9 100644 --- a/spec/features/groups/members/member_leaves_group_spec.rb +++ b/spec/features/groups/members/member_leaves_group_spec.rb @@ -13,7 +13,6 @@ feature 'Groups > Members > Member leaves group', feature: true do end scenario 'user leaves group' do - # find('#group-settings-button').click click_link 'Leave Group' expect(current_path).to eq(dashboard_groups_path) diff --git a/spec/features/projects_spec.rb b/spec/features/projects_spec.rb index 9dd0378d165..6fa8298d489 100644 --- a/spec/features/projects_spec.rb +++ b/spec/features/projects_spec.rb @@ -70,22 +70,6 @@ feature 'Project', feature: true do end end - describe 'leave project link' do - let(:user) { create(:user) } - let(:project) { create(:project, namespace: user.namespace) } - - before do - login_with(user) - project.team.add_user(user, Gitlab::Access::MASTER) - visit namespace_project_path(project.namespace, project) - end - - it 'click project-settings and find leave project' do - find('#project-settings-button').click - expect(page).to have_link('Leave Project') - end - end - describe 'project title' do include WaitForAjax -- cgit v1.2.1 From f112e2a1da696905e994bf5c37c10a950779b1a9 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Mon, 20 Jun 2016 11:37:27 +0100 Subject: Fixed issue with returning ref in commits JSON Added tests to project controller --- app/assets/javascripts/gl_dropdown.js.coffee | 2 +- app/controllers/projects_controller.rb | 6 +++--- spec/controllers/projects_controller_spec.rb | 20 ++++++++++++++++++++ 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/gl_dropdown.js.coffee b/app/assets/javascripts/gl_dropdown.js.coffee index f8a2db6d42c..2a7bf0bc306 100644 --- a/app/assets/javascripts/gl_dropdown.js.coffee +++ b/app/assets/javascripts/gl_dropdown.js.coffee @@ -102,7 +102,7 @@ class GitLabDropdownFilter $el = $(@) matches = fuzzaldrinPlus.match($el.text().trim(), search_text) - if $el.is(':not(.dropdown-header)') + unless $el.is('.dropdown-header') if matches.length $el.show() else diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index b65730b37c9..78ceaf3237f 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -1,7 +1,7 @@ class ProjectsController < Projects::ApplicationController include ExtractsPath - before_action :authenticate_user!, except: [:show, :activity] + before_action :authenticate_user!, except: [:show, :activity, :refs] before_action :project, except: [:new, :create] before_action :repository, except: [:new, :create] before_action :assign_ref_vars, :tree, only: [:show], if: :repo_exists? @@ -261,8 +261,8 @@ class ProjectsController < Projects::ApplicationController end # If reference is commit id - we should add it to branch/tag selectbox - ref = params[:ref] - if ref && options.flatten.exclude?(ref) && ref =~ /\A[0-9a-zA-Z]{6,52}\z/ + ref = Addressable::URI.unescape(params[:ref]) + if ref && options.flatten(2).exclude?(ref) && ref =~ /\A[0-9a-zA-Z]{6,52}\z/ options['Commits'] = [ref] end diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb index fba545560c7..146b2c2e131 100644 --- a/spec/controllers/projects_controller_spec.rb +++ b/spec/controllers/projects_controller_spec.rb @@ -237,4 +237,24 @@ describe ProjectsController do expect(response.status).to eq(401) end end + + describe "GET refs" do + it "should get a list of branches and tags" do + get :refs, namespace_id: public_project.namespace.path, id: public_project.path + + parsed_body = JSON.parse(response.body) + expect(parsed_body["Branches"]).to include("master") + expect(parsed_body["Tags"]).to include("v1.0.0") + expect(parsed_body["Commits"]).to be_nil + end + + it "should get a list of branches, tags and commits" do + get :refs, namespace_id: public_project.namespace.path, id: public_project.path, ref: "123456" + + parsed_body = JSON.parse(response.body) + expect(parsed_body["Branches"]).to include("master") + expect(parsed_body["Tags"]).to include("v1.0.0") + expect(parsed_body["Commits"]).to include("123456") + end + end end -- cgit v1.2.1 From 3cb1e96ef6b55026a3a6d7fbb3b95ade341b0709 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Mon, 20 Jun 2016 12:43:29 +0200 Subject: Avoid autoload issue such as 'Mail::Parsers::AddressStruct' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit By eager-loading the Mail gem in the Sidekiq initializer. Signed-off-by: Rémy Coutable --- config/initializers/sidekiq.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb index f1eec674888..7a2b9a7f6c1 100644 --- a/config/initializers/sidekiq.rb +++ b/config/initializers/sidekiq.rb @@ -23,6 +23,10 @@ Sidekiq.configure_server do |config| config['pool'] = Sidekiq.options[:concurrency] + 2 ActiveRecord::Base.establish_connection(config) Rails.logger.debug("Connection Pool size for Sidekiq Server is now: #{ActiveRecord::Base.connection.pool.instance_variable_get('@size')}") + + # Avoid autoload issue such as 'Mail::Parsers::AddressStruct' + # https://github.com/mikel/mail/issues/912#issuecomment-214850355 + Mail.eager_autoload! end Sidekiq.configure_client do |config| -- cgit v1.2.1 From ca01c4c6484aa135234028e5e1ca5829adad1a50 Mon Sep 17 00:00:00 2001 From: Paco Guzman Date: Thu, 16 Jun 2016 12:53:32 +0200 Subject: Remove Duplicated keys add UNIQUE index to fingerprint --- CHANGELOG | 1 + app/models/key.rb | 2 +- db/migrate/20160616102642_remove_duplicated_keys.rb | 19 +++++++++++++++++++ ...03005_remove_keys_fingerprint_index_if_exists.rb | 21 +++++++++++++++++++++ ...16103948_add_unique_index_to_keys_fingerprint.rb | 13 +++++++++++++ db/schema.rb | 3 ++- spec/models/key_spec.rb | 2 +- 7 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 db/migrate/20160616102642_remove_duplicated_keys.rb create mode 100644 db/migrate/20160616103005_remove_keys_fingerprint_index_if_exists.rb create mode 100644 db/migrate/20160616103948_add_unique_index_to_keys_fingerprint.rb diff --git a/CHANGELOG b/CHANGELOG index 44e6a194745..b5b224760a0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -130,6 +130,7 @@ v 8.9.0 (unreleased) - Update tanuki logo highlight/loading colors - Use Git cached counters for branches and tags on project page - Filter parameters for request_uri value on instrumented transactions. + - Remove duplicated keys add UNIQUE index to keys fingerprint column - Cache user todo counts from TodoService - Ensure Todos counters doesn't count Todos for projects pending delete diff --git a/app/models/key.rb b/app/models/key.rb index 0532e84f47d..b9bc38a0436 100644 --- a/app/models/key.rb +++ b/app/models/key.rb @@ -9,7 +9,7 @@ class Key < ActiveRecord::Base before_validation :strip_white_space, :generate_fingerprint validates :title, presence: true, length: { within: 0..255 } - validates :key, presence: true, length: { within: 0..5000 }, format: { with: /\A(ssh|ecdsa)-.*\Z/ }, uniqueness: true + validates :key, presence: true, length: { within: 0..5000 }, format: { with: /\A(ssh|ecdsa)-.*\Z/ } validates :key, format: { without: /\n|\r/, message: 'should be a single line' } validates :fingerprint, uniqueness: true, presence: { message: 'cannot be generated' } diff --git a/db/migrate/20160616102642_remove_duplicated_keys.rb b/db/migrate/20160616102642_remove_duplicated_keys.rb new file mode 100644 index 00000000000..00a45d7fe73 --- /dev/null +++ b/db/migrate/20160616102642_remove_duplicated_keys.rb @@ -0,0 +1,19 @@ +# rubocop:disable all +class RemoveDuplicatedKeys < ActiveRecord::Migration + def up + select_all("SELECT fingerprint FROM #{quote_table_name(:keys)} GROUP BY fingerprint HAVING COUNT(*) > 1").each do |row| + fingerprint = connection.quote(row['fingerprint']) + execute(%Q{ + DELETE FROM keys + WHERE fingerprint = #{fingerprint} + AND id != ( + SELECT id FROM ( + SELECT max(id) AS id + FROM keys + WHERE fingerprint = #{fingerprint} + ) max_ids + ) + }) + end + end +end diff --git a/db/migrate/20160616103005_remove_keys_fingerprint_index_if_exists.rb b/db/migrate/20160616103005_remove_keys_fingerprint_index_if_exists.rb new file mode 100644 index 00000000000..4bb4204cebd --- /dev/null +++ b/db/migrate/20160616103005_remove_keys_fingerprint_index_if_exists.rb @@ -0,0 +1,21 @@ +class RemoveKeysFingerprintIndexIfExists < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + disable_ddl_transaction! + + # https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/250 + # That MR was added on gitlab-ee so we need to check if the index + # already exists because we want to do is create an unique index instead. + + def up + if index_exists?(:keys, :fingerprint) + remove_index :keys, :fingerprint + end + end + + def down + unless index_exists?(:keys, :fingerprint) + add_concurrent_index :keys, :fingerprint + end + end +end diff --git a/db/migrate/20160616103948_add_unique_index_to_keys_fingerprint.rb b/db/migrate/20160616103948_add_unique_index_to_keys_fingerprint.rb new file mode 100644 index 00000000000..e35af38aac3 --- /dev/null +++ b/db/migrate/20160616103948_add_unique_index_to_keys_fingerprint.rb @@ -0,0 +1,13 @@ +class AddUniqueIndexToKeysFingerprint < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + disable_ddl_transaction! + + def up + add_concurrent_index :keys, :fingerprint, unique: true + end + + def down + remove_index :keys, :fingerprint + end +end diff --git a/db/schema.rb b/db/schema.rb index 5a27e9d5cdc..4c1eb8cc1b3 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160616084004) do +ActiveRecord::Schema.define(version: 20160616103948) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -507,6 +507,7 @@ ActiveRecord::Schema.define(version: 20160616084004) do end add_index "keys", ["created_at", "id"], name: "index_keys_on_created_at_and_id", using: :btree + add_index "keys", ["fingerprint"], name: "index_keys_on_fingerprint", unique: true, using: :btree add_index "keys", ["user_id"], name: "index_keys_on_user_id", using: :btree create_table "label_links", force: :cascade do |t| diff --git a/spec/models/key_spec.rb b/spec/models/key_spec.rb index 26fbedbef2f..49cf3d8633a 100644 --- a/spec/models/key_spec.rb +++ b/spec/models/key_spec.rb @@ -26,7 +26,7 @@ describe Key, models: true do end end - context "validation of uniqueness" do + context "validation of uniqueness (based on fingerprint uniqueness)" do let(:user) { create(:user) } it "accepts the key once" do -- cgit v1.2.1 From dd417699a39a952584d88c3179d890683603a606 Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Mon, 20 Jun 2016 13:25:33 +0200 Subject: Add styleguide on configuration settings documentation [ci skip] --- doc/development/doc_styleguide.md | 56 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/doc/development/doc_styleguide.md b/doc/development/doc_styleguide.md index f5d97179f8a..975bb82c37d 100644 --- a/doc/development/doc_styleguide.md +++ b/doc/development/doc_styleguide.md @@ -183,6 +183,62 @@ For example, if you were to move `doc/workflow/lfs/lfs_administration.md` to (`workflow/lfs/lfs_administration.md`). +## Configuration documentation for source and Omnibus installations + +GitLab currently officially supports two installation methods: installations +from source and Omnibus packages installations. + +Whenever there is a setting that is configurable for both installation methods, +prefer to document it in the CE docs to avoid duplication. + +Configuration settings include: + +- settings that touch configuration files in `config/` +- NGINX settings and settings in `lib/support/` in general + +When there is a list of steps to perform, usually that entails editing the +configuration file and reconfiguring/restarting GitLab. In such case, follow +the style below as a guide: + +```` +**For Omnibus installations** + +1. Edit `/etc/gitlab/gitlab.rb`: + + ```ruby + external_url "https://gitlab.example.com" + ``` + +1. Save the file and [reconfigure] GitLab for the changes to take effect. + +--- + +**For installations from source** + +1. Edit `config/gitlab.yml`: + + ```yaml + gitlab: + host: "gitlab.example.com" + ``` + +1. Save the file and [restart] GitLab for the changes to take effect. + + +[reconfigure]: path/to/administration/gitlab_restart.md#omnibus-gitlab-reconfigure +[restart]: path/to/administration/gitlab_restart.md#installations-from-source +```` + +In this case: + +- before each step list the installation method is declared in bold +- three dashes (`---`) are used to create an horizontal line and separate the + two methods +- the code blocks are indented one or more spaces under the list item to render + correctly +- different highlighting languages are used for each config in the code block +- the [references](#references) guide is used for reconfigure/restart + ## API Here is a list of must-have items. Use them in the exact order that appears -- cgit v1.2.1 From 3f12e8d1b2bca17554780104fd668299a5a2e196 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 20 Jun 2016 14:55:20 +0300 Subject: Put some admin settings in dropdown Signed-off-by: Dmitriy Zaporozhets --- app/views/admin/appearances/show.html.haml | 12 ++-- .../admin/application_settings/_head.html.haml | 11 --- .../admin/application_settings/show.html.haml | 8 +-- app/views/layouts/nav/_admin.html.haml | 84 +++++++++------------- app/views/layouts/nav/_admin_settings.html.haml | 31 ++++++++ 5 files changed, 75 insertions(+), 71 deletions(-) delete mode 100644 app/views/admin/application_settings/_head.html.haml create mode 100644 app/views/layouts/nav/_admin_settings.html.haml diff --git a/app/views/admin/appearances/show.html.haml b/app/views/admin/appearances/show.html.haml index e220f4956cb..454b779842c 100644 --- a/app/views/admin/appearances/show.html.haml +++ b/app/views/admin/appearances/show.html.haml @@ -1,7 +1,9 @@ -- @no_container = true - page_title "Appearance" -= render "admin/application_settings/head" -%div{ class: (container_class) } - .prepend-top-default - = render 'form' +%h3.page-title + Appearance settings +%p.light + You can modify the look and feel of GitLab here +%hr + += render 'form' diff --git a/app/views/admin/application_settings/_head.html.haml b/app/views/admin/application_settings/_head.html.haml deleted file mode 100644 index de919b298c1..00000000000 --- a/app/views/admin/application_settings/_head.html.haml +++ /dev/null @@ -1,11 +0,0 @@ -.nav-links.sub-nav - %ul{ class: (container_class) } - = nav_link(controller: :application_settings) do - = link_to admin_application_settings_path, title: 'Settings' do - %span - General - - = nav_link(controller: :appearances) do - = link_to admin_appearances_path, title: 'Appearances' do - %span - Appearance diff --git a/app/views/admin/application_settings/show.html.haml b/app/views/admin/application_settings/show.html.haml index 82588c275d0..ecc46d86afe 100644 --- a/app/views/admin/application_settings/show.html.haml +++ b/app/views/admin/application_settings/show.html.haml @@ -1,7 +1,5 @@ -- @no_container = true - page_title "Settings" -= render "admin/application_settings/head" -%div{ class: (container_class) } - .prepend-top-default - = render 'form' +%h3.page-title Settings +%hr += render 'form' diff --git a/app/views/layouts/nav/_admin.html.haml b/app/views/layouts/nav/_admin.html.haml index c6d8b17a1e5..4722c9d9353 100644 --- a/app/views/layouts/nav/_admin.html.haml +++ b/app/views/layouts/nav/_admin.html.haml @@ -1,55 +1,39 @@ -%ul.nav-links.scrolling-tabs - .fade-left - = nav_link(controller: %w(dashboard admin projects users groups builds runners), html_options: {class: 'home'}) do - = link_to admin_root_path, title: 'Overview', class: 'shortcuts-tree' do - %span - Overview - = nav_link(controller: %w(background_jobs logs health_check)) do - = link_to admin_background_jobs_path, title: 'Monitoring' do - %span - Monitoring - = nav_link(controller: :deploy_keys) do - = link_to admin_deploy_keys_path, title: 'Deploy Keys' do - %span - Deploy Keys - = nav_link(controller: :broadcast_messages) do - = link_to admin_broadcast_messages_path, title: 'Messages' do - %span - Messages - = nav_link(controller: :hooks) do - = link_to admin_hooks_path, title: 'Hooks' do - %span - Hooks +%div{ class: nav_control_class } + = render 'layouts/nav/admin_settings' - = nav_link(controller: :applications) do - = link_to admin_applications_path, title: 'Applications' do - %span - Applications - - = nav_link(controller: :services) do - = link_to admin_application_settings_services_path, title: 'Service Templates' do - %span - Service Templates - - = nav_link(controller: :labels) do - = link_to admin_labels_path, title: 'Labels' do - %span - Labels + %ul.nav-links.scrolling-tabs + .fade-left + = nav_link(controller: %w(dashboard admin projects users groups builds runners), html_options: {class: 'home'}) do + = link_to admin_root_path, title: 'Overview', class: 'shortcuts-tree' do + %span + Overview + = nav_link(controller: %w(background_jobs logs health_check)) do + = link_to admin_background_jobs_path, title: 'Monitoring' do + %span + Monitoring + = nav_link(controller: :broadcast_messages) do + = link_to admin_broadcast_messages_path, title: 'Messages' do + %span + Messages + = nav_link(controller: :hooks) do + = link_to admin_hooks_path, title: 'Hooks' do + %span + System Hooks - = nav_link(controller: :abuse_reports) do - = link_to admin_abuse_reports_path, title: "Abuse Reports" do - %span - Abuse Reports - %span.badge.count= number_with_delimiter(AbuseReport.count(:all)) + = nav_link(controller: :applications) do + = link_to admin_applications_path, title: 'Applications' do + %span + Applications - - if askimet_enabled? - = nav_link(controller: :spam_logs) do - = link_to admin_spam_logs_path, title: "Spam Logs" do + = nav_link(controller: :abuse_reports) do + = link_to admin_abuse_reports_path, title: "Abuse Reports" do %span - Spam Logs + Abuse Reports + %span.badge.count= number_with_delimiter(AbuseReport.count(:all)) - = nav_link(controller: [:application_settings, :appearances]) do - = link_to admin_application_settings_path, title: 'Settings' do - %span - Settings - .fade-right + - if askimet_enabled? + = nav_link(controller: :spam_logs) do + = link_to admin_spam_logs_path, title: "Spam Logs" do + %span + Spam Logs + .fade-right diff --git a/app/views/layouts/nav/_admin_settings.html.haml b/app/views/layouts/nav/_admin_settings.html.haml new file mode 100644 index 00000000000..38e9b80d129 --- /dev/null +++ b/app/views/layouts/nav/_admin_settings.html.haml @@ -0,0 +1,31 @@ +.controls + .dropdown.admin-settings-dropdown + %a.dropdown-new.btn.btn-default{href: '#', 'data-toggle' => 'dropdown'} + = icon('cog') + = icon('caret-down') + %ul.dropdown-menu.dropdown-menu-align-right + = nav_link(controller: :deploy_keys) do + = link_to admin_deploy_keys_path, title: 'Deploy Keys' do + %span + Deploy Keys + + = nav_link(controller: :services) do + = link_to admin_application_settings_services_path, title: 'Service Templates' do + %span + Service Templates + + = nav_link(controller: :labels) do + = link_to admin_labels_path, title: 'Labels' do + %span + Labels + + = nav_link(controller: :appearances) do + = link_to admin_appearances_path, title: 'Appearances' do + %span + Appearance + + %li.divider + = nav_link(controller: :application_settings) do + = link_to admin_application_settings_path, title: 'Settings' do + %span + Settings -- cgit v1.2.1 From c628eeb773a962c66bcb4f73bfee60cdc28d2435 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Mon, 20 Jun 2016 12:03:21 +0000 Subject: Add index for ci_runners.locked, feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/4093#note_12571602 and https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/4093#note_12571670 --- db/migrate/20160620115026_add_index_on_runners_locked.rb | 12 ++++++++++++ db/schema.rb | 3 ++- 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20160620115026_add_index_on_runners_locked.rb diff --git a/db/migrate/20160620115026_add_index_on_runners_locked.rb b/db/migrate/20160620115026_add_index_on_runners_locked.rb new file mode 100644 index 00000000000..dfa5110dea4 --- /dev/null +++ b/db/migrate/20160620115026_add_index_on_runners_locked.rb @@ -0,0 +1,12 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class AddIndexOnRunnersLocked < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + disable_ddl_transaction! + + def change + add_concurrent_index :ci_runners, :locked + end +end diff --git a/db/schema.rb b/db/schema.rb index daf66f1b4dd..cf9637b04b7 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160616084004) do +ActiveRecord::Schema.define(version: 20160620115026) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -291,6 +291,7 @@ ActiveRecord::Schema.define(version: 20160616084004) do end add_index "ci_runners", ["description"], name: "index_ci_runners_on_description_trigram", using: :gin, opclasses: {"description"=>"gin_trgm_ops"} + add_index "ci_runners", ["locked"], name: "index_ci_runners_on_locked", using: :btree add_index "ci_runners", ["token"], name: "index_ci_runners_on_token", using: :btree add_index "ci_runners", ["token"], name: "index_ci_runners_on_token_trigram", using: :gin, opclasses: {"token"=>"gin_trgm_ops"} -- cgit v1.2.1 From 09eb9481a840d0e812aaa81c13266769a253586d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 16 Jun 2016 00:14:25 +0000 Subject: Document email on push service --- doc/project_services/emails_on_push.md | 17 +++++++++++++++++ doc/project_services/img/emails_on_push_service.png | Bin 0 -> 98160 bytes doc/project_services/project_services.md | 2 +- 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 doc/project_services/emails_on_push.md create mode 100644 doc/project_services/img/emails_on_push_service.png diff --git a/doc/project_services/emails_on_push.md b/doc/project_services/emails_on_push.md new file mode 100644 index 00000000000..2f9f36f962e --- /dev/null +++ b/doc/project_services/emails_on_push.md @@ -0,0 +1,17 @@ +## Enabling emails on push + +To receive email notifications for every change that is pushed to the project, visit +your project's **Settings > Services > Emails on push** and activate the service. + +In the _Recipients_ area, provide a list of emails separated by commas. + +You can configure any of the following settings depending on your preference. + ++ **Push events** - Email will be triggered when a push event is recieved ++ **Tag push events** - Email will be triggered when a tag is created and pushed ++ **Send from committer** - Send notifications from the committer's email address if the domain is part of the domain GitLab is running on (e.g. `user@gitlab.com`). ++ **Disable code diffs** - Don't include possibly sensitive code diffs in notification body. + +--- + +![Email on push service settings](img/emails_on_push_service.png) diff --git a/doc/project_services/img/emails_on_push_service.png b/doc/project_services/img/emails_on_push_service.png new file mode 100644 index 00000000000..cd6f79ad1eb Binary files /dev/null and b/doc/project_services/img/emails_on_push_service.png differ diff --git a/doc/project_services/project_services.md b/doc/project_services/project_services.md index a5af620d9be..f81a035f70b 100644 --- a/doc/project_services/project_services.md +++ b/doc/project_services/project_services.md @@ -33,7 +33,7 @@ further configuration instructions and details. Contributions are welcome. | Campfire | Simple web-based real-time group chat | | Custom Issue Tracker | Custom issue tracker | | Drone CI | Continuous Integration platform built on Docker, written in Go | -| Emails on push | Email the commits and diff of each push to a list of recipients | +| [Emails on push](emails_on_push.md) | Email the commits and diff of each push to a list of recipients | | External Wiki | Replaces the link to the internal wiki with a link to an external wiki | | Flowdock | Flowdock is a collaboration web app for technical teams | | Gemnasium | Gemnasium monitors your project dependencies and alerts you about updates and security vulnerabilities | -- cgit v1.2.1 From 043522a8aed5e598f3cfe97480a5b169fe0786f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Mon, 20 Jun 2016 15:50:46 +0200 Subject: Display group/project access requesters separately in admin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also, reuse partials from the non-admin views. Signed-off-by: Rémy Coutable --- app/views/admin/groups/show.html.haml | 33 +++++---------- app/views/admin/projects/show.html.haml | 49 +++++++--------------- app/views/groups/group_members/index.html.haml | 3 +- .../project_members/_group_members.html.haml | 3 +- .../_shared_group_members.html.haml | 5 ++- app/views/projects/project_members/_team.html.haml | 3 +- app/views/projects/project_members/index.html.haml | 2 +- app/views/shared/members/_requests.html.haml | 2 +- 8 files changed, 35 insertions(+), 65 deletions(-) diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml index 5b8a0262ea0..50770465f07 100644 --- a/app/views/admin/groups/show.html.haml +++ b/app/views/admin/groups/show.html.haml @@ -88,28 +88,17 @@ = select_tag :access_level, options_for_select(GroupMember.access_level_roles), class: "project-access-select select2" %hr = button_tag 'Add users to group', class: "btn btn-create" + + = render 'shared/members/requests', membership_source: @group, members: @members.request + .panel.panel-default .panel-heading - %h3.panel-title - Members - %span.badge - #{@group.group_members.count} - %ul.well-list.group-users-list - - @members.each do |member| - - user = member.user - %li{class: dom_class(member), id: (dom_id(user) if user)} - .list-item-name - - if user - %strong - = link_to user.name, admin_user_path(user) - - else - %strong - = member.invite_email - (invited) - %span.pull-right.light - = member.human_access - - if can?(current_user, :destroy_group_member, member) - = link_to group_group_member_path(@group, member), data: { confirm: remove_member_message(member) }, method: :delete, remote: true, class: "btn-xs btn btn-remove", title: 'Remove user from group' do - %i.fa.fa-minus.fa-inverse + %strong= @group.name + group members + %span.badge= @group.members.non_request.size + .pull-right + = link_to icon('pencil-square-o', text: 'Manage Access'), polymorphic_url([@group, :members]), class: "btn btn-xs" + %ul.well-list.group-users-list.content-list + = render partial: 'shared/members/member', collection: @members.non_request, as: :member, locals: { show_controls: false } .panel-footer - = paginate @members, param_name: 'members_page', theme: 'gitlab' + = paginate @members.non_request, param_name: 'members_page', theme: 'gitlab' diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml index 9e55a562e18..461d588415d 100644 --- a/app/views/admin/projects/show.html.haml +++ b/app/views/admin/projects/show.html.haml @@ -135,44 +135,27 @@ - if @group .panel.panel-default .panel-heading - %strong #{@group.name} - group members (#{@group.group_members.count}) + %strong= @group.name + group members + %span.badge= @group_members.non_request.size .pull-right = link_to admin_group_path(@group), class: 'btn btn-xs' do - %i.fa.fa-pencil-square-o - %ul.well-list - - @group_members.each do |member| - = render 'shared/members/member', member: member, show_controls: false + = icon('pencil-square-o', text: 'Manage Access') + %ul.well-list.content-list + = render partial: 'shared/members/member', collection: @group_members.non_request, as: :member, locals: { show_controls: false } .panel-footer - = paginate @group_members, param_name: 'group_members_page', theme: 'gitlab' + = paginate @group_members.non_request, param_name: 'group_members_page', theme: 'gitlab' + + = render 'shared/members/requests', membership_source: @project, members: @project_members.request .panel.panel-default .panel-heading - Project members - %small - (#{@project.users.count}) + %strong= @project.name + project members + %span.badge= @project.users.size .pull-right - = link_to namespace_project_project_members_path(@project.namespace, @project), class: "btn btn-xs" do - %i.fa.fa-pencil-square-o - Manage Access - %ul.well-list.project_members - - @project_members.each do |project_member| - - user = project_member.user - %li.project_member - .list-item-name - - if user - %strong - = link_to user.name, admin_user_path(user) - - else - %strong - = project_member.invite_email - (invited) - .pull-right - - if project_member.owner? - %span.light Owner - - else - %span.light= project_member.human_access - = link_to namespace_project_project_member_path(@project.namespace, @project, project_member), data: { confirm: remove_member_message(project_member)}, method: :delete, remote: true, class: "btn btn-sm btn-remove" do - %i.fa.fa-times + = link_to icon('pencil-square-o', text: 'Manage Access'), polymorphic_url([@project, :members]), class: "btn btn-xs" + %ul.well-list.project_members.content-list + = render partial: 'shared/members/member', collection: @project_members.non_request, as: :member, locals: { show_controls: false } .panel-footer - = paginate @project_members, param_name: 'project_members_page', theme: 'gitlab' + = paginate @project_members.non_request, param_name: 'project_members_page', theme: 'gitlab' diff --git a/app/views/groups/group_members/index.html.haml b/app/views/groups/group_members/index.html.haml index a36531e095a..d6acade84f1 100644 --- a/app/views/groups/group_members/index.html.haml +++ b/app/views/groups/group_members/index.html.haml @@ -17,8 +17,7 @@ .panel-heading %strong #{@group.name} group members - %small - (#{@members.total_count}) + %span.badge= @members.non_request.size .controls = form_tag group_group_members_path(@group), method: :get, class: 'form-inline member-search-form' do .form-group diff --git a/app/views/projects/project_members/_group_members.html.haml b/app/views/projects/project_members/_group_members.html.haml index cb6136c215a..e783d8c72c5 100644 --- a/app/views/projects/project_members/_group_members.html.haml +++ b/app/views/projects/project_members/_group_members.html.haml @@ -2,8 +2,7 @@ .panel-heading %strong #{@group.name} group members - %small - (#{members.count}) + %span.badge= members.size - if can?(current_user, :admin_group_member, @group) .controls = link_to 'Manage group members', diff --git a/app/views/projects/project_members/_shared_group_members.html.haml b/app/views/projects/project_members/_shared_group_members.html.haml index 952844acefc..840b57c2e63 100644 --- a/app/views/projects/project_members/_shared_group_members.html.haml +++ b/app/views/projects/project_members/_shared_group_members.html.haml @@ -1,6 +1,7 @@ - @project_group_links.each do |group_links| - shared_group = group_links.group - - shared_group_users_count = group_links.group.group_members.count + - shared_group_members = shared_group.members.non_request + - shared_group_users_count = shared_group_members.size .panel.panel-default .panel-heading Shared with @@ -15,7 +16,7 @@ Edit group members %ul.content-list = render partial: 'shared/members/member', - collection: shared_group.group_members.order(access_level: :desc).limit(20), + collection: shared_group_members.order(access_level: :desc).limit(20), as: :member, locals: { show_controls: false, show_roles: false } - if shared_group_users_count > 20 diff --git a/app/views/projects/project_members/_team.html.haml b/app/views/projects/project_members/_team.html.haml index 03207614258..b0bfdd235f7 100644 --- a/app/views/projects/project_members/_team.html.haml +++ b/app/views/projects/project_members/_team.html.haml @@ -2,8 +2,7 @@ .panel-heading %strong #{@project.name} project members - %small - (#{members.count}) + %span.badge= members.size .controls = form_tag namespace_project_project_members_path(@project.namespace, @project), method: :get, class: 'form-inline member-search-form' do .form-group diff --git a/app/views/projects/project_members/index.html.haml b/app/views/projects/project_members/index.html.haml index 357ccccaf1d..a2026c41d01 100644 --- a/app/views/projects/project_members/index.html.haml +++ b/app/views/projects/project_members/index.html.haml @@ -18,7 +18,7 @@ = render 'team', members: @project_members.non_request - if @group - = render "group_members", members: @group_members + = render "group_members", members: @group_members.non_request - if @project_group_links.any? && @project.allowed_to_share_with_group? = render "shared_group_members" diff --git a/app/views/shared/members/_requests.html.haml b/app/views/shared/members/_requests.html.haml index b5963876034..e4bd2bdc265 100644 --- a/app/views/shared/members/_requests.html.haml +++ b/app/views/shared/members/_requests.html.haml @@ -3,6 +3,6 @@ .panel-heading %strong= membership_source.name access requests - %small= "(#{members.size})" + %span.badge= members.size %ul.content-list = render partial: 'shared/members/member', collection: members, as: :member -- cgit v1.2.1 From 7c41f35953494f5f7372a434c8c62a7b466c8212 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Mon, 20 Jun 2016 09:32:01 -0500 Subject: Add fade divs as li elements --- app/views/layouts/nav/_admin.html.haml | 4 ++-- app/views/layouts/nav/_group.html.haml | 4 ++-- app/views/layouts/nav/_profile.html.haml | 4 ++-- app/views/layouts/nav/_project.html.haml | 4 ++-- app/views/projects/commits/_head.html.haml | 4 ++-- app/views/shared/_event_filter.html.haml | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/app/views/layouts/nav/_admin.html.haml b/app/views/layouts/nav/_admin.html.haml index 4722c9d9353..ffdc7b7f504 100644 --- a/app/views/layouts/nav/_admin.html.haml +++ b/app/views/layouts/nav/_admin.html.haml @@ -2,7 +2,7 @@ = render 'layouts/nav/admin_settings' %ul.nav-links.scrolling-tabs - .fade-left + %li.fade-left = nav_link(controller: %w(dashboard admin projects users groups builds runners), html_options: {class: 'home'}) do = link_to admin_root_path, title: 'Overview', class: 'shortcuts-tree' do %span @@ -36,4 +36,4 @@ = link_to admin_spam_logs_path, title: "Spam Logs" do %span Spam Logs - .fade-right + %li.fade-right diff --git a/app/views/layouts/nav/_group.html.haml b/app/views/layouts/nav/_group.html.haml index 66361a644dd..3bd04c2c8b4 100644 --- a/app/views/layouts/nav/_group.html.haml +++ b/app/views/layouts/nav/_group.html.haml @@ -2,7 +2,7 @@ = render 'layouts/nav/group_settings' %ul.nav-links.scrolling-tabs - .fade-left + %li.fade-left = nav_link(path: 'groups#show', html_options: {class: 'home'}) do = link_to group_path(@group), title: 'Home' do %span @@ -31,4 +31,4 @@ = link_to group_group_members_path(@group), title: 'Members' do %span Members - .fade-right + %li.fade-right diff --git a/app/views/layouts/nav/_profile.html.haml b/app/views/layouts/nav/_profile.html.haml index bb6f14a6225..110a72d3a3c 100644 --- a/app/views/layouts/nav/_profile.html.haml +++ b/app/views/layouts/nav/_profile.html.haml @@ -1,5 +1,5 @@ %ul.nav-links.scrolling-tabs - .fade-left + %li.fade-left = nav_link(path: 'profiles#show', html_options: {class: 'home'}) do = link_to profile_path, title: 'Profile Settings' do %span @@ -43,4 +43,4 @@ = link_to audit_log_profile_path, title: 'Audit Log' do %span Audit Log - .fade-right + %li.fade-right diff --git a/app/views/layouts/nav/_project.html.haml b/app/views/layouts/nav/_project.html.haml index 39ea4920ccc..823051d1b83 100644 --- a/app/views/layouts/nav/_project.html.haml +++ b/app/views/layouts/nav/_project.html.haml @@ -25,7 +25,7 @@ %div{ class: nav_control_class } %ul.nav-links.scrolling-tabs - .fade-left + %li.fade-left = nav_link(path: 'projects#show', html_options: {class: 'home'}) do = link_to project_path(@project), title: 'Project', class: 'shortcuts-project' do %span @@ -109,4 +109,4 @@ %li.hidden = link_to project_commits_path(@project), title: 'Commits', class: 'shortcuts-commits' do Commits - .fade-right + %li.fade-right diff --git a/app/views/projects/commits/_head.html.haml b/app/views/projects/commits/_head.html.haml index c8aa849c217..888c6b6701b 100644 --- a/app/views/projects/commits/_head.html.haml +++ b/app/views/projects/commits/_head.html.haml @@ -1,7 +1,7 @@ .scrolling-tabs-container .nav-links.sub-nav.scrolling-tabs %ul{ class: (container_class) } - .fade-left + %li.fade-left = nav_link(controller: %w(tree blob blame edit_tree new_tree find_file)) do = link_to project_files_path(@project) do Files @@ -25,4 +25,4 @@ = nav_link(controller: [:tags, :releases]) do = link_to namespace_project_tags_path(@project.namespace, @project) do Tags - .fade-right + %li.fade-right diff --git a/app/views/shared/_event_filter.html.haml b/app/views/shared/_event_filter.html.haml index 30055002213..6f9809a9ed8 100644 --- a/app/views/shared/_event_filter.html.haml +++ b/app/views/shared/_event_filter.html.haml @@ -1,7 +1,7 @@ %ul.nav-links.event-filter.scrolling-tabs - .fade-left + %li.fade-left = event_filter_link EventFilter.push, 'Push events' = event_filter_link EventFilter.merged, 'Merge events' = event_filter_link EventFilter.comments, 'Comments' = event_filter_link EventFilter.team, 'Team' - .fade-right + %li.fade-right -- cgit v1.2.1 From 00ac7ae84a9d518e4d800973ac1056b720e86719 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Mon, 20 Jun 2016 16:40:35 +0200 Subject: Fix specs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémy Coutable --- spec/features/groups/members/owner_manages_access_requests_spec.rb | 2 +- spec/features/projects/members/master_manages_access_requests_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/groups/members/owner_manages_access_requests_spec.rb b/spec/features/groups/members/owner_manages_access_requests_spec.rb index 22525ce530b..321c9bad7d0 100644 --- a/spec/features/groups/members/owner_manages_access_requests_spec.rb +++ b/spec/features/groups/members/owner_manages_access_requests_spec.rb @@ -42,7 +42,7 @@ feature 'Groups > Members > Owner manages access requests', feature: true do def expect_visible_access_request(group, user) expect(group.members.request.exists?(user_id: user)).to be_truthy - expect(page).to have_content "#{group.name} access requests (1)" + expect(page).to have_content "#{group.name} access requests 1" expect(page).to have_content user.name end end diff --git a/spec/features/projects/members/master_manages_access_requests_spec.rb b/spec/features/projects/members/master_manages_access_requests_spec.rb index 5fe4caa12f0..aa2d906fa2e 100644 --- a/spec/features/projects/members/master_manages_access_requests_spec.rb +++ b/spec/features/projects/members/master_manages_access_requests_spec.rb @@ -41,7 +41,7 @@ feature 'Projects > Members > Master manages access requests', feature: true do def expect_visible_access_request(project, user) expect(project.members.request.exists?(user_id: user)).to be_truthy - expect(page).to have_content "#{project.name} access requests (1)" + expect(page).to have_content "#{project.name} access requests 1" expect(page).to have_content user.name end end -- cgit v1.2.1 From 8a2a01e023b719af7c5823973a84758ef4012bac Mon Sep 17 00:00:00 2001 From: Felipe Artur Date: Mon, 20 Jun 2016 11:52:43 -0300 Subject: Add notification_settings:events to schema --- db/schema.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/db/schema.rb b/db/schema.rb index 4c1eb8cc1b3..29f90c47848 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160616103948) do +ActiveRecord::Schema.define(version: 20160617301627) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -708,6 +708,7 @@ ActiveRecord::Schema.define(version: 20160616103948) do t.integer "level", default: 0, null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.text "events" end add_index "notification_settings", ["source_id", "source_type"], name: "index_notification_settings_on_source_id_and_source_type", using: :btree -- cgit v1.2.1 From e50739f4c7bf823f2c1a4a65363ed987eff7d399 Mon Sep 17 00:00:00 2001 From: Connor Shea Date: Mon, 20 Jun 2016 09:21:14 -0600 Subject: Apply responsive design for Contributors graphs. Fixes #18845. --- .../javascripts/graphs/stat_graph_contributors_graph.js.coffee | 6 +++++- app/assets/stylesheets/pages/stat_graph.scss | 6 ++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/graphs/stat_graph_contributors_graph.js.coffee b/app/assets/javascripts/graphs/stat_graph_contributors_graph.js.coffee index 584d281a510..834a81af459 100644 --- a/app/assets/javascripts/graphs/stat_graph_contributors_graph.js.coffee +++ b/app/assets/javascripts/graphs/stat_graph_contributors_graph.js.coffee @@ -121,7 +121,11 @@ class @ContributorsMasterGraph extends ContributorsGraph class @ContributorsAuthorGraph extends ContributorsGraph constructor: (@data) -> - @width = $('.content').width()/2 - 100 + # Don't split graph size in half for mobile devices. + if $(window).width() < 768 + @width = $('.content').width() - 80 + else + @width = ($('.content').width() / 2) - 100 @height = 200 @x = null @y = null diff --git a/app/assets/stylesheets/pages/stat_graph.scss b/app/assets/stylesheets/pages/stat_graph.scss index 85a0304196c..8a1f2d098d6 100644 --- a/app/assets/stylesheets/pages/stat_graph.scss +++ b/app/assets/stylesheets/pages/stat_graph.scss @@ -25,13 +25,19 @@ &:nth-child(even) { float: right; } + float: left; margin-top: 10px; + + @media (max-width: $screen-sm-min) { + width: 100%; + } } .person .spark { display: block; background: #f3f3f3; + width: 100%; } .person .area-contributor { -- cgit v1.2.1 From bcecc1957120ed1e24b617d554637cd7da60d0cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Rodr=C3=ADguez?= Date: Thu, 16 Jun 2016 10:45:03 -0400 Subject: Set missing stages on ci builds to 'test' to avoid regressions in the pipelines view --- db/migrate/20160615191922_set_missing_stage_on_ci_builds.rb | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 db/migrate/20160615191922_set_missing_stage_on_ci_builds.rb diff --git a/db/migrate/20160615191922_set_missing_stage_on_ci_builds.rb b/db/migrate/20160615191922_set_missing_stage_on_ci_builds.rb new file mode 100644 index 00000000000..bd0463886bc --- /dev/null +++ b/db/migrate/20160615191922_set_missing_stage_on_ci_builds.rb @@ -0,0 +1,9 @@ +class SetMissingStageOnCiBuilds < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + def up + update_column_in_batches(:ci_builds, :stage, :test) do |table, query| + query.where(table[:stage].eq(nil)) + end + end +end -- cgit v1.2.1 From 9a5b2e94d65774edda9bb0e8bf6df22347d48ed7 Mon Sep 17 00:00:00 2001 From: winniehell Date: Mon, 20 Jun 2016 09:26:28 +0200 Subject: wrap code blocks on Activies and Todos page --- CHANGELOG | 1 + app/assets/stylesheets/pages/events.scss | 4 ++++ app/assets/stylesheets/pages/todos.scss | 4 ++++ 3 files changed, 9 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 44e6a194745..204fb4ea0f5 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -31,6 +31,7 @@ v 8.9.0 (unreleased) - Implement a fair usage of shared runners - Remove project notification settings associated with deleted projects - Fix 404 page when viewing TODOs that contain milestones or labels in different projects + - Wrap code blocks on Activies and Todos page !4783 (winniehell) - Add a metric for the number of new Redis connections created by a transaction - Fix Error 500 when viewing a blob with binary characters after the 1024-byte mark - Redesign navigation for project pages diff --git a/app/assets/stylesheets/pages/events.scss b/app/assets/stylesheets/pages/events.scss index 6c36f603daf..a2145956eb5 100644 --- a/app/assets/stylesheets/pages/events.scss +++ b/app/assets/stylesheets/pages/events.scss @@ -54,6 +54,10 @@ } } + code { + white-space: pre-wrap; + } + pre { border: none; background: #f9f9f9; diff --git a/app/assets/stylesheets/pages/todos.scss b/app/assets/stylesheets/pages/todos.scss index afc00a68572..cf16d070cfe 100644 --- a/app/assets/stylesheets/pages/todos.scss +++ b/app/assets/stylesheets/pages/todos.scss @@ -62,6 +62,10 @@ } } + code { + white-space: pre-wrap; + } + pre { border: none; background: #f9f9f9; -- cgit v1.2.1 From 459547c259a5bb3e740bb5cba4790e133b16d60a Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Mon, 20 Jun 2016 11:26:00 -0500 Subject: Align avatar and text within commit row --- app/assets/stylesheets/pages/commits.scss | 12 +++++-- app/views/projects/commits/_commit.html.haml | 47 ++++++++++++++-------------- 2 files changed, 34 insertions(+), 25 deletions(-) diff --git a/app/assets/stylesheets/pages/commits.scss b/app/assets/stylesheets/pages/commits.scss index 761e33f0df7..de534d28421 100644 --- a/app/assets/stylesheets/pages/commits.scss +++ b/app/assets/stylesheets/pages/commits.scss @@ -80,9 +80,14 @@ .commit { padding: 10px 0; + position: relative; @media (min-width: $screen-sm-min) { - padding-left: 46px; + padding-left: 20px; + + .commit-info-block { + padding-left: 44px; + } } &:not(:last-child) { @@ -95,8 +100,11 @@ vertical-align: baseline; } + .avatar { - margin-left: -46px; + position: absolute; + top: 10px; + left: 16px; } .item-title { diff --git a/app/views/projects/commits/_commit.html.haml b/app/views/projects/commits/_commit.html.haml index a959b34a539..929496f81d8 100644 --- a/app/views/projects/commits/_commit.html.haml +++ b/app/views/projects/commits/_commit.html.haml @@ -10,29 +10,30 @@ = cache(cache_key) do %li.commit.js-toggle-container{ id: "commit-#{commit.short_id}" } = commit_author_avatar(commit, size: 36) - .commit-row-title - %span.item-title - = link_to_gfm commit.title, namespace_project_commit_path(project.namespace, project, commit.id), class: "commit-row-message" - %span.commit-row-message.visible-xs-inline - · - = commit.short_id - - if commit.status - = render_commit_status(commit, cssclass: 'visible-xs-inline') - - if commit.description? - %a.text-expander.hidden-xs.js-toggle-button ... + .commit-info-block + .commit-row-title + %span.item-title + = link_to_gfm commit.title, namespace_project_commit_path(project.namespace, project, commit.id), class: "commit-row-message" + %span.commit-row-message.visible-xs-inline + · + = commit.short_id + - if commit.status + = render_commit_status(commit, cssclass: 'visible-xs-inline') + - if commit.description? + %a.text-expander.hidden-xs.js-toggle-button ... - .commit-actions.hidden-xs - - if commit.status - = render_commit_status(commit, cssclass: 'btn btn-transparent') - = clipboard_button_with_class({ clipboard_text: commit.id }, css_class: 'btn-transparent') - = link_to commit.short_id, namespace_project_commit_path(project.namespace, project, commit), class: "commit-short-id btn btn-transparent" - = link_to_browse_code(project, commit) + .commit-actions.hidden-xs + - if commit.status + = render_commit_status(commit, cssclass: 'btn btn-transparent') + = clipboard_button_with_class({ clipboard_text: commit.id }, css_class: 'btn-transparent') + = link_to commit.short_id, namespace_project_commit_path(project.namespace, project, commit), class: "commit-short-id btn btn-transparent" + = link_to_browse_code(project, commit) - - if commit.description? - %pre.commit-row-description.js-toggle-content - = preserve(markdown(escape_once(commit.description), pipeline: :single_line, author: commit.author)) + - if commit.description? + %pre.commit-row-description.js-toggle-content + = preserve(markdown(escape_once(commit.description), pipeline: :single_line, author: commit.author)) - .commit-row-info - = commit_author_link(commit, avatar: false, size: 24) - authored - #{time_ago_with_tooltip(commit.committed_date)} + .commit-row-info + = commit_author_link(commit, avatar: false, size: 24) + authored + #{time_ago_with_tooltip(commit.committed_date)} -- cgit v1.2.1 From 07195358839a43ab4bae8bd8f112a45af13a79a5 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Mon, 20 Jun 2016 12:11:22 -0500 Subject: Add arrow in horizontal scroll fade --- app/assets/stylesheets/framework/nav.scss | 15 +++++++++++++++ app/views/layouts/nav/_admin.html.haml | 2 ++ app/views/layouts/nav/_group.html.haml | 2 ++ app/views/layouts/nav/_profile.html.haml | 2 ++ app/views/layouts/nav/_project.html.haml | 2 ++ app/views/projects/commits/_head.html.haml | 2 ++ app/views/shared/_event_filter.html.haml | 2 ++ 7 files changed, 27 insertions(+) diff --git a/app/assets/stylesheets/framework/nav.scss b/app/assets/stylesheets/framework/nav.scss index a55918f8711..06f517b8f2e 100644 --- a/app/assets/stylesheets/framework/nav.scss +++ b/app/assets/stylesheets/framework/nav.scss @@ -18,6 +18,13 @@ opacity: 0; transition-duration: .3s; } + + .fa { + position: relative; + top: 3px; + font-size: 13px; + color: $btn-placeholder-gray; + } } @mixin scrolling-links() { @@ -319,11 +326,19 @@ .fade-right { @include fade(left, rgba(250, 250, 250, 0.4), $background-color); right: 0; + + .fa { + right: -7px; + } } .fade-left { @include fade(right, rgba(250, 250, 250, 0.4), $background-color); left: 0; + + .fa { + left: -7px; + } } li { diff --git a/app/views/layouts/nav/_admin.html.haml b/app/views/layouts/nav/_admin.html.haml index 4722c9d9353..8b1acd8d52a 100644 --- a/app/views/layouts/nav/_admin.html.haml +++ b/app/views/layouts/nav/_admin.html.haml @@ -3,6 +3,7 @@ %ul.nav-links.scrolling-tabs .fade-left + = icon('arrow-left') = nav_link(controller: %w(dashboard admin projects users groups builds runners), html_options: {class: 'home'}) do = link_to admin_root_path, title: 'Overview', class: 'shortcuts-tree' do %span @@ -37,3 +38,4 @@ %span Spam Logs .fade-right + = icon('arrow-right') diff --git a/app/views/layouts/nav/_group.html.haml b/app/views/layouts/nav/_group.html.haml index 66361a644dd..42052373cee 100644 --- a/app/views/layouts/nav/_group.html.haml +++ b/app/views/layouts/nav/_group.html.haml @@ -3,6 +3,7 @@ %ul.nav-links.scrolling-tabs .fade-left + = icon('arrow-left') = nav_link(path: 'groups#show', html_options: {class: 'home'}) do = link_to group_path(@group), title: 'Home' do %span @@ -32,3 +33,4 @@ %span Members .fade-right + = icon('arrow-right') diff --git a/app/views/layouts/nav/_profile.html.haml b/app/views/layouts/nav/_profile.html.haml index bb6f14a6225..7fc68398870 100644 --- a/app/views/layouts/nav/_profile.html.haml +++ b/app/views/layouts/nav/_profile.html.haml @@ -1,5 +1,6 @@ %ul.nav-links.scrolling-tabs .fade-left + = icon('arrow-left') = nav_link(path: 'profiles#show', html_options: {class: 'home'}) do = link_to profile_path, title: 'Profile Settings' do %span @@ -44,3 +45,4 @@ %span Audit Log .fade-right + = icon('arrow-right') diff --git a/app/views/layouts/nav/_project.html.haml b/app/views/layouts/nav/_project.html.haml index 39ea4920ccc..840777920a5 100644 --- a/app/views/layouts/nav/_project.html.haml +++ b/app/views/layouts/nav/_project.html.haml @@ -26,6 +26,7 @@ %div{ class: nav_control_class } %ul.nav-links.scrolling-tabs .fade-left + = icon('arrow-left') = nav_link(path: 'projects#show', html_options: {class: 'home'}) do = link_to project_path(@project), title: 'Project', class: 'shortcuts-project' do %span @@ -110,3 +111,4 @@ = link_to project_commits_path(@project), title: 'Commits', class: 'shortcuts-commits' do Commits .fade-right + = icon('arrow-right') diff --git a/app/views/projects/commits/_head.html.haml b/app/views/projects/commits/_head.html.haml index c8aa849c217..7236b299efc 100644 --- a/app/views/projects/commits/_head.html.haml +++ b/app/views/projects/commits/_head.html.haml @@ -2,6 +2,7 @@ .nav-links.sub-nav.scrolling-tabs %ul{ class: (container_class) } .fade-left + = icon('arrow-left') = nav_link(controller: %w(tree blob blame edit_tree new_tree find_file)) do = link_to project_files_path(@project) do Files @@ -26,3 +27,4 @@ = link_to namespace_project_tags_path(@project.namespace, @project) do Tags .fade-right + = icon('arrow-right') diff --git a/app/views/shared/_event_filter.html.haml b/app/views/shared/_event_filter.html.haml index 30055002213..f96cc981c8d 100644 --- a/app/views/shared/_event_filter.html.haml +++ b/app/views/shared/_event_filter.html.haml @@ -1,7 +1,9 @@ %ul.nav-links.event-filter.scrolling-tabs .fade-left + = icon('arrow-left') = event_filter_link EventFilter.push, 'Push events' = event_filter_link EventFilter.merged, 'Merge events' = event_filter_link EventFilter.comments, 'Comments' = event_filter_link EventFilter.team, 'Team' .fade-right + = icon('arrow-right') -- cgit v1.2.1 From e3d9d46beccc087bd28874896153ac906915bf66 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Mon, 20 Jun 2016 12:15:42 -0500 Subject: Update CHANGELOG --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 01e7e7a1606..7ba53612164 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -134,6 +134,7 @@ v 8.9.0 (unreleased) - Remove duplicated keys add UNIQUE index to keys fingerprint column - Cache user todo counts from TodoService - Ensure Todos counters doesn't count Todos for projects pending delete + - Add left/right arrows horizontal navigation v 8.8.5 - Import GitHub repositories respecting the API rate limit !4166 -- cgit v1.2.1 From 0273de3a0728822572f56201e9fe7b3dba510272 Mon Sep 17 00:00:00 2001 From: Alfredo Sumaran Date: Mon, 20 Jun 2016 14:11:15 -0500 Subject: Fixes labels view on mobile --- app/assets/stylesheets/pages/labels.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/pages/labels.scss b/app/assets/stylesheets/pages/labels.scss index 046c38aba44..f5f67e2cd84 100644 --- a/app/assets/stylesheets/pages/labels.scss +++ b/app/assets/stylesheets/pages/labels.scss @@ -50,11 +50,10 @@ .label-row { .label-name { - display: block; + display: inline-block; margin-bottom: 10px; @media (min-width: $screen-sm-min) { - display: inline-block; width: 200px; margin-bottom: 0; } @@ -63,6 +62,7 @@ .label-description { display: block; margin-bottom: 10px; + margin-left: 50px; @media (min-width: $screen-sm-min) { display: inline-block; -- cgit v1.2.1 From 26d2fa0aaa4546ab6d41d08b4f0af66ca5d14ec0 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Mon, 20 Jun 2016 12:30:04 -0700 Subject: Rename Code tab to Repo Closes #18830 --- app/views/layouts/nav/_project.html.haml | 4 ++-- features/steps/project/project_find_file.rb | 4 ++-- features/steps/shared/project_tab.rb | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/views/layouts/nav/_project.html.haml b/app/views/layouts/nav/_project.html.haml index 39ea4920ccc..068332205bb 100644 --- a/app/views/layouts/nav/_project.html.haml +++ b/app/views/layouts/nav/_project.html.haml @@ -38,9 +38,9 @@ - if project_nav_tab? :files = nav_link(controller: %w(tree blob blame edit_tree new_tree find_file commit commits compare repositories tags branches releases network)) do - = link_to project_files_path(@project), title: 'Code', class: 'shortcuts-tree' do + = link_to project_files_path(@project), title: 'Repo', class: 'shortcuts-tree' do %span - Code + Repo - if project_nav_tab? :pipelines = nav_link(controller: [:pipelines, :builds, :environments]) do diff --git a/features/steps/project/project_find_file.rb b/features/steps/project/project_find_file.rb index 47de4b91df1..9833eec3730 100644 --- a/features/steps/project/project_find_file.rb +++ b/features/steps/project/project_find_file.rb @@ -13,12 +13,12 @@ class Spinach::Features::ProjectFindFile < Spinach::FeatureSteps end step 'I should see "find file" page' do - ensure_active_main_tab('Code') + ensure_active_main_tab('Repo') expect(page).to have_selector('.file-finder-holder', count: 1) end step 'I fill in Find by path with "git"' do - ensure_active_main_tab('Code') + ensure_active_main_tab('Repo') expect(page).to have_selector('.file-finder-holder', count: 1) end diff --git a/features/steps/shared/project_tab.rb b/features/steps/shared/project_tab.rb index bfee8793301..595913ff3d8 100644 --- a/features/steps/shared/project_tab.rb +++ b/features/steps/shared/project_tab.rb @@ -8,8 +8,8 @@ module SharedProjectTab ensure_active_main_tab('Project') end - step 'the active main tab should be Code' do - ensure_active_main_tab('Code') + step 'the active main tab should be Repo' do + ensure_active_main_tab('Repo') end step 'the active main tab should be Graphs' do -- cgit v1.2.1 From 208b18c956b38103b98bc93a952dc1e8a200dead Mon Sep 17 00:00:00 2001 From: Paco Guzman Date: Mon, 20 Jun 2016 15:38:54 +0200 Subject: Unify check branch name exist --- app/controllers/projects/application_controller.rb | 2 +- app/helpers/application_helper.rb | 2 +- app/helpers/branches_helper.rb | 2 +- app/models/repository.rb | 7 ++----- app/models/user.rb | 3 +-- spec/workers/merge_worker_spec.rb | 2 +- 6 files changed, 7 insertions(+), 11 deletions(-) diff --git a/app/controllers/projects/application_controller.rb b/app/controllers/projects/application_controller.rb index 776ba92c9ab..996909a28c6 100644 --- a/app/controllers/projects/application_controller.rb +++ b/app/controllers/projects/application_controller.rb @@ -74,7 +74,7 @@ class Projects::ApplicationController < ApplicationController end def require_branch_head - unless @repository.branch_names.include?(@ref) + unless @repository.branch_exists?(@ref) redirect_to( namespace_project_tree_path(@project.namespace, @project, @ref), notice: "This action is not allowed unless you are on a branch" diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 82421d74de9..41859841834 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -116,7 +116,7 @@ module ApplicationHelper return false if project.merge_requests.where(source_branch: event.branch_name).opened.any? # Skip if user removed branch right after that - return false unless project.repository.branch_names.include?(event.branch_name) + return false unless project.repository.branch_exists?(event.branch_name) true end diff --git a/app/helpers/branches_helper.rb b/app/helpers/branches_helper.rb index 3ee3fc74f0c..c533659b600 100644 --- a/app/helpers/branches_helper.rb +++ b/app/helpers/branches_helper.rb @@ -10,7 +10,7 @@ module BranchesHelper end def can_push_branch?(project, branch_name) - return false unless project.repository.branch_names.include?(branch_name) + return false unless project.repository.branch_exists?(branch_name) ::Gitlab::GitAccess.new(current_user, project).can_push_to_branch?(branch_name) end diff --git a/app/models/repository.rb b/app/models/repository.rb index bbd7682d8e7..e9de6418fe0 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -192,7 +192,7 @@ class Repository end def branch_names - cache.fetch(:branch_names) { branches.map(&:name) } + @branch_names ||= cache.fetch(:branch_names) { branches.map(&:name) } end def branch_exists?(branch_name) @@ -267,6 +267,7 @@ class Repository def expire_branches_cache cache.expire(:branch_names) + @branch_names = nil @local_branches = nil end @@ -332,10 +333,6 @@ class Repository @lookup_cache ||= {} end - def expire_branch_names - cache.expire(:branch_names) - end - def expire_avatar_cache(branch_name = nil, revision = nil) # Avatars are pulled from the default branch, thus if somebody pushes to a # different branch there's no need to expire anything. diff --git a/app/models/user.rb b/app/models/user.rb index 2e458329cb9..876ccc69d8d 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -487,9 +487,8 @@ class User < ActiveRecord::Base events.recent.find do |event| project = Project.find_by_id(event.project_id) next unless project - repo = project.repository - if repo.branch_names.include?(event.branch_name) + if project.repository.branch_exists?(event.branch_name) merge_requests = MergeRequest.where("created_at >= ?", event.created_at). where(source_project_id: project.id, source_branch: event.branch_name) diff --git a/spec/workers/merge_worker_spec.rb b/spec/workers/merge_worker_spec.rb index 1abd87d7d33..b5e1fdb8ded 100644 --- a/spec/workers/merge_worker_spec.rb +++ b/spec/workers/merge_worker_spec.rb @@ -9,7 +9,7 @@ describe MergeWorker do before do source_project.team << [author, :master] - source_project.repository.expire_branch_names + source_project.repository.expire_branches_cache end it 'clears cache of source repo after removing source branch' do -- cgit v1.2.1 From df6639070911abd14d76d53891682270473e9bf3 Mon Sep 17 00:00:00 2001 From: Paco Guzman Date: Mon, 20 Jun 2016 16:52:10 +0200 Subject: Get ref_names from branch_names/tag_names cached --- CHANGELOG | 1 + app/models/repository.rb | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 0e19ae06715..fbb545cf2f3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -133,6 +133,7 @@ v 8.9.0 (unreleased) - Use Git cached counters for branches and tags on project page - Filter parameters for request_uri value on instrumented transactions. - Remove duplicated keys add UNIQUE index to keys fingerprint column + - ExtractsPath get ref_names from repository cache, if not there access git. - Cache user todo counts from TodoService - Ensure Todos counters doesn't count Todos for projects pending delete diff --git a/app/models/repository.rb b/app/models/repository.rb index e9de6418fe0..221c87164ca 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -191,6 +191,10 @@ class Repository end end + def ref_names + branch_names + tag_names + end + def branch_names @branch_names ||= cache.fetch(:branch_names) { branches.map(&:name) } end -- cgit v1.2.1 From 79c521f5df560ca6a8bd379dc211ccc1cf3ee3c4 Mon Sep 17 00:00:00 2001 From: Paco Guzman Date: Mon, 20 Jun 2016 21:41:46 +0200 Subject: Provide default branch/file path for ProjectsController#show --- app/controllers/projects_controller.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 78ceaf3237f..2b1f50fd01e 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -303,8 +303,14 @@ class ProjectsController < Projects::ApplicationController project.repository_exists? && !project.empty_repo? end - # Override get_id from ExtractsPath, which returns the branch and file path + # Override extract_ref from ExtractsPath, which returns the branch and file path # for the blob/tree, which in this case is just the root of the default branch. + # This way we avoid to access the repository.ref_names. + def extract_ref(_id) + [get_id, ''] + end + + # Override get_id from ExtractsPath in this case is just the root of the default branch. def get_id project.repository.root_ref end -- cgit v1.2.1 From 27bf7ae59eb95bff0254b8ad3c001ea2397ec544 Mon Sep 17 00:00:00 2001 From: ZJ van de Weg Date: Fri, 27 May 2016 11:00:56 +0200 Subject: Refactor Gitlab::Gitignores --- app/helpers/blob_helper.rb | 8 ++-- lib/api/api.rb | 2 +- lib/api/entities.rb | 4 +- lib/api/gitignores.rb | 29 -------------- lib/api/templates.rb | 35 +++++++++++++++++ lib/gitlab/gitignore.rb | 56 --------------------------- lib/gitlab/template/base_template.rb | 54 ++++++++++++++++++++++++++ lib/gitlab/template/gitignore.rb | 23 +++++++++++ lib/tasks/gitlab/update_gitignore.rake | 46 ---------------------- lib/tasks/gitlab/update_templates.rake | 61 ++++++++++++++++++++++++++++++ spec/lib/gitlab/gitignore_spec.rb | 40 -------------------- spec/lib/gitlab/template/gitignore_spec.rb | 40 ++++++++++++++++++++ spec/requests/api/gitignores_spec.rb | 2 +- 13 files changed, 220 insertions(+), 180 deletions(-) delete mode 100644 lib/api/gitignores.rb create mode 100644 lib/api/templates.rb delete mode 100644 lib/gitlab/gitignore.rb create mode 100644 lib/gitlab/template/base_template.rb create mode 100644 lib/gitlab/template/gitignore.rb delete mode 100644 lib/tasks/gitlab/update_gitignore.rake create mode 100644 lib/tasks/gitlab/update_templates.rake delete mode 100644 spec/lib/gitlab/gitignore_spec.rb create mode 100644 spec/lib/gitlab/template/gitignore_spec.rb diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb index 5b54b34070c..2d42cce95ce 100644 --- a/app/helpers/blob_helper.rb +++ b/app/helpers/blob_helper.rb @@ -188,10 +188,8 @@ module BlobHelper def gitignore_names return @gitignore_names if defined?(@gitignore_names) - @gitignore_names = { - Global: Gitlab::Gitignore.global.map { |gitignore| { name: gitignore.name } }, - # Note that the key here doesn't cover it really - Languages: Gitlab::Gitignore.languages_frameworks.map{ |gitignore| { name: gitignore.name } } - } + @gitignore_names = Gitlab::Template::Gitignore.categories.map do |k, _| + [k, Gitlab::Template::Gitignore.by_category(k)] + end.to_h end end diff --git a/lib/api/api.rb b/lib/api/api.rb index 0e7a1cc2623..f8f680a6311 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -33,7 +33,6 @@ module API mount ::API::Commits mount ::API::DeployKeys mount ::API::Files - mount ::API::Gitignores mount ::API::GroupMembers mount ::API::Groups mount ::API::Internal @@ -58,6 +57,7 @@ module API mount ::API::Subscriptions mount ::API::SystemHooks mount ::API::Tags + mount ::API::Templates mount ::API::Triggers mount ::API::Users mount ::API::Variables diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 2e397643ed1..0c9fc5604fd 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -472,11 +472,11 @@ module API expose :content end - class GitignoresList < Grape::Entity + class TemplatesList < Grape::Entity expose :name end - class Gitignore < Grape::Entity + class Template < Grape::Entity expose :name, :content end end diff --git a/lib/api/gitignores.rb b/lib/api/gitignores.rb deleted file mode 100644 index 270c9501dd2..00000000000 --- a/lib/api/gitignores.rb +++ /dev/null @@ -1,29 +0,0 @@ -module API - class Gitignores < Grape::API - - # Get the list of the available gitignore templates - # - # Example Request: - # GET /gitignores - get 'gitignores' do - present Gitlab::Gitignore.all, with: Entities::GitignoresList - end - - # Get the text for a specific gitignore - # - # Parameters: - # name (required) - The name of a license - # - # Example Request: - # GET /gitignores/Elixir - # - get 'gitignores/:name' do - required_attributes! [:name] - - gitignore = Gitlab::Gitignore.find(params[:name]) - not_found!('.gitignore') unless gitignore - - present gitignore, with: Entities::Gitignore - end - end -end diff --git a/lib/api/templates.rb b/lib/api/templates.rb new file mode 100644 index 00000000000..4c770c0b9dd --- /dev/null +++ b/lib/api/templates.rb @@ -0,0 +1,35 @@ +module API + class Templates < Grape::API + TEMPLATE_TYPES = { + gitignores: Gitlab::Template::Gitignore + }.freeze + + TEMPLATE_TYPES.each do |template, klass| + # Get the list of the available template + # + # Example Request: + # GET /gitignores + # GET /gitlab_ci_ymls + get template.to_s do + present klass.all, with: Entities::TemplatesList + end + + # Get the text for a specific template + # + # Parameters: + # name (required) - The name of a template + # + # Example Request: + # GET /gitignores/Elixir + # GET /gitlab_ci_ymls/Ruby + get "#{template}/:name" do + required_attributes! [:name] + + new_template = klass.find(params[:name]) + not_found!("#{template.to_s.singularize}") unless new_template + + present new_template, with: Entities::Template + end + end + end +end diff --git a/lib/gitlab/gitignore.rb b/lib/gitlab/gitignore.rb deleted file mode 100644 index f46b43b61a4..00000000000 --- a/lib/gitlab/gitignore.rb +++ /dev/null @@ -1,56 +0,0 @@ -module Gitlab - class Gitignore - FILTER_REGEX = /\.gitignore\z/.freeze - - def initialize(path) - @path = path - end - - def name - File.basename(@path, '.gitignore') - end - - def content - File.read(@path) - end - - class << self - def all - languages_frameworks + global - end - - def find(key) - file_name = "#{key}.gitignore" - - directory = select_directory(file_name) - directory ? new(File.join(directory, file_name)) : nil - end - - def global - files_for_folder(global_dir).map { |file| new(File.join(global_dir, file)) } - end - - def languages_frameworks - files_for_folder(gitignore_dir).map { |file| new(File.join(gitignore_dir, file)) } - end - - private - - def select_directory(file_name) - [gitignore_dir, global_dir].find { |dir| File.exist?(File.join(dir, file_name)) } - end - - def global_dir - File.join(gitignore_dir, 'Global') - end - - def gitignore_dir - Rails.root.join('vendor/gitignore') - end - - def files_for_folder(dir) - Dir.glob("#{dir.to_s}/*.gitignore").map { |file| file.gsub(FILTER_REGEX, '') } - end - end - end -end diff --git a/lib/gitlab/template/base_template.rb b/lib/gitlab/template/base_template.rb new file mode 100644 index 00000000000..e1cdfc8f5f6 --- /dev/null +++ b/lib/gitlab/template/base_template.rb @@ -0,0 +1,54 @@ +module Gitlab + module Template + class BaseTemplate + def initialize(path) + @path = path + end + + def name + File.basename(@path, self.class.extension) + end + + def content + File.read(@path) + end + + class << self + def all + self.category_directories.flat_map do |dir| + templates_for_folder(dir) + end + end + + def find(key) + file_name = "#{key}#{self.extension}" + + directory = select_directory(file_name) + directory ? new(File.join(directory, file_name)) : nil + end + + def by_category(category) + templates_for_folder(categories[category]) + end + + def category_directories + self.categories.values.map { |subdir| File.join(base_dir, subdir)} + end + + private + + def select_directory(file_name) + category_directories.find { |dir| File.exist?(File.join(dir, file_name)) } + end + + def templates_for_folder(dir) + Dir.glob("#{dir.to_s}/*#{self.extension}").select { |f| f =~ filter_regex }.map { |f| new(f) } + end + + def filter_regex + /#{Regexp.escape(extension)}\z/ + end + end + end + end +end diff --git a/lib/gitlab/template/gitignore.rb b/lib/gitlab/template/gitignore.rb new file mode 100644 index 00000000000..73fb3b18c4d --- /dev/null +++ b/lib/gitlab/template/gitignore.rb @@ -0,0 +1,23 @@ +module Gitlab + module Template + class Gitignore < BaseTemplate + + class << self + def extension + '.gitignore' + end + + def categories + { + Languages: '', + Global: 'Global' + } + end + + def base_dir + Rails.root.join('vendor/gitignore') + end + end + end + end +end diff --git a/lib/tasks/gitlab/update_gitignore.rake b/lib/tasks/gitlab/update_gitignore.rake deleted file mode 100644 index 4fd48cccb1d..00000000000 --- a/lib/tasks/gitlab/update_gitignore.rake +++ /dev/null @@ -1,46 +0,0 @@ -namespace :gitlab do - desc "GitLab | Update gitignore" - task :update_gitignore do - unless clone_gitignores - puts "Cloning the gitignores failed".color(:red) - return - end - - remove_unneeded_files(gitignore_directory) - remove_unneeded_files(global_directory) - - puts "Done".color(:green) - end - - def clone_gitignores - FileUtils.rm_rf(gitignore_directory) if Dir.exist?(gitignore_directory) - FileUtils.cd vendor_directory - - system('git clone --depth=1 --branch=master https://github.com/github/gitignore.git') - end - - # Retain only certain files: - # - The LICENSE, because we have to - # - The sub dir global - # - The gitignores themself - # - Dir.entires returns also the entries '.' and '..' - def remove_unneeded_files(path) - Dir.foreach(path) do |file| - FileUtils.rm_rf(File.join(path, file)) unless file =~ /(\.{1,2}|LICENSE|Global|\.gitignore)\z/ - end - end - - private - - def vendor_directory - Rails.root.join('vendor') - end - - def gitignore_directory - File.join(vendor_directory, 'gitignore') - end - - def global_directory - File.join(gitignore_directory, 'Global') - end -end diff --git a/lib/tasks/gitlab/update_templates.rake b/lib/tasks/gitlab/update_templates.rake new file mode 100644 index 00000000000..36ffad8aae9 --- /dev/null +++ b/lib/tasks/gitlab/update_templates.rake @@ -0,0 +1,61 @@ +namespace :gitlab do + desc "GitLab | Update templates" + task :update_templates do + update("gitignore") + update("gitlab-ci-yml") + end + + def update(directory) + unless clone_repository(directory) + puts "Cloning the #{directory} templates failed".red + return + end + + remove_unneeded_files(directory) + puts "Done".green + end + + def clone_repository(directory) + dir = File.join(vendor_directory, directory) + FileUtils.rm_rf(dir) if Dir.exist?(dir) + FileUtils.cd vendor_directory + + system("git clone --depth=1 --branch=master #{TEMPLATE_DATA[directory]}") + end + + # Retain only certain files: + # - The LICENSE, because we have to + # - The sub dir global + # - The gitignores themself + # - Dir.entires returns also the entries '.' and '..' + def remove_unneeded_files(directory) + regex = CLEANUP_REGEX[directory] + Dir.foreach(directory) do |file| + FileUtils.rm_rf(File.join(directory, file)) unless file =~ regex + end + end + + private + + TEMPLATE_DATA = { + "gitignore" => "https://github.com/github/gitignore.git", + "gitlab-ci-yml" => "https://gitlab.com/gitlab-org/gitlab-ci-yml.git" + }.freeze + + CLEANUP_REGEX = { + "gitignore" => /(\.{1,2}|LICENSE|Global|\.gitignore)\z/, + "gitlab-ci-yml" => /(\.{1,2}|LICENSE|Pages|\.gitignore)\z/ + }.freeze + + def vendor_directory + Rails.root.join('vendor') + end + + def gitignore_directory + File.join(vendor_directory, 'gitignore') + end + + def gitlab_ci_directory + File.join(vendor_directory, 'gitlab-ci') + end +end diff --git a/spec/lib/gitlab/gitignore_spec.rb b/spec/lib/gitlab/gitignore_spec.rb deleted file mode 100644 index 72baa516cc4..00000000000 --- a/spec/lib/gitlab/gitignore_spec.rb +++ /dev/null @@ -1,40 +0,0 @@ -require 'spec_helper' - -describe Gitlab::Gitignore do - subject { Gitlab::Gitignore } - - describe '.all' do - it 'strips the gitignore suffix' do - expect(subject.all.first.name).not_to end_with('.gitignore') - end - - it 'combines the globals and rest' do - all = subject.all.map(&:name) - - expect(all).to include('Vim') - expect(all).to include('Ruby') - end - end - - describe '.find' do - it 'returns nil if the file does not exist' do - expect(subject.find('mepmep-yadida')).to be nil - end - - it 'returns the Gitignore object of a valid file' do - ruby = subject.find('Ruby') - - expect(ruby).to be_a Gitlab::Gitignore - expect(ruby.name).to eq('Ruby') - end - end - - describe '#content' do - it 'loads the full file' do - gitignore = subject.new(Rails.root.join('vendor/gitignore/Ruby.gitignore')) - - expect(gitignore.name).to eq 'Ruby' - expect(gitignore.content).to start_with('*.gem') - end - end -end diff --git a/spec/lib/gitlab/template/gitignore_spec.rb b/spec/lib/gitlab/template/gitignore_spec.rb new file mode 100644 index 00000000000..bc0ec9325cc --- /dev/null +++ b/spec/lib/gitlab/template/gitignore_spec.rb @@ -0,0 +1,40 @@ +require 'spec_helper' + +describe Gitlab::Template::Gitignore do + subject { described_class } + + describe '.all' do + it 'strips the gitignore suffix' do + expect(subject.all.first.name).not_to end_with('.gitignore') + end + + it 'combines the globals and rest' do + all = subject.all.map(&:name) + + expect(all).to include('Vim') + expect(all).to include('Ruby') + end + end + + describe '.find' do + it 'returns nil if the file does not exist' do + expect(subject.find('mepmep-yadida')).to be nil + end + + it 'returns the Gitignore object of a valid file' do + ruby = subject.find('Ruby') + + expect(ruby).to be_a Gitlab::Template::Gitignore + expect(ruby.name).to eq('Ruby') + end + end + + describe '#content' do + it 'loads the full file' do + gitignore = subject.new(Rails.root.join('vendor/gitignore/Ruby.gitignore')) + + expect(gitignore.name).to eq 'Ruby' + expect(gitignore.content).to start_with('*.gem') + end + end +end diff --git a/spec/requests/api/gitignores_spec.rb b/spec/requests/api/gitignores_spec.rb index aab2d8c81b9..9130312c057 100644 --- a/spec/requests/api/gitignores_spec.rb +++ b/spec/requests/api/gitignores_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe API::Gitignores, api: true do +describe API::Templates, api: true do include ApiHelpers describe 'Entity Gitignore' do -- cgit v1.2.1 From 567f6a7b4271d97afd6dea1545210b9aba858421 Mon Sep 17 00:00:00 2001 From: "Z.J. van de Weg" Date: Thu, 9 Jun 2016 13:32:26 +0200 Subject: Add first templates for gitlab-ci dropdown --- vendor/gitlab-ci-yml/LICENSE | 21 +++++++++++++++++ vendor/gitlab-ci-yml/Pages/brunch.gitlab-ci.yml | 16 +++++++++++++ vendor/gitlab-ci-yml/Pages/doxygen.gitlab-ci.yml | 13 +++++++++++ vendor/gitlab-ci-yml/Pages/harp.gitlab-ci.yml | 16 +++++++++++++ vendor/gitlab-ci-yml/Pages/hexo.gitlab-ci.yml | 25 ++++++++++++++++++++ vendor/gitlab-ci-yml/Pages/html.gitlab-ci.yml | 12 ++++++++++ vendor/gitlab-ci-yml/Pages/hugo.gitlab-ci.yml | 11 +++++++++ vendor/gitlab-ci-yml/Pages/hyde.gitlab-ci.yml | 25 ++++++++++++++++++++ vendor/gitlab-ci-yml/Pages/jekyll.gitlab-ci.yml | 24 +++++++++++++++++++ vendor/gitlab-ci-yml/Pages/lektor.gitlab-ci.yml | 12 ++++++++++ .../gitlab-ci-yml/Pages/metalsmith.gitlab-ci.yml | 17 ++++++++++++++ vendor/gitlab-ci-yml/Pages/middleman.gitlab-ci.yml | 27 ++++++++++++++++++++++ vendor/gitlab-ci-yml/Pages/nanoc.gitlab-ci.yml | 12 ++++++++++ vendor/gitlab-ci-yml/Pages/octopress.gitlab-ci.yml | 15 ++++++++++++ vendor/gitlab-ci-yml/Pages/pelican.gitlab-ci.yml | 10 ++++++++ 15 files changed, 256 insertions(+) create mode 100644 vendor/gitlab-ci-yml/LICENSE create mode 100644 vendor/gitlab-ci-yml/Pages/brunch.gitlab-ci.yml create mode 100644 vendor/gitlab-ci-yml/Pages/doxygen.gitlab-ci.yml create mode 100644 vendor/gitlab-ci-yml/Pages/harp.gitlab-ci.yml create mode 100644 vendor/gitlab-ci-yml/Pages/hexo.gitlab-ci.yml create mode 100644 vendor/gitlab-ci-yml/Pages/html.gitlab-ci.yml create mode 100644 vendor/gitlab-ci-yml/Pages/hugo.gitlab-ci.yml create mode 100644 vendor/gitlab-ci-yml/Pages/hyde.gitlab-ci.yml create mode 100644 vendor/gitlab-ci-yml/Pages/jekyll.gitlab-ci.yml create mode 100644 vendor/gitlab-ci-yml/Pages/lektor.gitlab-ci.yml create mode 100644 vendor/gitlab-ci-yml/Pages/metalsmith.gitlab-ci.yml create mode 100644 vendor/gitlab-ci-yml/Pages/middleman.gitlab-ci.yml create mode 100644 vendor/gitlab-ci-yml/Pages/nanoc.gitlab-ci.yml create mode 100644 vendor/gitlab-ci-yml/Pages/octopress.gitlab-ci.yml create mode 100644 vendor/gitlab-ci-yml/Pages/pelican.gitlab-ci.yml diff --git a/vendor/gitlab-ci-yml/LICENSE b/vendor/gitlab-ci-yml/LICENSE new file mode 100644 index 00000000000..80f7b87b6c0 --- /dev/null +++ b/vendor/gitlab-ci-yml/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 GitLab.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/gitlab-ci-yml/Pages/brunch.gitlab-ci.yml b/vendor/gitlab-ci-yml/Pages/brunch.gitlab-ci.yml new file mode 100644 index 00000000000..7fcc0b436b5 --- /dev/null +++ b/vendor/gitlab-ci-yml/Pages/brunch.gitlab-ci.yml @@ -0,0 +1,16 @@ +# Full project: https://gitlab.com/pages/brunch +image: node:4.2.2 + +pages: + cache: + paths: + - node_modules/ + + script: + - npm install -g brunch + - brunch build --production + artifacts: + paths: + - public + only: + - master diff --git a/vendor/gitlab-ci-yml/Pages/doxygen.gitlab-ci.yml b/vendor/gitlab-ci-yml/Pages/doxygen.gitlab-ci.yml new file mode 100644 index 00000000000..791afdd23f1 --- /dev/null +++ b/vendor/gitlab-ci-yml/Pages/doxygen.gitlab-ci.yml @@ -0,0 +1,13 @@ +# Full project: https://gitlab.com/pages/doxygen +image: alpine + +pages: + script: + - apk update && apk add doxygen + - doxygen doxygen/Doxyfile + - mv doxygen/documentation/html/ public/ + artifacts: + paths: + - public + only: + - master diff --git a/vendor/gitlab-ci-yml/Pages/harp.gitlab-ci.yml b/vendor/gitlab-ci-yml/Pages/harp.gitlab-ci.yml new file mode 100644 index 00000000000..dd3ef149668 --- /dev/null +++ b/vendor/gitlab-ci-yml/Pages/harp.gitlab-ci.yml @@ -0,0 +1,16 @@ +# Full project: https://gitlab.com/pages/harp +image: node:4.2.2 + +pages: + cache: + paths: + - node_modules + + script: + - npm install -g harp + - harp compile ./ public + artifacts: + paths: + - public + only: + - master diff --git a/vendor/gitlab-ci-yml/Pages/hexo.gitlab-ci.yml b/vendor/gitlab-ci-yml/Pages/hexo.gitlab-ci.yml new file mode 100644 index 00000000000..b468d79bcad --- /dev/null +++ b/vendor/gitlab-ci-yml/Pages/hexo.gitlab-ci.yml @@ -0,0 +1,25 @@ +# Full project: https://gitlab.com/pages/hexo +image: python:2.7 + +cache: + paths: + - vendor/ + +test: + stage: test + script: + - pip install hyde + - hyde gen + except: + - master + +pages: + stage: deploy + script: + - pip install hyde + - hyde gen -d public + artifacts: + paths: + - public + only: + - master diff --git a/vendor/gitlab-ci-yml/Pages/html.gitlab-ci.yml b/vendor/gitlab-ci-yml/Pages/html.gitlab-ci.yml new file mode 100644 index 00000000000..249a168aa33 --- /dev/null +++ b/vendor/gitlab-ci-yml/Pages/html.gitlab-ci.yml @@ -0,0 +1,12 @@ +# Full project: https://gitlab.com/pages/plain-html +pages: + stage: deploy + script: + - mkdir .public + - cp -r * .public + - mv .public public + artifacts: + paths: + - public + only: + - master diff --git a/vendor/gitlab-ci-yml/Pages/hugo.gitlab-ci.yml b/vendor/gitlab-ci-yml/Pages/hugo.gitlab-ci.yml new file mode 100644 index 00000000000..45df6975259 --- /dev/null +++ b/vendor/gitlab-ci-yml/Pages/hugo.gitlab-ci.yml @@ -0,0 +1,11 @@ +# Full project: https://gitlab.com/pages/hugo +image: publysher/hugo + +pages: + script: + - hugo + artifacts: + paths: + - public + only: + - master diff --git a/vendor/gitlab-ci-yml/Pages/hyde.gitlab-ci.yml b/vendor/gitlab-ci-yml/Pages/hyde.gitlab-ci.yml new file mode 100644 index 00000000000..f5b40f2b9f1 --- /dev/null +++ b/vendor/gitlab-ci-yml/Pages/hyde.gitlab-ci.yml @@ -0,0 +1,25 @@ +# Full project: https://gitlab.com/pages/hyde +image: python:2.7 + +cache: + paths: + - vendor/ + +test: + stage: test + script: + - pip install hyde + - hyde gen + except: + - master + +pages: + stage: deploy + script: + - pip install hyde + - hyde gen -d public + artifacts: + paths: + - public + only: + - master diff --git a/vendor/gitlab-ci-yml/Pages/jekyll.gitlab-ci.yml b/vendor/gitlab-ci-yml/Pages/jekyll.gitlab-ci.yml new file mode 100644 index 00000000000..36918fc005a --- /dev/null +++ b/vendor/gitlab-ci-yml/Pages/jekyll.gitlab-ci.yml @@ -0,0 +1,24 @@ +# Full project: https://gitlab.com/pages/jekyll +image: ruby:2.3 + +test: + stage: test + script: + - gem install jekyll + - jekyll build -d test + artifacts: + paths: + - test + except: + - master + +pages: + stage: deploy + script: + - gem install jekyll + - jekyll build -d public + artifacts: + paths: + - public + only: + - master diff --git a/vendor/gitlab-ci-yml/Pages/lektor.gitlab-ci.yml b/vendor/gitlab-ci-yml/Pages/lektor.gitlab-ci.yml new file mode 100644 index 00000000000..c5c44a5d86c --- /dev/null +++ b/vendor/gitlab-ci-yml/Pages/lektor.gitlab-ci.yml @@ -0,0 +1,12 @@ +# Full project: https://gitlab.com/pages/hyde +image: python:2.7 + +pages: + script: + - pip install lektor + - lektor build --output-path public + artifacts: + paths: + - public + only: + - master diff --git a/vendor/gitlab-ci-yml/Pages/metalsmith.gitlab-ci.yml b/vendor/gitlab-ci-yml/Pages/metalsmith.gitlab-ci.yml new file mode 100644 index 00000000000..50e8b7ccd46 --- /dev/null +++ b/vendor/gitlab-ci-yml/Pages/metalsmith.gitlab-ci.yml @@ -0,0 +1,17 @@ +# Full project: https://gitlab.com/pages/metalsmith +image: node:4.2.2 + +pages: + cache: + paths: + - node_modules/ + + script: + - npm install -g metalsmith + - npm install + - make build + artifacts: + paths: + - public + only: + - master diff --git a/vendor/gitlab-ci-yml/Pages/middleman.gitlab-ci.yml b/vendor/gitlab-ci-yml/Pages/middleman.gitlab-ci.yml new file mode 100644 index 00000000000..9f4cc0574d6 --- /dev/null +++ b/vendor/gitlab-ci-yml/Pages/middleman.gitlab-ci.yml @@ -0,0 +1,27 @@ +# Full project: https://gitlab.com/pages/middleman +image: ruby:2.3 + +cache: + paths: + - vendor + +test: + script: + - apt-get update -yqqq + - apt-get install -y nodejs + - bundle install --path vendor + - bundle exec middleman build + except: + - master + +pages: + script: + - apt-get update -yqqq + - apt-get install -y nodejs + - bundle install --path vendor + - bundle exec middleman build + artifacts: + paths: + - public + only: + - master diff --git a/vendor/gitlab-ci-yml/Pages/nanoc.gitlab-ci.yml b/vendor/gitlab-ci-yml/Pages/nanoc.gitlab-ci.yml new file mode 100644 index 00000000000..b469b316ba5 --- /dev/null +++ b/vendor/gitlab-ci-yml/Pages/nanoc.gitlab-ci.yml @@ -0,0 +1,12 @@ +# Full project: https://gitlab.com/pages/nanoc +image: ruby:2.3 + +pages: + script: + - bundle install -j4 + - nanoc + artifacts: + paths: + - public + only: + - master diff --git a/vendor/gitlab-ci-yml/Pages/octopress.gitlab-ci.yml b/vendor/gitlab-ci-yml/Pages/octopress.gitlab-ci.yml new file mode 100644 index 00000000000..4762ec9acfd --- /dev/null +++ b/vendor/gitlab-ci-yml/Pages/octopress.gitlab-ci.yml @@ -0,0 +1,15 @@ +# Full project: https://gitlab.com/pages/octopress +image: ruby:2.3 + +pages: + script: + - apt-get update -qq && apt-get install -qq nodejs + - bundle install -j4 + - bundle exec rake generate + - mv public .public + - mv .public/octopress public + artifacts: + paths: + - public + only: + - master diff --git a/vendor/gitlab-ci-yml/Pages/pelican.gitlab-ci.yml b/vendor/gitlab-ci-yml/Pages/pelican.gitlab-ci.yml new file mode 100644 index 00000000000..c5f3154f587 --- /dev/null +++ b/vendor/gitlab-ci-yml/Pages/pelican.gitlab-ci.yml @@ -0,0 +1,10 @@ +# Full project: https://gitlab.com/pages/pelican +image: python:2.7-alpine + +pages: + script: + - pip install -r requirements.txt + - pelican -s publishconf.py + artifacts: + paths: + - public/ -- cgit v1.2.1 From 620d014aefd23030ed6ae043e223ccc5dc52fc8a Mon Sep 17 00:00:00 2001 From: "Z.J. van de Weg" Date: Thu, 2 Jun 2016 18:20:08 +0200 Subject: Implement backend gitlab ci dropdown This commit builds on the groundwork in ee008e300b1ec0abcc90e6a30816ec0754cea0dd, which refactored the backend so the same code could be used for new dropdowns. In this commit its used for templates for the `.gitlab-ci.yml` files. --- app/helpers/blob_helper.rb | 14 ++++++--- lib/api/templates.rb | 3 +- lib/gitlab/template/base_template.rb | 35 +++++++++++++++------- lib/gitlab/template/gitignore.rb | 5 ++-- lib/gitlab/template/gitlab_ci_yml.rb | 22 ++++++++++++++ lib/tasks/gitlab/update_templates.rake | 55 ++++++++++++++-------------------- spec/requests/api/gitignores_spec.rb | 29 ------------------ spec/requests/api/templates_spec.rb | 43 ++++++++++++++++++++++++++ 8 files changed, 126 insertions(+), 80 deletions(-) create mode 100644 lib/gitlab/template/gitlab_ci_yml.rb delete mode 100644 spec/requests/api/gitignores_spec.rb create mode 100644 spec/requests/api/templates_spec.rb diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb index 2d42cce95ce..b30a01614be 100644 --- a/app/helpers/blob_helper.rb +++ b/app/helpers/blob_helper.rb @@ -186,10 +186,16 @@ module BlobHelper end def gitignore_names - return @gitignore_names if defined?(@gitignore_names) + @gitignore_names ||= + Gitlab::Template::Gitignore.categories.keys.map do |k| + [k, Gitlab::Template::Gitignore.by_category(k).map { |t| { name: t.name } }] + end.to_h + end - @gitignore_names = Gitlab::Template::Gitignore.categories.map do |k, _| - [k, Gitlab::Template::Gitignore.by_category(k)] - end.to_h + def gitlab_ci_ymls + @gitlab_ci_ymls ||= + Gitlab::Template::GitlabCIYml.categories.keys.map do |k| + [k, Gitlab::Template::GitlabCIYml.by_category(k).map { |t| { name: t.name } }] + end.to_h end end diff --git a/lib/api/templates.rb b/lib/api/templates.rb index 4c770c0b9dd..9f5f10a5088 100644 --- a/lib/api/templates.rb +++ b/lib/api/templates.rb @@ -1,7 +1,8 @@ module API class Templates < Grape::API TEMPLATE_TYPES = { - gitignores: Gitlab::Template::Gitignore + gitignores: Gitlab::Template::Gitignore, + gitlab_ci_ymls: Gitlab::Template::GitlabCIYml }.freeze TEMPLATE_TYPES.each do |template, klass| diff --git a/lib/gitlab/template/base_template.rb b/lib/gitlab/template/base_template.rb index e1cdfc8f5f6..652a496b57b 100644 --- a/lib/gitlab/template/base_template.rb +++ b/lib/gitlab/template/base_template.rb @@ -13,40 +13,53 @@ module Gitlab File.read(@path) end + def categories + raise NotImplementedError + end + + def extension + raise NotImplementedError + end + + def base_dir + raise NotImplementedError + end + class << self def all - self.category_directories.flat_map do |dir| - templates_for_folder(dir) - end + self.categories.keys.flat_map { |cat| by_category(cat) } end def find(key) file_name = "#{key}#{self.extension}" directory = select_directory(file_name) - directory ? new(File.join(directory, file_name)) : nil + directory ? new(File.join(category_directory(directory), file_name)) : nil end def by_category(category) - templates_for_folder(categories[category]) + templates_for_directory(category_directory(category)) end - def category_directories - self.categories.values.map { |subdir| File.join(base_dir, subdir)} + def category_directory(category) + File.join(base_dir, categories[category]) end private def select_directory(file_name) - category_directories.find { |dir| File.exist?(File.join(dir, file_name)) } + categories.keys.find do |category| + File.exist?(File.join(category_directory(category), file_name)) + end end - def templates_for_folder(dir) - Dir.glob("#{dir.to_s}/*#{self.extension}").select { |f| f =~ filter_regex }.map { |f| new(f) } + def templates_for_directory(dir) + dir << '/' unless dir.end_with?('/') + Dir.glob(File.join(dir, "*#{self.extension}")).select { |f| f =~ filter_regex }.map { |f| new(f) } end def filter_regex - /#{Regexp.escape(extension)}\z/ + @filter_reges ||= /#{Regexp.escape(extension)}\z/ end end end diff --git a/lib/gitlab/template/gitignore.rb b/lib/gitlab/template/gitignore.rb index 73fb3b18c4d..964fbfd4de3 100644 --- a/lib/gitlab/template/gitignore.rb +++ b/lib/gitlab/template/gitignore.rb @@ -1,7 +1,6 @@ module Gitlab module Template class Gitignore < BaseTemplate - class << self def extension '.gitignore' @@ -9,8 +8,8 @@ module Gitlab def categories { - Languages: '', - Global: 'Global' + "Languages" => '', + "Global" => 'Global' } end diff --git a/lib/gitlab/template/gitlab_ci_yml.rb b/lib/gitlab/template/gitlab_ci_yml.rb new file mode 100644 index 00000000000..20377499ac9 --- /dev/null +++ b/lib/gitlab/template/gitlab_ci_yml.rb @@ -0,0 +1,22 @@ +module Gitlab + module Template + class GitlabCIYml < BaseTemplate + class << self + def extension + '.gitlab-ci.yml' + end + + def categories + { + "General" => '', + "Pages" =>'Pages' + } + end + + def base_dir + Rails.root.join('vendor/gitlab-ci-yml') + end + end + end + end +end diff --git a/lib/tasks/gitlab/update_templates.rake b/lib/tasks/gitlab/update_templates.rake index 36ffad8aae9..90b1a64ed5a 100644 --- a/lib/tasks/gitlab/update_templates.rake +++ b/lib/tasks/gitlab/update_templates.rake @@ -1,35 +1,34 @@ namespace :gitlab do desc "GitLab | Update templates" task :update_templates do - update("gitignore") - update("gitlab-ci-yml") + TEMPLATE_DATA.each { |template| update(template) } end - def update(directory) - unless clone_repository(directory) - puts "Cloning the #{directory} templates failed".red + def update(template) + sub_dir = template.repo_url.match(/([a-z-]+)\.git\z/)[1] + dir = File.join(vendor_directory, sub_dir) + + unless clone_repository(template.repo_url, dir) + puts "Cloning the #{sub_dir} templates failed".red return end - remove_unneeded_files(directory) + remove_unneeded_files(dir, template.cleanup_regex) puts "Done".green end - def clone_repository(directory) - dir = File.join(vendor_directory, directory) - FileUtils.rm_rf(dir) if Dir.exist?(dir) - FileUtils.cd vendor_directory + def clone_repository(url, directory) + FileUtils.rm_rf(directory) if Dir.exist?(directory) - system("git clone --depth=1 --branch=master #{TEMPLATE_DATA[directory]}") + system("git clone #{url} --depth=1 --branch=master #{directory}") end # Retain only certain files: # - The LICENSE, because we have to - # - The sub dir global - # - The gitignores themself + # - The sub dirs so we can organise the file by category + # - The templates themself # - Dir.entires returns also the entries '.' and '..' - def remove_unneeded_files(directory) - regex = CLEANUP_REGEX[directory] + def remove_unneeded_files(directory, regex) Dir.foreach(directory) do |file| FileUtils.rm_rf(File.join(directory, file)) unless file =~ regex end @@ -37,25 +36,17 @@ namespace :gitlab do private - TEMPLATE_DATA = { - "gitignore" => "https://github.com/github/gitignore.git", - "gitlab-ci-yml" => "https://gitlab.com/gitlab-org/gitlab-ci-yml.git" - }.freeze - - CLEANUP_REGEX = { - "gitignore" => /(\.{1,2}|LICENSE|Global|\.gitignore)\z/, - "gitlab-ci-yml" => /(\.{1,2}|LICENSE|Pages|\.gitignore)\z/ - }.freeze + Template = Struct.new(:repo_url, :cleanup_regex) + TEMPLATE_DATA = [Template.new( + "https://github.com/github/gitignore.git", + /(\.{1,2}|LICENSE|Global|\.gitignore)\z/ + ), + Template.new( + "https://gitlab.com/gitlab-org/gitlab-ci-yml.git", + /(\.{1,2}|LICENSE|Pages|\.gitignore)\z/ + )] def vendor_directory Rails.root.join('vendor') end - - def gitignore_directory - File.join(vendor_directory, 'gitignore') - end - - def gitlab_ci_directory - File.join(vendor_directory, 'gitlab-ci') - end end diff --git a/spec/requests/api/gitignores_spec.rb b/spec/requests/api/gitignores_spec.rb deleted file mode 100644 index 9130312c057..00000000000 --- a/spec/requests/api/gitignores_spec.rb +++ /dev/null @@ -1,29 +0,0 @@ -require 'spec_helper' - -describe API::Templates, api: true do - include ApiHelpers - - describe 'Entity Gitignore' do - before { get api('/gitignores/Ruby') } - - it { expect(json_response['name']).to eq('Ruby') } - it { expect(json_response['content']).to include('*.gem') } - end - - describe 'Entity GitignoresList' do - before { get api('/gitignores') } - - it { expect(json_response.first['name']).not_to be_nil } - it { expect(json_response.first['content']).to be_nil } - end - - describe 'GET /gitignores' do - it 'returns a list of available license templates' do - get api('/gitignores') - - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.size).to be > 15 - end - end -end diff --git a/spec/requests/api/templates_spec.rb b/spec/requests/api/templates_spec.rb new file mode 100644 index 00000000000..0e9a28b1ff6 --- /dev/null +++ b/spec/requests/api/templates_spec.rb @@ -0,0 +1,43 @@ +require 'spec_helper' + +describe API::Templates, api: true do + include ApiHelpers + + describe 'the Template Entity' do + before { get api('/gitignores/Ruby') } + + it { expect(json_response['name']).to eq('Ruby') } + it { expect(json_response['content']).to include('*.gem') } + end + + describe 'the TemplateList Entity' do + before { get api('/gitignores') } + + it { expect(json_response.first['name']).not_to be_nil } + it { expect(json_response.first['content']).to be_nil } + end + + context 'requesting gitignores' do + describe 'GET /gitignores' do + it 'returns a list of available gitignore templates' do + get api('/gitignores') + + expect(response.status).to eq(200) + expect(json_response).to be_an Array + expect(json_response.size).to be > 15 + end + end + end + + context 'requesting gitlab-ci-ymls' do + describe 'GET /gitlab_ci_ymls' do + it 'returns a list of available gitlab_ci_ymls' do + get api('/gitlab_ci_ymls') + + expect(response.status).to eq(200) + expect(json_response).to be_an Array + expect(json_response.first['name']).not_to be_nil + end + end + end +end -- cgit v1.2.1 From 5d12189296e173616ee980c60943680ed2d7d061 Mon Sep 17 00:00:00 2001 From: Alfredo Sumaran Date: Thu, 16 Jun 2016 02:06:30 -0500 Subject: Add GitLab CI Yml dropdown selector --- app/assets/javascripts/api.js.coffee | 7 +++++++ app/assets/javascripts/blob/blob_ci_yaml.js.coffee | 23 ++++++++++++++++++++++ app/assets/javascripts/blob/edit_blob.js.coffee | 1 + app/assets/stylesheets/pages/editor.scss | 11 +++++++++-- app/views/projects/blob/_editor.html.haml | 2 ++ 5 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 app/assets/javascripts/blob/blob_ci_yaml.js.coffee diff --git a/app/assets/javascripts/api.js.coffee b/app/assets/javascripts/api.js.coffee index 3f61ea1eaf4..d543e3b7a96 100644 --- a/app/assets/javascripts/api.js.coffee +++ b/app/assets/javascripts/api.js.coffee @@ -7,6 +7,7 @@ labelsPath: "/api/:version/projects/:id/labels" licensePath: "/api/:version/licenses/:key" gitignorePath: "/api/:version/gitignores/:key" + gitlabCIYmlPath: "/api/:version/gitlab_ci_ymls/:key" group: (group_id, callback) -> url = Api.buildUrl(Api.groupPath) @@ -110,6 +111,12 @@ $.get url, (gitignore) -> callback(gitignore) + gitlabCIYml: (key, callback) -> + url = Api.buildUrl(Api.gitlabCIYmlPath).replace(':key', key) + + $.get url, (file) -> + callback(file) + buildUrl: (url) -> url = gon.relative_url_root + url if gon.relative_url_root? return url.replace(':version', gon.api_version) diff --git a/app/assets/javascripts/blob/blob_ci_yaml.js.coffee b/app/assets/javascripts/blob/blob_ci_yaml.js.coffee new file mode 100644 index 00000000000..dc14700d305 --- /dev/null +++ b/app/assets/javascripts/blob/blob_ci_yaml.js.coffee @@ -0,0 +1,23 @@ +#= require blob/template_selector + +class @BlobCiYamlSelector extends TemplateSelector + requestFile: (query) -> + Api.gitlabCIYml query.name, @requestFileSuccess.bind(@) + +class @BlobCiYamlSelectors + constructor: (opts) -> + { + @$dropdowns = $('.js-gitlab-ci-yml-selector') + @editor + } = opts + + @$dropdowns.each (i, dropdown) => + $dropdown = $(dropdown) + + new BlobCiYamlSelector( + pattern: /(.gitlab-ci.yml)/, + data: $dropdown.data('data'), + wrapper: $dropdown.closest('.js-gitlab-ci-yml-selector-wrap'), + dropdown: $dropdown, + editor: @editor + ) diff --git a/app/assets/javascripts/blob/edit_blob.js.coffee b/app/assets/javascripts/blob/edit_blob.js.coffee index 636f909dbd0..19e584519d7 100644 --- a/app/assets/javascripts/blob/edit_blob.js.coffee +++ b/app/assets/javascripts/blob/edit_blob.js.coffee @@ -15,6 +15,7 @@ class @EditBlob new BlobLicenseSelectors { @editor } new BlobGitignoreSelectors { @editor } + new BlobCiYamlSelectors { @editor } initModePanesAndLinks: -> @$editModePanes = $(".js-edit-mode-pane") diff --git a/app/assets/stylesheets/pages/editor.scss b/app/assets/stylesheets/pages/editor.scss index a34b06f1054..1aa4e06d975 100644 --- a/app/assets/stylesheets/pages/editor.scss +++ b/app/assets/stylesheets/pages/editor.scss @@ -60,13 +60,14 @@ .encoding-selector, .license-selector, - .gitignore-selector { + .gitignore-selector, + .gitlab-ci-yml-selector { display: inline-block; vertical-align: top; font-family: $regular_font; } - .gitignore-selector, .license-selector { + .gitignore-selector, .license-selector, .gitlab-ci-yml-selector { .dropdown { line-height: 21px; } @@ -76,4 +77,10 @@ width: 220px; } } + + .gitlab-ci-yml-selector { + .dropdown-menu-toggle { + width: 250px; + } + } } diff --git a/app/views/projects/blob/_editor.html.haml b/app/views/projects/blob/_editor.html.haml index ae89637df60..29c7d45074a 100644 --- a/app/views/projects/blob/_editor.html.haml +++ b/app/views/projects/blob/_editor.html.haml @@ -17,6 +17,8 @@ = dropdown_tag("Choose a License template", options: { toggle_class: 'js-license-selector', title: "Choose a license", filter: true, placeholder: "Filter", data: { data: licenses_for_select, project: @project.name, fullname: @project.namespace.human_name } } ) .gitignore-selector.js-gitignore-selector-wrap.hidden = dropdown_tag("Choose a .gitignore template", options: { toggle_class: 'js-gitignore-selector', title: "Choose a template", filter: true, placeholder: "Filter", data: { data: gitignore_names } } ) + .gitlab-ci-yml-selector.js-gitlab-ci-yml-selector-wrap.hidden + = dropdown_tag("Choose a GitLab CI Yaml template", options: { toggle_class: 'js-gitlab-ci-yml-selector', title: "Choose a template", filter: true, placeholder: "Filter", data: { data: gitlab_ci_ymls } } ) .encoding-selector = select_tag :encoding, options_for_select([ "base64", "text" ], "text"), class: 'select2' -- cgit v1.2.1 From 8039856d80ce710f69af611f58857b29b74712b4 Mon Sep 17 00:00:00 2001 From: "Z.J. van de Weg" Date: Thu, 16 Jun 2016 10:09:41 +0200 Subject: Add changelog item, fix rubocop issue --- CHANGELOG | 1 + lib/gitlab/template/gitlab_ci_yml.rb | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 0e19ae06715..f26512c87ba 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -102,6 +102,7 @@ v 8.9.0 (unreleased) - An indicator is now displayed at the top of the comment field for confidential issues. - Show categorised search queries in the search autocomplete - RepositoryCheck::SingleRepositoryWorker public and private methods are now instrumented + - Dropdown for `.gitlab-ci.yml` templates - Improve issuables APIs performance when accessing notes !4471 - Add sorting dropdown to tags page !4423 - External links now open in a new tab diff --git a/lib/gitlab/template/gitlab_ci_yml.rb b/lib/gitlab/template/gitlab_ci_yml.rb index 20377499ac9..da7273b8d70 100644 --- a/lib/gitlab/template/gitlab_ci_yml.rb +++ b/lib/gitlab/template/gitlab_ci_yml.rb @@ -9,7 +9,7 @@ module Gitlab def categories { "General" => '', - "Pages" =>'Pages' + "Pages" => 'Pages' } end -- cgit v1.2.1 From 96ae6099dd5921ae32139a206d598043520fb506 Mon Sep 17 00:00:00 2001 From: "Z.J. van de Weg" Date: Thu, 16 Jun 2016 10:39:17 +0200 Subject: Run rake gitlab:update_templates --- lib/tasks/gitlab/update_templates.rake | 2 +- vendor/gitignore/Android.gitignore | 3 ++- vendor/gitignore/C++.gitignore | 1 + vendor/gitignore/CMake.gitignore | 1 + vendor/gitignore/D.gitignore | 4 ++++ vendor/gitignore/Global/Bazaar.gitignore | 2 ++ vendor/gitignore/Global/OSX.gitignore | 3 ++- vendor/gitignore/Global/README.md | 10 +++++++++ vendor/gitignore/Global/SublimeText.gitignore | 13 ++++++++++++ vendor/gitignore/Haskell.gitignore | 1 + vendor/gitignore/Julia.gitignore | 4 ++++ vendor/gitignore/LICENSE | 19 +++++++++++++++++ vendor/gitignore/Laravel.gitignore | 1 - vendor/gitignore/Objective-C.gitignore | 9 ++++++++ vendor/gitignore/Qt.gitignore | 2 +- vendor/gitignore/README.md | 14 ------------- vendor/gitignore/Rails.gitignore | 4 ++++ vendor/gitignore/Swift.gitignore | 2 ++ vendor/gitignore/UnrealEngine.gitignore | 1 + vendor/gitignore/VisualStudio.gitignore | 1 + vendor/gitlab-ci-yml/Docker.gitlab-ci.yml | 7 +++++++ vendor/gitlab-ci-yml/Elixir.gitlab-ci.yml | 18 ++++++++++++++++ vendor/gitlab-ci-yml/Nodejs.gitlab-ci.yml | 27 ++++++++++++++++++++++++ vendor/gitlab-ci-yml/Ruby.gitlab-ci.yml | 30 +++++++++++++++++++++++++++ 24 files changed, 160 insertions(+), 19 deletions(-) create mode 100644 vendor/gitignore/Global/Bazaar.gitignore create mode 100644 vendor/gitignore/Global/README.md create mode 100644 vendor/gitignore/Julia.gitignore create mode 100644 vendor/gitignore/LICENSE delete mode 100644 vendor/gitignore/README.md create mode 100644 vendor/gitlab-ci-yml/Docker.gitlab-ci.yml create mode 100644 vendor/gitlab-ci-yml/Elixir.gitlab-ci.yml create mode 100644 vendor/gitlab-ci-yml/Nodejs.gitlab-ci.yml create mode 100644 vendor/gitlab-ci-yml/Ruby.gitlab-ci.yml diff --git a/lib/tasks/gitlab/update_templates.rake b/lib/tasks/gitlab/update_templates.rake index 90b1a64ed5a..14277fe4c4b 100644 --- a/lib/tasks/gitlab/update_templates.rake +++ b/lib/tasks/gitlab/update_templates.rake @@ -43,7 +43,7 @@ namespace :gitlab do ), Template.new( "https://gitlab.com/gitlab-org/gitlab-ci-yml.git", - /(\.{1,2}|LICENSE|Pages|\.gitignore)\z/ + /(\.{1,2}|LICENSE|Pages|\.gitlab-ci.yml)\z/ )] def vendor_directory diff --git a/vendor/gitignore/Android.gitignore b/vendor/gitignore/Android.gitignore index a8368751267..f6b286cea98 100644 --- a/vendor/gitignore/Android.gitignore +++ b/vendor/gitignore/Android.gitignore @@ -2,7 +2,7 @@ *.apk *.ap_ -# Files for the Dalvik VM +# Files for the ART/Dalvik VM *.dex # Java class files @@ -34,6 +34,7 @@ captures/ # Intellij *.iml +.idea/workspace.xml # Keystore files *.jks diff --git a/vendor/gitignore/C++.gitignore b/vendor/gitignore/C++.gitignore index b8bd0267bdf..4581ef2eeef 100644 --- a/vendor/gitignore/C++.gitignore +++ b/vendor/gitignore/C++.gitignore @@ -15,6 +15,7 @@ # Fortran module files *.mod +*.smod # Compiled Static libraries *.lai diff --git a/vendor/gitignore/CMake.gitignore b/vendor/gitignore/CMake.gitignore index b558e9afa6d..0cc7e4b5275 100644 --- a/vendor/gitignore/CMake.gitignore +++ b/vendor/gitignore/CMake.gitignore @@ -4,3 +4,4 @@ CMakeScripts Makefile cmake_install.cmake install_manifest.txt +CTestTestfile.cmake diff --git a/vendor/gitignore/D.gitignore b/vendor/gitignore/D.gitignore index b4433f8a512..74b926fc901 100644 --- a/vendor/gitignore/D.gitignore +++ b/vendor/gitignore/D.gitignore @@ -18,3 +18,7 @@ .dub docs.json __dummy.html +docs/ + +# Code coverage +*.lst diff --git a/vendor/gitignore/Global/Bazaar.gitignore b/vendor/gitignore/Global/Bazaar.gitignore new file mode 100644 index 00000000000..3cbbcbd11ec --- /dev/null +++ b/vendor/gitignore/Global/Bazaar.gitignore @@ -0,0 +1,2 @@ +.bzr/ +.bzrignore diff --git a/vendor/gitignore/Global/OSX.gitignore b/vendor/gitignore/Global/OSX.gitignore index 660b31353e8..5972fe50f66 100644 --- a/vendor/gitignore/Global/OSX.gitignore +++ b/vendor/gitignore/Global/OSX.gitignore @@ -1,4 +1,4 @@ -.DS_Store +*.DS_Store .AppleDouble .LSOverride @@ -15,6 +15,7 @@ Icon .TemporaryItems .Trashes .VolumeIcon.icns +.com.apple.timemachine.donotpresent # Directories potentially created on remote AFP share .AppleDB diff --git a/vendor/gitignore/Global/README.md b/vendor/gitignore/Global/README.md new file mode 100644 index 00000000000..06b6649bd9a --- /dev/null +++ b/vendor/gitignore/Global/README.md @@ -0,0 +1,10 @@ +## Globally Useful gitignores + +This directory contains globally useful gitignores, +e.g. OS-specific and editor specific. + +For more on global gitignores: + + +And a good blog post about 'em: + diff --git a/vendor/gitignore/Global/SublimeText.gitignore b/vendor/gitignore/Global/SublimeText.gitignore index 1d4e6137591..69c8c2b29ce 100644 --- a/vendor/gitignore/Global/SublimeText.gitignore +++ b/vendor/gitignore/Global/SublimeText.gitignore @@ -12,3 +12,16 @@ # sftp configuration file sftp-config.json + +# Package control specific files +Package Control.last-run +Package Control.ca-list +Package Control.ca-bundle +Package Control.system-ca-bundle +Package Control.cache/ +Package Control.ca-certs/ +bh_unicode_properties.cache + +# Sublime-github package stores a github token in this file +# https://packagecontrol.io/packages/sublime-github +GitHub.sublime-settings diff --git a/vendor/gitignore/Haskell.gitignore b/vendor/gitignore/Haskell.gitignore index 096abdd90b3..a4ee41ab62b 100644 --- a/vendor/gitignore/Haskell.gitignore +++ b/vendor/gitignore/Haskell.gitignore @@ -16,3 +16,4 @@ cabal.sandbox.config *.hp *.eventlog .stack-work/ +cabal.project.local diff --git a/vendor/gitignore/Julia.gitignore b/vendor/gitignore/Julia.gitignore new file mode 100644 index 00000000000..381e0b6d252 --- /dev/null +++ b/vendor/gitignore/Julia.gitignore @@ -0,0 +1,4 @@ +*.jl.cov +*.jl.*.cov +*.jl.mem +deps/deps.jl diff --git a/vendor/gitignore/LICENSE b/vendor/gitignore/LICENSE new file mode 100644 index 00000000000..b8a103ac9b1 --- /dev/null +++ b/vendor/gitignore/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2016 GitHub, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/vendor/gitignore/Laravel.gitignore b/vendor/gitignore/Laravel.gitignore index c491fa2bc6f..1cd717b6921 100644 --- a/vendor/gitignore/Laravel.gitignore +++ b/vendor/gitignore/Laravel.gitignore @@ -7,7 +7,6 @@ app/storage/ # Laravel 5 & Lumen specific bootstrap/cache/ -storage/ .env.*.php .env.php .env diff --git a/vendor/gitignore/Objective-C.gitignore b/vendor/gitignore/Objective-C.gitignore index 3020bc327a7..86f21d8e0ff 100644 --- a/vendor/gitignore/Objective-C.gitignore +++ b/vendor/gitignore/Objective-C.gitignore @@ -24,6 +24,8 @@ xcuserdata/ ## Obj-C/Swift specific *.hmap *.ipa +*.dSYM.zip +*.dSYM # CocoaPods # @@ -49,3 +51,10 @@ Carthage/Build fastlane/report.xml fastlane/screenshots + +#Code Injection +# +# After new code Injection tools there's a generated folder /iOSInjectionProject +# https://github.com/johnno1962/injectionforxcode + +iOSInjectionProject/ diff --git a/vendor/gitignore/Qt.gitignore b/vendor/gitignore/Qt.gitignore index fa24b2efee8..c7659c24f38 100644 --- a/vendor/gitignore/Qt.gitignore +++ b/vendor/gitignore/Qt.gitignore @@ -34,5 +34,5 @@ Makefile* *.qmlproject.user.* # QtCtreator CMake -CMakeLists.txt.user +CMakeLists.txt.user* diff --git a/vendor/gitignore/README.md b/vendor/gitignore/README.md deleted file mode 100644 index 43131e815cc..00000000000 --- a/vendor/gitignore/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# .gitignore templates - -This directory contains language-specific .gitignore templates that are used by GitLab. - -These files were automatically pulled from [this repository](https://github.com/github/gitignore). -Please submit pull requests to that repository. There is no need to edit the files in this directory. - -## Bulk Update - -To update this directory with the latest changes in the repository, run: - -```sh -bundle exec rake gitlab:update_gitignore -``` diff --git a/vendor/gitignore/Rails.gitignore b/vendor/gitignore/Rails.gitignore index 2121e0a8038..d8c256c1925 100644 --- a/vendor/gitignore/Rails.gitignore +++ b/vendor/gitignore/Rails.gitignore @@ -16,6 +16,10 @@ pickle-email-*.html config/initializers/secret_token.rb config/secrets.yml +# dotenv +# TODO Comment out this rule if environment variables can be committed +.env + ## Environment normalization: /.bundle /vendor/bundle diff --git a/vendor/gitignore/Swift.gitignore b/vendor/gitignore/Swift.gitignore index 8a29fa52af4..2c22487b5e3 100644 --- a/vendor/gitignore/Swift.gitignore +++ b/vendor/gitignore/Swift.gitignore @@ -24,6 +24,8 @@ xcuserdata/ ## Obj-C/Swift specific *.hmap *.ipa +*.dSYM.zip +*.dSYM ## Playgrounds timeline.xctimeline diff --git a/vendor/gitignore/UnrealEngine.gitignore b/vendor/gitignore/UnrealEngine.gitignore index 75b1186b0af..be0e4913c3a 100644 --- a/vendor/gitignore/UnrealEngine.gitignore +++ b/vendor/gitignore/UnrealEngine.gitignore @@ -37,6 +37,7 @@ *.suo *.opensdf *.sdf +*.VC.db *.VC.opendb # Precompiled Assets diff --git a/vendor/gitignore/VisualStudio.gitignore b/vendor/gitignore/VisualStudio.gitignore index f1e3d20e056..67acbf42f5e 100644 --- a/vendor/gitignore/VisualStudio.gitignore +++ b/vendor/gitignore/VisualStudio.gitignore @@ -42,6 +42,7 @@ dlldata.c # DNX project.lock.json +project.fragment.lock.json artifacts/ *_i.c diff --git a/vendor/gitlab-ci-yml/Docker.gitlab-ci.yml b/vendor/gitlab-ci-yml/Docker.gitlab-ci.yml new file mode 100644 index 00000000000..396d3f1b042 --- /dev/null +++ b/vendor/gitlab-ci-yml/Docker.gitlab-ci.yml @@ -0,0 +1,7 @@ +# Official docker image. +image: docker:latest + +build: + stage: build + script: + - docker build -t test . diff --git a/vendor/gitlab-ci-yml/Elixir.gitlab-ci.yml b/vendor/gitlab-ci-yml/Elixir.gitlab-ci.yml new file mode 100644 index 00000000000..0b329aaf1c4 --- /dev/null +++ b/vendor/gitlab-ci-yml/Elixir.gitlab-ci.yml @@ -0,0 +1,18 @@ +# This template uses the non default language docker image +# The image already has Hex installed. You might want to consider to use `elixir:latest` +image: trenpixster/elixir:latest + +# Pic zero or more services to be used on all builds. +# Only needed when using a docker container to run your tests in. +# Check out: http://docs.gitlab.com/ce/ci/docker/using_docker_images.html#what-is-service +services: + - mysql:latest + - redis:latest + - postgres:latest + +before_script: + - mix deps.get + +mix: + script: + - mix test diff --git a/vendor/gitlab-ci-yml/Nodejs.gitlab-ci.yml b/vendor/gitlab-ci-yml/Nodejs.gitlab-ci.yml new file mode 100644 index 00000000000..e5bce3503f3 --- /dev/null +++ b/vendor/gitlab-ci-yml/Nodejs.gitlab-ci.yml @@ -0,0 +1,27 @@ +# Official framework image. Look for the different tagged releases at: +# https://hub.docker.com/r/library/node/tags/ +image: node:latest + +# Pick zero or more services to be used on all builds. +# Only needed when using a docker container to run your tests in. +# Check out: http://docs.gitlab.com/ce/ci/docker/using_docker_images.html#what-is-service +services: + - mysql:latest + - redis:latest + - postgres:latest + +# This folder is cached between builds +# http://docs.gitlab.com/ce/ci/yaml/README.html#cache +cache: + paths: + - node_modules/ + +test_async: + script: + - npm install + - node ./specs/start.js ./specs/async.spec.js + +test_db: + script: + - npm install + - node ./specs/start.js ./specs/db-postgres.spec.js diff --git a/vendor/gitlab-ci-yml/Ruby.gitlab-ci.yml b/vendor/gitlab-ci-yml/Ruby.gitlab-ci.yml new file mode 100644 index 00000000000..78f3e39949f --- /dev/null +++ b/vendor/gitlab-ci-yml/Ruby.gitlab-ci.yml @@ -0,0 +1,30 @@ +# Official language image. Look for the different tagged releases at: +# https://hub.docker.com/r/library/ruby/tags/ +image: "ruby:2.3" + +# Pick zero or more services to be used on all builds. +# Only needed when using a docker container to run your tests in. +# Check out: http://docs.gitlab.com/ce/ci/docker/using_docker_images.html#what-is-service +services: + - mysql:latest + - redis:latest + - postgres:latest + +# This is a basic example for a gem or script which doesn't use +# services such as redis or postgres +before_script: + - gem install bundler # Bundler is not installed with the image + - bundle install -j $(nproc) # Install dependencies + +rubocop: + script: + - rubocop + +rspec: + script: + - rspec spec + +rails: + script: + - rake db:migrate + - rspec spec -- cgit v1.2.1 From 483dc62eaac0e11717b5b103317c4441ec0ff23d Mon Sep 17 00:00:00 2001 From: "Z.J. van de Weg" Date: Thu, 16 Jun 2016 15:33:11 +0200 Subject: Incorporate review --- app/assets/javascripts/api.js.coffee | 6 +++--- app/assets/javascripts/blob/blob_ci_yaml.js.coffee | 2 +- app/helpers/blob_helper.rb | 4 ++-- lib/api/templates.rb | 6 +++++- lib/gitlab/template/base_template.rb | 4 +++- lib/gitlab/template/gitlab_ci_yml.rb | 2 +- lib/tasks/gitlab/update_templates.rake | 18 ++++++++++-------- spec/requests/api/templates_spec.rb | 9 +++++++++ 8 files changed, 34 insertions(+), 17 deletions(-) diff --git a/app/assets/javascripts/api.js.coffee b/app/assets/javascripts/api.js.coffee index d543e3b7a96..cf46f15a156 100644 --- a/app/assets/javascripts/api.js.coffee +++ b/app/assets/javascripts/api.js.coffee @@ -7,7 +7,7 @@ labelsPath: "/api/:version/projects/:id/labels" licensePath: "/api/:version/licenses/:key" gitignorePath: "/api/:version/gitignores/:key" - gitlabCIYmlPath: "/api/:version/gitlab_ci_ymls/:key" + gitlabCiYmlPath: "/api/:version/gitlab_ci_ymls/:key" group: (group_id, callback) -> url = Api.buildUrl(Api.groupPath) @@ -111,8 +111,8 @@ $.get url, (gitignore) -> callback(gitignore) - gitlabCIYml: (key, callback) -> - url = Api.buildUrl(Api.gitlabCIYmlPath).replace(':key', key) + gitlabCiYml: (key, callback) -> + url = Api.buildUrl(Api.gitlabCiYmlPath).replace(':key', key) $.get url, (file) -> callback(file) diff --git a/app/assets/javascripts/blob/blob_ci_yaml.js.coffee b/app/assets/javascripts/blob/blob_ci_yaml.js.coffee index dc14700d305..d9a03d05529 100644 --- a/app/assets/javascripts/blob/blob_ci_yaml.js.coffee +++ b/app/assets/javascripts/blob/blob_ci_yaml.js.coffee @@ -2,7 +2,7 @@ class @BlobCiYamlSelector extends TemplateSelector requestFile: (query) -> - Api.gitlabCIYml query.name, @requestFileSuccess.bind(@) + Api.gitlabCiYml query.name, @requestFileSuccess.bind(@) class @BlobCiYamlSelectors constructor: (opts) -> diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb index b30a01614be..16d9d7d2d5a 100644 --- a/app/helpers/blob_helper.rb +++ b/app/helpers/blob_helper.rb @@ -194,8 +194,8 @@ module BlobHelper def gitlab_ci_ymls @gitlab_ci_ymls ||= - Gitlab::Template::GitlabCIYml.categories.keys.map do |k| - [k, Gitlab::Template::GitlabCIYml.by_category(k).map { |t| { name: t.name } }] + Gitlab::Template::GitlabCiYml.categories.keys.map do |k| + [k, Gitlab::Template::GitlabCiYml.by_category(k).map { |t| { name: t.name } }] end.to_h end end diff --git a/lib/api/templates.rb b/lib/api/templates.rb index 9f5f10a5088..33cbb0c9e1b 100644 --- a/lib/api/templates.rb +++ b/lib/api/templates.rb @@ -2,7 +2,7 @@ module API class Templates < Grape::API TEMPLATE_TYPES = { gitignores: Gitlab::Template::Gitignore, - gitlab_ci_ymls: Gitlab::Template::GitlabCIYml + gitlab_ci_ymls: Gitlab::Template::GitlabCiYml }.freeze TEMPLATE_TYPES.each do |template, klass| @@ -29,6 +29,10 @@ module API new_template = klass.find(params[:name]) not_found!("#{template.to_s.singularize}") unless new_template + if new_template.class == Gitlab::Template::GitlabCiYml + new_template.content = "# This file is a template, and might need editing before it works on your project.\n" + new_template.content + end + present new_template, with: Entities::Template end end diff --git a/lib/gitlab/template/base_template.rb b/lib/gitlab/template/base_template.rb index 652a496b57b..4086d8701bf 100644 --- a/lib/gitlab/template/base_template.rb +++ b/lib/gitlab/template/base_template.rb @@ -1,6 +1,8 @@ module Gitlab module Template class BaseTemplate + attr_writer :content + def initialize(path) @path = path end @@ -10,7 +12,7 @@ module Gitlab end def content - File.read(@path) + @content ||= File.read(@path) end def categories diff --git a/lib/gitlab/template/gitlab_ci_yml.rb b/lib/gitlab/template/gitlab_ci_yml.rb index da7273b8d70..f1e96d22d64 100644 --- a/lib/gitlab/template/gitlab_ci_yml.rb +++ b/lib/gitlab/template/gitlab_ci_yml.rb @@ -1,6 +1,6 @@ module Gitlab module Template - class GitlabCIYml < BaseTemplate + class GitlabCiYml < BaseTemplate class << self def extension '.gitlab-ci.yml' diff --git a/lib/tasks/gitlab/update_templates.rake b/lib/tasks/gitlab/update_templates.rake index 14277fe4c4b..2d3c7993445 100644 --- a/lib/tasks/gitlab/update_templates.rake +++ b/lib/tasks/gitlab/update_templates.rake @@ -37,14 +37,16 @@ namespace :gitlab do private Template = Struct.new(:repo_url, :cleanup_regex) - TEMPLATE_DATA = [Template.new( - "https://github.com/github/gitignore.git", - /(\.{1,2}|LICENSE|Global|\.gitignore)\z/ - ), - Template.new( - "https://gitlab.com/gitlab-org/gitlab-ci-yml.git", - /(\.{1,2}|LICENSE|Pages|\.gitlab-ci.yml)\z/ - )] + TEMPLATE_DATA = [ + Template.new( + "https://github.com/github/gitignore.git", + /(\.{1,2}|LICENSE|Global|\.gitignore)\z/ + ), + Template.new( + "https://gitlab.com/gitlab-org/gitlab-ci-yml.git", + /(\.{1,2}|LICENSE|Pages|\.gitlab-ci.yml)\z/ + ) + ] def vendor_directory Rails.root.join('vendor') diff --git a/spec/requests/api/templates_spec.rb b/spec/requests/api/templates_spec.rb index 0e9a28b1ff6..a6d5ade3013 100644 --- a/spec/requests/api/templates_spec.rb +++ b/spec/requests/api/templates_spec.rb @@ -40,4 +40,13 @@ describe API::Templates, api: true do end end end + + describe 'GET /gitlab_ci_ymls/Ruby' do + it 'adds a disclaimer on the top' do + get api('/gitlab_ci_ymls/Ruby') + + expect(response.status).to eq(200) + expect(json_response['content']).to start_with("# This file is a template,") + end + end end -- cgit v1.2.1 From a18df1d15af68be4d129412ad2a6145277ca43d3 Mon Sep 17 00:00:00 2001 From: Alfredo Sumaran Date: Thu, 16 Jun 2016 18:53:41 -0500 Subject: Add feature test for gitab CI dropdown --- .../projects/files/gitlab_ci_yml_dropdown_spec.rb | 30 ++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb diff --git a/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb b/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb new file mode 100644 index 00000000000..d516e8ce55a --- /dev/null +++ b/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb @@ -0,0 +1,30 @@ +require 'spec_helper' + +feature 'User wants to add a .gitlab-ci.yml file', feature: true do + include WaitForAjax + + before do + user = create(:user) + project = create(:project) + project.team << [user, :master] + login_as user + visit namespace_project_new_blob_path(project.namespace, project, 'master', file_name: '.gitlab-ci.yml') + end + + scenario 'user can see .gitlab-ci.yml dropdown' do + expect(page).to have_css('.gitlab-ci-yml-selector') + end + + scenario 'user can pick a template from the dropdown', js: true do + find('.js-gitlab-ci-yml-selector').click + wait_for_ajax + within '.gitlab-ci-yml-selector' do + find('.dropdown-input-field').set('jekyll') + find('.dropdown-content li', text: 'jekyll').click + end + wait_for_ajax + + expect(page).to have_content('This file is a template, and might need editing before it works on your project') + expect(page).to have_content('jekyll build -d test') + end +end -- cgit v1.2.1 From bbfd62bc34061089f753e4170912be64bae16f84 Mon Sep 17 00:00:00 2001 From: "Z.J. van de Weg" Date: Fri, 17 Jun 2016 08:37:19 +0200 Subject: fixup! override content method --- lib/api/templates.rb | 6 +----- lib/gitlab/template/base_template.rb | 28 +++++++++++++--------------- lib/gitlab/template/gitlab_ci_yml.rb | 5 +++++ lib/tasks/gitlab/update_templates.rake | 2 +- 4 files changed, 20 insertions(+), 21 deletions(-) diff --git a/lib/api/templates.rb b/lib/api/templates.rb index 33cbb0c9e1b..18408797756 100644 --- a/lib/api/templates.rb +++ b/lib/api/templates.rb @@ -27,11 +27,7 @@ module API required_attributes! [:name] new_template = klass.find(params[:name]) - not_found!("#{template.to_s.singularize}") unless new_template - - if new_template.class == Gitlab::Template::GitlabCiYml - new_template.content = "# This file is a template, and might need editing before it works on your project.\n" + new_template.content - end + not_found!(template.to_s.singularize) unless new_template present new_template, with: Entities::Template end diff --git a/lib/gitlab/template/base_template.rb b/lib/gitlab/template/base_template.rb index 4086d8701bf..760ff3e614a 100644 --- a/lib/gitlab/template/base_template.rb +++ b/lib/gitlab/template/base_template.rb @@ -1,8 +1,6 @@ module Gitlab module Template class BaseTemplate - attr_writer :content - def initialize(path) @path = path end @@ -12,19 +10,7 @@ module Gitlab end def content - @content ||= File.read(@path) - end - - def categories - raise NotImplementedError - end - - def extension - raise NotImplementedError - end - - def base_dir - raise NotImplementedError + File.read(@path) end class << self @@ -39,6 +25,18 @@ module Gitlab directory ? new(File.join(category_directory(directory), file_name)) : nil end + def categories + raise NotImplementedError + end + + def extension + raise NotImplementedError + end + + def base_dir + raise NotImplementedError + end + def by_category(category) templates_for_directory(category_directory(category)) end diff --git a/lib/gitlab/template/gitlab_ci_yml.rb b/lib/gitlab/template/gitlab_ci_yml.rb index f1e96d22d64..7f480fe33c0 100644 --- a/lib/gitlab/template/gitlab_ci_yml.rb +++ b/lib/gitlab/template/gitlab_ci_yml.rb @@ -1,6 +1,11 @@ module Gitlab module Template class GitlabCiYml < BaseTemplate + def content + explanation = "# This file is a template, and might need editing before it works on your project." + [explanation, super].join("\n") + end + class << self def extension '.gitlab-ci.yml' diff --git a/lib/tasks/gitlab/update_templates.rake b/lib/tasks/gitlab/update_templates.rake index 2d3c7993445..4f76dad7286 100644 --- a/lib/tasks/gitlab/update_templates.rake +++ b/lib/tasks/gitlab/update_templates.rake @@ -27,7 +27,7 @@ namespace :gitlab do # - The LICENSE, because we have to # - The sub dirs so we can organise the file by category # - The templates themself - # - Dir.entires returns also the entries '.' and '..' + # - Dir.entries returns also the entries '.' and '..' def remove_unneeded_files(directory, regex) Dir.foreach(directory) do |file| FileUtils.rm_rf(File.join(directory, file)) unless file =~ regex -- cgit v1.2.1 From 5c9f0896ef3118b4e381e1834073827f42a10feb Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Mon, 20 Jun 2016 12:50:40 -0700 Subject: Rename Code -> Repo in feature specs --- features/project/active_tab.feature | 30 +++++++++++++++--------------- features/project/shortcuts.feature | 6 +++--- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/features/project/active_tab.feature b/features/project/active_tab.feature index c4f987a7923..db4507b9889 100644 --- a/features/project/active_tab.feature +++ b/features/project/active_tab.feature @@ -10,9 +10,9 @@ Feature: Project Active Tab Then the active main tab should be Home And no other main tabs should be active - Scenario: On Project Code + Scenario: On Project Repo Given I visit my project's files page - Then the active main tab should be Code + Then the active main tab should be Repo And no other main tabs should be active Scenario: On Project Issues @@ -59,46 +59,46 @@ Feature: Project Active Tab And no other sub navs should be active And the active main tab should be Settings - # Sub Tabs: Code + # Sub Tabs: Repo - Scenario: On Project Code/Files + Scenario: On Project Repo/Files Given I visit my project's files page Then the active sub tab should be Files And no other sub tabs should be active - And the active main tab should be Code + And the active main tab should be Repo - Scenario: On Project Code/Commits + Scenario: On Project Repo/Commits Given I visit my project's commits page Then the active sub tab should be Commits And no other sub tabs should be active - And the active main tab should be Code + And the active main tab should be Repo - Scenario: On Project Code/Network + Scenario: On Project Repo/Network Given I visit my project's network page Then the active sub tab should be Network And no other sub tabs should be active - And the active main tab should be Code + And the active main tab should be Repo - Scenario: On Project Code/Compare + Scenario: On Project Repo/Compare Given I visit my project's commits page And I click the "Compare" tab Then the active sub tab should be Compare And no other sub tabs should be active - And the active main tab should be Code + And the active main tab should be Repo - Scenario: On Project Code/Branches + Scenario: On Project Repo/Branches Given I visit my project's commits page And I click the "Branches" tab Then the active sub tab should be Branches And no other sub tabs should be active - And the active main tab should be Code + And the active main tab should be Repo - Scenario: On Project Code/Tags + Scenario: On Project Repo/Tags Given I visit my project's commits page And I click the "Tags" tab Then the active sub tab should be Tags And no other sub tabs should be active - And the active main tab should be Code + And the active main tab should be Repo Scenario: On Project Issues/Browse Given I visit my project's issues page diff --git a/features/project/shortcuts.feature b/features/project/shortcuts.feature index c73d0b32337..aa5edaaa9d7 100644 --- a/features/project/shortcuts.feature +++ b/features/project/shortcuts.feature @@ -8,21 +8,21 @@ Feature: Project Shortcuts @javascript Scenario: Navigate to files tab Given I press "g" and "f" - Then the active main tab should be Code + Then the active main tab should be Repo Then the active sub tab should be Files @javascript Scenario: Navigate to commits tab Given I visit my project's files page Given I press "g" and "c" - Then the active main tab should be Code + Then the active main tab should be Repo Then the active sub tab should be Commits @javascript Scenario: Navigate to network tab Given I press "g" and "n" Then the active sub tab should be Network - And the active main tab should be Code + And the active main tab should be Repo @javascript Scenario: Navigate to graphs tab -- cgit v1.2.1 From 35383f33acaae6b286c203005b0410388a3bcca0 Mon Sep 17 00:00:00 2001 From: Alfredo Sumaran Date: Mon, 20 Jun 2016 15:06:36 -0500 Subject: Add button to add .gitlab-ci.yml file --- app/views/projects/show.html.haml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml index e9ca46a74bf..5f041aedfc0 100644 --- a/app/views/projects/show.html.haml +++ b/app/views/projects/show.html.haml @@ -57,6 +57,10 @@ %li.missing = link_to add_special_file_path(@project, file_name: 'CONTRIBUTING.md', commit_message: 'Add contribution guide') do Add Contribution guide + - unless @repository.gitlab_ci_yml + %li.missing + = link_to add_special_file_path(@project, file_name: '.gitlab-ci.yml') do + Set up CI - if @repository.commit .content-block.second-block.white -- cgit v1.2.1 From 3cf9b772d9eac98797ed12bfa00509ad8f4fa1d9 Mon Sep 17 00:00:00 2001 From: Fatih Acet Date: Tue, 21 Jun 2016 00:21:56 +0300 Subject: jQuery selector refactor in application.js. --- app/assets/javascripts/application.js.coffee | 33 ++++++++++++++++------------ 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/app/assets/javascripts/application.js.coffee b/app/assets/javascripts/application.js.coffee index 4529c514555..17b1cfda579 100644 --- a/app/assets/javascripts/application.js.coffee +++ b/app/assets/javascripts/application.js.coffee @@ -121,6 +121,11 @@ window.onload = -> setTimeout shiftWindow, 100 $ -> + + $document = $(document) + $window = $(window) + $body = $('body') + gl.utils.preventDisabledButtons() bootstrapBreakpoint = bp.getBreakpointSize() @@ -152,7 +157,7 @@ $ -> ), 1 # Initialize tooltips - $('body').tooltip( + $body.tooltip( selector: '.has-tooltip, [data-toggle="tooltip"]' placement: (_, el) -> $el = $(el) @@ -171,7 +176,7 @@ $ -> flash.show() # Disable form buttons while a form is submitting - $('body').on 'ajax:complete, ajax:beforeSend, submit', 'form', (e) -> + $body.on 'ajax:complete, ajax:beforeSend, submit', 'form', (e) -> buttons = $('[type="submit"]', @) switch e.type @@ -184,7 +189,7 @@ $ -> $('.account-box').hover -> $(@).toggleClass('hover') # Commit show suppressed diff - $(document).on 'click', '.diff-content .js-show-suppressed-diff', -> + $document.on 'click', '.diff-content .js-show-suppressed-diff', -> $container = $(@).parent() $container.next('table').show() $container.remove() @@ -197,13 +202,13 @@ $ -> $('.navbar-toggle i').toggleClass("fa-angle-right fa-angle-left") # Show/hide comments on diff - $("body").on "click", ".js-toggle-diff-comments", (e) -> + $body.on "click", ".js-toggle-diff-comments", (e) -> $(@).toggleClass('active') $(@).closest(".diff-file").find(".notes_holder").toggle() e.preventDefault() - $(document).off "click", '.js-confirm-danger' - $(document).on "click", '.js-confirm-danger', (e) -> + $document.off "click", '.js-confirm-danger' + $document.on "click", '.js-confirm-danger', (e) -> e.preventDefault() btn = $(e.target) text = btn.data("confirm-danger-message") @@ -211,7 +216,7 @@ $ -> new ConfirmDangerModal(form, text) - $(document).on 'click', 'button', -> + $document.on 'click', 'button', -> $(this).blur() $('input[type="search"]').each -> @@ -219,7 +224,7 @@ $ -> $this.attr 'value', $this.val() return - $(document) + $document .off 'keyup', 'input[type="search"]' .on 'keyup', 'input[type="search"]' , (e) -> $this = $(this) @@ -227,7 +232,7 @@ $ -> $sidebarGutterToggle = $('.js-sidebar-toggle') - $(document) + $document .off 'breakpoint:change' .on 'breakpoint:change', (e, breakpoint) -> if breakpoint is 'sm' or breakpoint is 'xs' @@ -239,14 +244,14 @@ $ -> oldBootstrapBreakpoint = bootstrapBreakpoint bootstrapBreakpoint = bp.getBreakpointSize() if bootstrapBreakpoint != oldBootstrapBreakpoint - $(document).trigger('breakpoint:change', [bootstrapBreakpoint]) + $document.trigger('breakpoint:change', [bootstrapBreakpoint]) checkInitialSidebarSize = -> bootstrapBreakpoint = bp.getBreakpointSize() if bootstrapBreakpoint is "xs" or "sm" - $(document).trigger('breakpoint:change', [bootstrapBreakpoint]) + $document.trigger('breakpoint:change', [bootstrapBreakpoint]) - $(window) + $window .off "resize.app" .on "resize.app", (e) -> fitSidebarForSize() @@ -256,14 +261,14 @@ $ -> new Aside() # Sidenav pinning - if $(window).width() < 1440 and $.cookie('pin_nav') is 'true' + if $window.width() < 1440 and $.cookie('pin_nav') is 'true' $.cookie('pin_nav', 'false', { path: '/' }) $('.page-with-sidebar') .toggleClass('page-sidebar-collapsed page-sidebar-expanded') .removeClass('page-sidebar-pinned') $('.navbar-fixed-top').removeClass('header-pinned-nav') - $(document) + $document .off 'click', '.js-nav-pin' .on 'click', '.js-nav-pin', (e) -> e.preventDefault() -- cgit v1.2.1 From a0fefc2ad22ed2392bcba5acb02a0a95b73cbba8 Mon Sep 17 00:00:00 2001 From: Mark Pundsack Date: Tue, 14 Jun 2016 17:58:20 -0700 Subject: Add definitions and tweak some docs. Partially fixes #17733 --- doc/ci/README.md | 1 + doc/ci/definitions/README.md | 52 ++++++++++++++++++++++++++++++++++++++++++++ doc/ci/quick_start/README.md | 24 ++++++++++---------- doc/ci/yaml/README.md | 4 ++-- 4 files changed, 67 insertions(+), 14 deletions(-) create mode 100644 doc/ci/definitions/README.md diff --git a/doc/ci/README.md b/doc/ci/README.md index 5a1cb5319c6..c7a29e269b5 100644 --- a/doc/ci/README.md +++ b/doc/ci/README.md @@ -3,6 +3,7 @@ ### CI User documentation - [Get started with GitLab CI](quick_start/README.md) +- [CI/CD Definitions](definitions/README.md) - [CI examples for various languages](examples/README.md) - [Learn how to enable or disable GitLab CI](enable_or_disable_ci.md) - [Environments and deployments](environments.md) diff --git a/doc/ci/definitions/README.md b/doc/ci/definitions/README.md new file mode 100644 index 00000000000..4ec5eee5757 --- /dev/null +++ b/doc/ci/definitions/README.md @@ -0,0 +1,52 @@ +## CI/CD Definitions + +### Pipelines + +A pipeline is a group of [builds] that get executed in [stages] (batches). All of +the builds in a stage are executed in parallel (if there are enough concurrent +[runners]), and if they all succeed, the pipeline moves on to the next stage. If +one of the builds fails, the next stage is not (usually) executed. + +### Builds + +Builds are runs of [jobs]. Not to be confused with a `build` stage. + +### Jobs + +Jobs are the basic work unit of CI/CD. Jobs are used to create [builds], which are +then picked up by [Runners] and executed within the environment of the Runner. +Each job is run independently from each other. + +### Runners + +A runner is an isolated (virtual) machine that picks up builds through the +coordinator API of GitLab CI. A runner can be specific to a certain project or +serve any project in GitLab CI. A runner that serves all projects is called a +shared runner. + +### Stages + +Stages allow [jobs] to be grouped into parallel and sequential [builds]. Builds +of the same stage are executed in parallel and builds of the next stage are run +after the jobs from the previous stage complete successfully. Stages allow for +flexible multi-stage [pipelines]. By default [pipelines] have `build`, `test` +and `deploy` stages, but these can be defined in `.gitlab-ci.yml`. If a job +doesn't specify a stage, the job is assigned to the test stage. + +### Environments + +Environments are places where code gets deployed, such as staging or production. +CI/CD [Pipelines] usually have one or more deploy stages with [jobs] that do +[deployments] to an environment. + +### Deployments + +Deployments are created when [jobs] deploy versions of code to [environments]. + +[pipelines]: #pipelines +[builds]: #builds +[runners]: #runners +[jobs]: #jobs +[stages]: #stages +[environments]: #environments +[deployments]: #deployments diff --git a/doc/ci/quick_start/README.md b/doc/ci/quick_start/README.md index 386b8e29fcf..07fbefa0416 100644 --- a/doc/ci/quick_start/README.md +++ b/doc/ci/quick_start/README.md @@ -4,41 +4,40 @@ is fully integrated into GitLab itself and is [enabled] by default on all projects. -The TL;DR version of how GitLab CI works is the following. - ---- - GitLab offers a [continuous integration][ci] service. If you [add a `.gitlab-ci.yml` file][yaml] to the root directory of your repository, and configure your GitLab project to use a [Runner], then each merge request or -push triggers a build. +push triggers your CI [pipeline]. The `.gitlab-ci.yml` file tells the GitLab runner what to do. By default it -runs three [stages]: `build`, `test`, and `deploy`. +runs a pipeline with three [stages]: `build`, `test`, and `deploy`. If everything runs OK (no non-zero return values), you'll get a nice green checkmark associated with the pushed commit or merge request. This makes it -easy to see whether a merge request will cause any of the tests to fail before +easy to see whether a merge request caused any of the tests to fail before you even look at the code. -Most projects only use GitLab's CI service to run the test suite so that +Most projects use GitLab's CI service to run the test suite so that developers get immediate feedback if they broke something. +There's a growing trend to use continuous delivery and continuous deployment to +automatically deploy tested code to staging and production environments. + So in brief, the steps needed to have a working CI can be summed up to: 1. Add `.gitlab-ci.yml` to the root directory of your repository 1. Configure a Runner -From there on, on every push to your Git repository, the build will be -automagically started by the Runner and will appear under the project's -`/builds` page. +From there on, on every push to your Git repository, the Runner will +automagically start the pipeline and the pipeline will appear under the +project's `/pipelines` page. --- This guide assumes that you: - have a working GitLab instance of version 8.0 or higher or are using - [GitLab.com](https://gitlab.com/users/sign_in) + [GitLab.com](https://gitlab.com) - have a project in GitLab that you would like to use CI for Let's break it down to pieces and work on solving the GitLab CI puzzle. @@ -238,3 +237,4 @@ CI with various languages. [runner]: ../runners/README.md [enabled]: ../enable_or_disable_ci.md [stages]: ../yaml/README.md#stages +[pipeline]: ../definitions/README.md#pipelines diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md index d0fbcbe9988..b134b5cd5d3 100644 --- a/doc/ci/yaml/README.md +++ b/doc/ci/yaml/README.md @@ -54,7 +54,7 @@ of your repository and contains definitions of how your project should be built. The YAML file defines a set of jobs with constraints stating when they should be run. The jobs are defined as top-level elements with a name and always have -to contain the `script` clause: +to contain at least the `script` clause: ```yaml job1: @@ -165,7 +165,7 @@ stages: There are also two edge cases worth mentioning: -1. If no `stages` is defined in `.gitlab-ci.yml`, then by default the `build`, +1. If no `stages` are defined in `.gitlab-ci.yml`, then by default the `build`, `test` and `deploy` are allowed to be used as job's stage by default. 2. If a job doesn't specify a `stage`, the job is assigned the `test` stage. -- cgit v1.2.1 From a1c2b168377869da8f3393c9a8f18a85633c3d57 Mon Sep 17 00:00:00 2001 From: Mark Pundsack Date: Tue, 14 Jun 2016 18:12:39 -0700 Subject: Add pipeline image --- doc/ci/quick_start/README.md | 42 +++++++++++++++------------- doc/ci/quick_start/img/pipelines_status.png | Bin 0 -> 89387 bytes 2 files changed, 23 insertions(+), 19 deletions(-) create mode 100644 doc/ci/quick_start/img/pipelines_status.png diff --git a/doc/ci/quick_start/README.md b/doc/ci/quick_start/README.md index 07fbefa0416..c32b69aad8b 100644 --- a/doc/ci/quick_start/README.md +++ b/doc/ci/quick_start/README.md @@ -9,8 +9,9 @@ GitLab offers a [continuous integration][ci] service. If you and configure your GitLab project to use a [Runner], then each merge request or push triggers your CI [pipeline]. -The `.gitlab-ci.yml` file tells the GitLab runner what to do. By default it -runs a pipeline with three [stages]: `build`, `test`, and `deploy`. +The `.gitlab-ci.yml` file tells the GitLab runner what to do. By default it runs +a pipeline with three [stages]: `build`, `test`, and `deploy`. You don't need to +use all three stages; stages with no jobs are simply ignored. If everything runs OK (no non-zero return values), you'll get a nice green checkmark associated with the pushed commit or merge request. This makes it @@ -56,15 +57,14 @@ On any push to your repository, GitLab will look for the `.gitlab-ci.yml` file and start builds on _Runners_ according to the contents of the file, for that commit. -Because `.gitlab-ci.yml` is in the repository, it is version controlled, -old versions still build successfully, forks can easily make use of CI, -branches can have separate builds and you have a single source of truth for CI. -You can read more about the reasons why we are using `.gitlab-ci.yml` -[in our blog about it][blog-ci]. +Because `.gitlab-ci.yml` is in the repository and is version controlled, old +versions still build successfully, forks can easily make use of CI, branches can +have different pipelines and jobs, and you have a single source of truth for CI. +You can read more about the reasons why we are using `.gitlab-ci.yml` [in our +blog about it][blog-ci]. **Note:** `.gitlab-ci.yml` is a [YAML](https://en.wikipedia.org/wiki/YAML) file -so you have to pay extra attention to the indentation. Always use spaces, not -tabs. +so you have to pay extra attention to indentation. Always use spaces, not tabs. ### Creating a simple `.gitlab-ci.yml` file @@ -107,7 +107,7 @@ If you want to check whether your `.gitlab-ci.yml` file is valid, there is a Lint tool under the page `/ci/lint` of your GitLab instance. You can also find the link under **Settings > CI settings** in your project. -For more information and a complete `.gitlab-ci.yml` syntax, please check +For more information and a complete `.gitlab-ci.yml` syntax, please read [the documentation on .gitlab-ci.yml](../yaml/README.md). ### Push `.gitlab-ci.yml` to GitLab @@ -121,7 +121,8 @@ git commit -m "Add .gitlab-ci.yml" git push origin master ``` -Now if you go to the **Builds** page you will see that the builds are pending. +Now if you go to the **Pipelines** page you will see that the pipeline is +pending. You can also go to the **Commits** page and notice the little clock icon next to the commit SHA. @@ -137,15 +138,14 @@ Notice that there are two jobs pending which are named after what we wrote in `.gitlab-ci.yml`. The red triangle indicates that there is no Runner configured yet for these builds. -The next step is to configure a Runner so that it picks the pending jobs. +The next step is to configure a Runner so that it picks the pending builds. ## Configuring a Runner -In GitLab, Runners run the builds that you define in `.gitlab-ci.yml`. -A Runner can be a virtual machine, a VPS, a bare-metal machine, a docker -container or even a cluster of containers. GitLab and the Runners communicate -through an API, so the only needed requirement is that the machine on which the -Runner is configured to have Internet access. +In GitLab, Runners run the builds that you define in `.gitlab-ci.yml`. A Runner +can be a virtual machine, a VPS, a bare-metal machine, a docker container or +even a cluster of containers. GitLab and the Runners communicate through an API, +so the only requirement is that the Runner's machine has Internet access. A Runner can be specific to a certain project or serve multiple projects in GitLab. If it serves all projects it's called a _Shared Runner_. @@ -187,12 +187,16 @@ To enable **Shared Runners** you have to go to your project's [Read more on Shared Runners](../runners/README.md). -## Seeing the status of your build +## Seeing the status of your pipeline and builds After configuring the Runner successfully, you should see the status of your last commit change from _pending_ to either _running_, _success_ or _failed_. -You can view all builds, by going to the **Builds** page in your project. +You can view all pipelines by going to the **Pipelines** page in your project. + +![Commit status](img/pipelines_status.png) + +Or you can view all builds, by going to the **Pipelines > Builds** page. ![Commit status](img/builds_status.png) diff --git a/doc/ci/quick_start/img/pipelines_status.png b/doc/ci/quick_start/img/pipelines_status.png new file mode 100644 index 00000000000..6bc97bb739c Binary files /dev/null and b/doc/ci/quick_start/img/pipelines_status.png differ -- cgit v1.2.1 From edfe2e2db98e1a5541d5d683ac3a686d24a9c429 Mon Sep 17 00:00:00 2001 From: Mark Pundsack Date: Tue, 14 Jun 2016 20:34:35 -0700 Subject: Add CD --- doc/README.md | 24 ++++++++++++------------ doc/ci/README.md | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/doc/README.md b/doc/README.md index 5d89d0c9821..3e7165d5ae4 100644 --- a/doc/README.md +++ b/doc/README.md @@ -3,17 +3,17 @@ ## User documentation - [API](api/README.md) Automate GitLab via a simple and powerful API. -- [CI](ci/README.md) GitLab Continuous Integration (CI) getting started, `.gitlab-ci.yml` options, and examples. +- [CI/CD](ci/README.md) GitLab Continuous Integration (CI) and Continuous Delivery (CD) getting started, `.gitlab-ci.yml` options, and examples. - [GitLab as OAuth2 authentication service provider](integration/oauth_provider.md). It allows you to login to other applications from GitLab. +- [Container Registry](container_registry/README.md) Learn how to use GitLab Container Registry. - [GitLab Basics](gitlab-basics/README.md) Find step by step how to start working on your commandline and on GitLab. -- [Importing to GitLab](workflow/importing/README.md). +- [Importing to GitLab](workflow/importing/README.md) - [Markdown](markdown/markdown.md) GitLab's advanced formatting system. -- [Migrating from SVN](workflow/importing/migrating_from_svn.md) Convert a SVN repository to Git and GitLab +- [Migrating from SVN](workflow/importing/migrating_from_svn.md) Convert a SVN repository to Git and GitLab. - [Permissions](permissions/permissions.md) Learn what each role in a project (external/guest/reporter/developer/master/owner) can do. - [Profile Settings](profile/README.md) - [Project Services](project_services/project_services.md) Integrate a project with external services, such as CI and chat. - [Public access](public_access/public_access.md) Learn how you can allow public and internal access to projects. -- [Container Registry](container_registry/README.md) Learn how to use GitLab Container Registry. - [SSH](ssh/README.md) Setup your ssh keys and deploy keys for secure access to your projects. - [Webhooks](web_hooks/web_hooks.md) Let GitLab notify you when new code has been pushed to your project. - [Workflow](workflow/README.md) Using GitLab functionality and importing projects from GitHub and SVN. @@ -24,15 +24,15 @@ external authentication with LDAP, SAML, CAS and additional Omniauth providers. - [Custom git hooks](hooks/custom_hooks.md) Custom git hooks (on the filesystem) for when webhooks aren't enough. - [Install](install/README.md) Requirements, directory structures and installation from source. -- [Restart GitLab](administration/restart_gitlab.md) Learn how to restart GitLab and its components +- [Restart GitLab](administration/restart_gitlab.md) Learn how to restart GitLab and its components. - [Integration](integration/README.md) How to integrate with systems such as JIRA, Redmine, Twitter. - [Issue closing](customization/issue_closing.md) Customize how to close an issue from commit messages. - [Libravatar](customization/libravatar.md) Use Libravatar for user avatars. - [Log system](administration/logs.md) Log system. - [Environment Variables](administration/environment_variables.md) to configure GitLab. -- [Operations](operations/README.md) Keeping GitLab up and running +- [Operations](operations/README.md) Keeping GitLab up and running. - [Raketasks](raketasks/README.md) Backups, maintenance, automatic webhook setup and the importing of projects. -- [Repository checks](administration/repository_checks.md) Periodic Git repository checks +- [Repository checks](administration/repository_checks.md) Periodic Git repository checks. - [Security](security/README.md) Learn what you can do to further secure your GitLab instance. - [System hooks](system_hooks/system_hooks.md) Notifications when users, projects and keys are changed. - [Update](update/README.md) Update guides to upgrade your installation. @@ -41,11 +41,11 @@ - [Migrate GitLab CI to CE/EE](migrate_ci_to_ce/README.md) Follow this guide to migrate your existing GitLab CI data to GitLab CE/EE. - [Git LFS configuration](workflow/lfs/lfs_administration.md) - [Housekeeping](administration/housekeeping.md) Keep your Git repository tidy and fast. -- [GitLab Performance Monitoring](monitoring/performance/introduction.md) Configure GitLab and InfluxDB for measuring performance metrics -- [Monitoring uptime](monitoring/health_check.md) Check the server status using the health check endpoint -- [Sidekiq Troubleshooting](administration/troubleshooting/sidekiq.md) Debug when Sidekiq appears hung and is not processing jobs -- [High Availability](administration/high_availability/README.md) Configure multiple servers for scaling or high availability -- [Container Registry](administration/container_registry.md) Configure Docker Registry with GitLab +- [GitLab Performance Monitoring](monitoring/performance/introduction.md) Configure GitLab and InfluxDB for measuring performance metrics. +- [Monitoring uptime](monitoring/health_check.md) Check the server status using the health check endpoint. +- [Sidekiq Troubleshooting](administration/troubleshooting/sidekiq.md) Debug when Sidekiq appears hung and is not processing jobs. +- [High Availability](administration/high_availability/README.md) Configure multiple servers for scaling or high availability. +- [Container Registry](administration/container_registry.md) Configure Docker Registry with GitLab. ## Contributor documentation diff --git a/doc/ci/README.md b/doc/ci/README.md index c7a29e269b5..7abce85c8d8 100644 --- a/doc/ci/README.md +++ b/doc/ci/README.md @@ -1,6 +1,6 @@ ## GitLab CI Documentation -### CI User documentation +### CI/CD User documentation - [Get started with GitLab CI](quick_start/README.md) - [CI/CD Definitions](definitions/README.md) -- cgit v1.2.1 From 41af86bc86a3bab9c83729ff76776fc137b350ef Mon Sep 17 00:00:00 2001 From: Mark Pundsack Date: Mon, 20 Jun 2016 15:07:38 -0700 Subject: Move Pipelines and Builds definitions to their own page --- doc/ci/README.md | 4 ++-- doc/ci/definitions/README.md | 52 -------------------------------------------- doc/ci/environments.md | 2 +- 3 files changed, 3 insertions(+), 55 deletions(-) delete mode 100644 doc/ci/definitions/README.md diff --git a/doc/ci/README.md b/doc/ci/README.md index 7abce85c8d8..f8d02af31ab 100644 --- a/doc/ci/README.md +++ b/doc/ci/README.md @@ -1,11 +1,11 @@ ## GitLab CI Documentation -### CI/CD User documentation +### CI User documentation - [Get started with GitLab CI](quick_start/README.md) -- [CI/CD Definitions](definitions/README.md) - [CI examples for various languages](examples/README.md) - [Learn how to enable or disable GitLab CI](enable_or_disable_ci.md) +- [Pipelines](pipelines.md) - [Environments and deployments](environments.md) - [Learn how `.gitlab-ci.yml` works](yaml/README.md) - [Configure a Runner, the application that runs your builds](runners/README.md) diff --git a/doc/ci/definitions/README.md b/doc/ci/definitions/README.md deleted file mode 100644 index 4ec5eee5757..00000000000 --- a/doc/ci/definitions/README.md +++ /dev/null @@ -1,52 +0,0 @@ -## CI/CD Definitions - -### Pipelines - -A pipeline is a group of [builds] that get executed in [stages] (batches). All of -the builds in a stage are executed in parallel (if there are enough concurrent -[runners]), and if they all succeed, the pipeline moves on to the next stage. If -one of the builds fails, the next stage is not (usually) executed. - -### Builds - -Builds are runs of [jobs]. Not to be confused with a `build` stage. - -### Jobs - -Jobs are the basic work unit of CI/CD. Jobs are used to create [builds], which are -then picked up by [Runners] and executed within the environment of the Runner. -Each job is run independently from each other. - -### Runners - -A runner is an isolated (virtual) machine that picks up builds through the -coordinator API of GitLab CI. A runner can be specific to a certain project or -serve any project in GitLab CI. A runner that serves all projects is called a -shared runner. - -### Stages - -Stages allow [jobs] to be grouped into parallel and sequential [builds]. Builds -of the same stage are executed in parallel and builds of the next stage are run -after the jobs from the previous stage complete successfully. Stages allow for -flexible multi-stage [pipelines]. By default [pipelines] have `build`, `test` -and `deploy` stages, but these can be defined in `.gitlab-ci.yml`. If a job -doesn't specify a stage, the job is assigned to the test stage. - -### Environments - -Environments are places where code gets deployed, such as staging or production. -CI/CD [Pipelines] usually have one or more deploy stages with [jobs] that do -[deployments] to an environment. - -### Deployments - -Deployments are created when [jobs] deploy versions of code to [environments]. - -[pipelines]: #pipelines -[builds]: #builds -[runners]: #runners -[jobs]: #jobs -[stages]: #stages -[environments]: #environments -[deployments]: #deployments diff --git a/doc/ci/environments.md b/doc/ci/environments.md index 040379bb381..d85b8a34ced 100644 --- a/doc/ci/environments.md +++ b/doc/ci/environments.md @@ -52,7 +52,7 @@ Clicking on an environment will show the history of deployments. Only deploys that happen after your `.gitlab-ci.yml` is properly configured will show up in the environments and deployments lists. -[Pipelines]: quick_start/README.md +[Pipelines]: pipelines.md [jobs]: yaml/README.md#jobs [environments]: #environments [deployments]: #deployments -- cgit v1.2.1 From 2302b2c131044cf502b020d900b334bc187f945a Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Mon, 20 Jun 2016 15:08:29 -0700 Subject: Update browser gem to 2.2.0 Fixes https://github.com/fnando/browser/issues/241 --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index bc1223e1bbc..2ea91da07fe 100644 --- a/Gemfile +++ b/Gemfile @@ -48,7 +48,7 @@ gem 'attr_encrypted', '~> 3.0.0' gem 'u2f', '~> 0.2.1' # Browser detection -gem "browser", '~> 2.0.3' +gem "browser", '~> 2.2' # Extracting information from a git repository # Provide access to Gitlab::Git library diff --git a/Gemfile.lock b/Gemfile.lock index 49e548fb94f..ed01d766e80 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -98,7 +98,7 @@ GEM autoprefixer-rails (>= 5.2.1) sass (>= 3.3.4) brakeman (3.3.2) - browser (2.0.3) + browser (2.2.0) builder (3.2.2) bullet (5.0.0) activesupport (>= 3.0.0) @@ -833,7 +833,7 @@ DEPENDENCIES binding_of_caller (~> 0.7.2) bootstrap-sass (~> 3.3.0) brakeman (~> 3.3.0) - browser (~> 2.0.3) + browser (~> 2.2) bullet bundler-audit byebug -- cgit v1.2.1 From a03cadcdbf3024ec59234a07a9b87884de5cc7dc Mon Sep 17 00:00:00 2001 From: Mark Pundsack Date: Mon, 20 Jun 2016 15:10:11 -0700 Subject: Move Pipelines and Builds definitions to their own page --- doc/ci/pipelines.md | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 doc/ci/pipelines.md diff --git a/doc/ci/pipelines.md b/doc/ci/pipelines.md new file mode 100644 index 00000000000..48a9f994759 --- /dev/null +++ b/doc/ci/pipelines.md @@ -0,0 +1,38 @@ +# Introduction to pipelines and builds + +>**Note:** +Introduced in GitLab 8.8. + +## Pipelines + +A pipeline is a group of [builds] that get executed in [stages] (batches). All +of the builds in a stage are executed in parallel (if there are enough +concurrent [runners]), and if they all succeed, the pipeline moves on to the +next stage. If one of the builds fails, the next stage is not (usually) +executed. + +## Builds + +Builds are individual runs of [jobs]. Not to be confused with a `build` job or +`build` stage. + +## Defining pipelines + +Pipelines are defined in `.gitlab-ci.yml` by specifying [jobs] that run in +[stages]. + +See full [documentation](yaml/README.md#jobs). + +## Seeing pipeline status + +You can find the current and historical pipeline runs under **Pipelines** for your +project. + +## Seeing build status + +Clicking on a pipeline will show the builds that were run for that pipeline. + +[builds]: #builds +[jobs]: yaml/README.md#jobs +[stages]: yaml/README.md#stages +[runners]: runners/README.md -- cgit v1.2.1 From 0582c085554a8649f3c9daa0dde611e3a851db3e Mon Sep 17 00:00:00 2001 From: Mark Pundsack Date: Mon, 20 Jun 2016 15:12:04 -0700 Subject: Add 'and builds' --- doc/ci/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/ci/README.md b/doc/ci/README.md index f8d02af31ab..3dd4e2bc230 100644 --- a/doc/ci/README.md +++ b/doc/ci/README.md @@ -5,7 +5,7 @@ - [Get started with GitLab CI](quick_start/README.md) - [CI examples for various languages](examples/README.md) - [Learn how to enable or disable GitLab CI](enable_or_disable_ci.md) -- [Pipelines](pipelines.md) +- [Pipelines and builds](pipelines.md) - [Environments and deployments](environments.md) - [Learn how `.gitlab-ci.yml` works](yaml/README.md) - [Configure a Runner, the application that runs your builds](runners/README.md) -- cgit v1.2.1 From a4d4a7e6357b60aceec93f6539b5dbefd3327032 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Mon, 13 Jun 2016 10:00:26 +0100 Subject: Fixed issue with notification dropdownn not updating active Changes bell icon to spinner to show the action is happening Removed the flash message Closes #18480 --- app/assets/javascripts/notifications_dropdown.js.coffee | 7 ++++--- app/assets/javascripts/project.js.coffee | 1 - app/assets/stylesheets/pages/projects.scss | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/assets/javascripts/notifications_dropdown.js.coffee b/app/assets/javascripts/notifications_dropdown.js.coffee index 74d2298c1fa..0bbd082c156 100644 --- a/app/assets/javascripts/notifications_dropdown.js.coffee +++ b/app/assets/javascripts/notifications_dropdown.js.coffee @@ -1,5 +1,5 @@ class @NotificationsDropdown - $ -> + constructor: -> $(document) .off 'click', '.update-notification' .on 'click', '.update-notification', (e) -> @@ -18,7 +18,8 @@ class @NotificationsDropdown .off 'ajax:success', '.notification-form' .on 'ajax:success', '.notification-form', (e, data) -> if data.saved - new Flash('Notification settings saved', 'notice') - $(e.currentTarget).closest('.notification-dropdown').replaceWith(data.html) + $(e.currentTarget) + .closest('.notification-dropdown') + .replaceWith(data.html) else new Flash('Failed to save new settings', 'alert') diff --git a/app/assets/javascripts/project.js.coffee b/app/assets/javascripts/project.js.coffee index 54c539d5f9b..96e10dd7e8a 100644 --- a/app/assets/javascripts/project.js.coffee +++ b/app/assets/javascripts/project.js.coffee @@ -35,7 +35,6 @@ class @Project $(@).parents('.no-password-message').remove() e.preventDefault() - @projectSelectDropdown() projectSelectDropdown: -> diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss index 346badf6d86..d3e59d7fdb9 100644 --- a/app/assets/stylesheets/pages/projects.scss +++ b/app/assets/stylesheets/pages/projects.scss @@ -101,7 +101,8 @@ .notifications-btn { - .fa-bell { + .fa-bell, + .fa-spinner { margin-right: 6px; } -- cgit v1.2.1 From 472fe597e02669964c165061391408de324420ed Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Mon, 13 Jun 2016 15:14:58 +0100 Subject: Fixed notification tests --- features/steps/project/project.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/steps/project/project.rb b/features/steps/project/project.rb index 98b57e5cbfb..76fefee9254 100644 --- a/features/steps/project/project.rb +++ b/features/steps/project/project.rb @@ -134,8 +134,8 @@ class Spinach::Features::Project < Spinach::FeatureSteps end step 'I should see Notification saved message' do - page.within '.flash-container' do - expect(page).to have_content 'Notification settings saved' + page.within '#notifications-button' do + expect(page).to have_content 'On mention' end end -- cgit v1.2.1 From cdcbc8d7219a669c016aaba89a1d47faebdd2208 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Tue, 21 Jun 2016 16:31:37 +0800 Subject: Update wordings according to: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/4093#note_12594802 --- app/views/projects/runners/_form.html.haml | 4 ++-- app/views/projects/runners/_runner.html.haml | 2 +- app/views/projects/runners/show.html.haml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/projects/runners/_form.html.haml b/app/views/projects/runners/_form.html.haml index 0946e5e327a..c45a9d4f81f 100644 --- a/app/views/projects/runners/_form.html.haml +++ b/app/views/projects/runners/_form.html.haml @@ -13,11 +13,11 @@ = f.check_box :run_untagged %span.light Indicates whether this runner can pick jobs without tags .form-group - = label :locked, 'Lock to this project', class: 'control-label' + = label :locked, 'Lock to current projects', class: 'control-label' .col-sm-10 .checkbox = f.check_box :locked - %span.light When a runner is locked, it cannot be enabled for other projects + %span.light When a runner is locked, it cannot be assigned to other projects .form-group = label_tag :token, class: 'control-label' do Token diff --git a/app/views/projects/runners/_runner.html.haml b/app/views/projects/runners/_runner.html.haml index 3cf66bbcb4a..85225857758 100644 --- a/app/views/projects/runners/_runner.html.haml +++ b/app/views/projects/runners/_runner.html.haml @@ -5,7 +5,7 @@ - if @project_runners.include?(runner) = link_to runner.short_sha, runner_path(runner) - if runner.locked? - = icon('lock', class: 'has-tooltip', title: 'Exclusive to this project') + = icon('lock', class: 'has-tooltip', title: 'Locked to current projects') %small = link_to edit_namespace_project_runner_path(@project.namespace, @project, runner) do %i.fa.fa-edit.btn diff --git a/app/views/projects/runners/show.html.haml b/app/views/projects/runners/show.html.haml index fc6424402ae..61b99f35d74 100644 --- a/app/views/projects/runners/show.html.haml +++ b/app/views/projects/runners/show.html.haml @@ -23,7 +23,7 @@ %td Can run untagged jobs %td= @runner.run_untagged? ? 'Yes' : 'No' %tr - %td Exclusive to this project + %td Locked to this project %td= @runner.locked? ? 'Yes' : 'No' %tr %td Tags -- cgit v1.2.1 From b5a718d1d793dd0dde38d598b5594d40873874cd Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Tue, 21 Jun 2016 09:54:15 +0100 Subject: Updated blank state for environments and deployments Closes #18661 --- app/assets/stylesheets/framework.scss | 1 + app/assets/stylesheets/framework/blank.scss | 23 +++++++++++++++++++++++ app/views/projects/environments/index.html.haml | 11 +++++++---- app/views/projects/environments/new.html.haml | 5 ++++- app/views/projects/environments/show.html.haml | 12 ++++++++---- 5 files changed, 43 insertions(+), 9 deletions(-) create mode 100644 app/assets/stylesheets/framework/blank.scss diff --git a/app/assets/stylesheets/framework.scss b/app/assets/stylesheets/framework.scss index 3cbddc59f11..a306b8f3f29 100644 --- a/app/assets/stylesheets/framework.scss +++ b/app/assets/stylesheets/framework.scss @@ -37,3 +37,4 @@ @import "framework/timeline.scss"; @import "framework/typography.scss"; @import "framework/zen.scss"; +@import "framework/blank"; diff --git a/app/assets/stylesheets/framework/blank.scss b/app/assets/stylesheets/framework/blank.scss new file mode 100644 index 00000000000..40b5171a8c6 --- /dev/null +++ b/app/assets/stylesheets/framework/blank.scss @@ -0,0 +1,23 @@ +.blank-state { + padding-top: 20px; + padding-bottom: 20px; + text-align: center; +} + +.blank-state-no-icon { + padding-top: 40px; + padding-bottom: 40px; +} + +.blank-state-title { + margin-top: 0; + margin-bottom: 5px; + font-size: 19px; + font-weight: normal; +} + +.blank-state-text { + margin-top: 0; + margin-bottom: $gl-padding; + font-size: 15px; +} diff --git a/app/views/projects/environments/index.html.haml b/app/views/projects/environments/index.html.haml index ae9e77e7d89..bfd8a11ce93 100644 --- a/app/views/projects/environments/index.html.haml +++ b/app/views/projects/environments/index.html.haml @@ -3,16 +3,19 @@ = render "projects/pipelines/head" %div{ class: (container_class) } - - if can?(current_user, :create_environment, @project) + - if can?(current_user, :create_environment, @project) && !@environments.blank? .top-area .nav-controls = link_to new_namespace_project_environment_path(@project.namespace, @project), class: 'btn btn-create' do New environment - if @environments.blank? - %ul.content-list.environments - %li.nothing-here-block - No environments to show + .blank-state.blank-state-no-icon + %h2.blank-state-title + You don't have any environments right now. + %p.blank-state-text + Environments are places where code gets deployed, such as staging or production. + = link_to "Read more", help_page_path("ci", "environments"), class: "btn btn-success" - else .table-holder %table.table.environments diff --git a/app/views/projects/environments/new.html.haml b/app/views/projects/environments/new.html.haml index 54465828ba9..da325efecd2 100644 --- a/app/views/projects/environments/new.html.haml +++ b/app/views/projects/environments/new.html.haml @@ -4,6 +4,9 @@ .col-lg-3 %h4.prepend-top-0 New Environment - %p Environments allow you to track deployments of your application + %p + Environments allow you to track deployments of your application + = succeed "." do + = link_to "Read more about environments", help_page_path("ci", "environments") = render 'form' diff --git a/app/views/projects/environments/show.html.haml b/app/views/projects/environments/show.html.haml index 069b77b5adf..4c15e2759d6 100644 --- a/app/views/projects/environments/show.html.haml +++ b/app/views/projects/environments/show.html.haml @@ -13,10 +13,14 @@ = link_to 'Destroy', namespace_project_environment_path(@project.namespace, @project, @environment), data: { confirm: 'Are you sure you want to delete this environment?' }, class: 'btn btn-danger', method: :delete - if @deployments.blank? - %ul.content-list.environments - %li.nothing-here-block - No deployments for - %strong= @environment.name + .blank-state.blank-state-no-icon + %h2.blank-state-title + You don't have any deployments right now. + %p.blank-state-text + Define environments in the deploy stage(s) in + %code .gitlab-ci.yml + to track deployments here. + = link_to "Read more", help_page_path("ci", "environments"), class: "btn btn-success" - else .table-holder %table.table.environments -- cgit v1.2.1 From 6bc22d95b823514d6b22455512002731766a1dd1 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Tue, 21 Jun 2016 11:26:44 +0200 Subject: Add test coverage to LFS fetching --- lib/gitlab/lfs/router.rb | 2 + spec/lib/gitlab/lfs/lfs_router_spec.rb | 529 +++++++++++++++------------------ 2 files changed, 242 insertions(+), 289 deletions(-) diff --git a/lib/gitlab/lfs/router.rb b/lib/gitlab/lfs/router.rb index f0c58890547..69bd5e62305 100644 --- a/lib/gitlab/lfs/router.rb +++ b/lib/gitlab/lfs/router.rb @@ -1,6 +1,8 @@ module Gitlab module Lfs class Router + attr_reader :project, :user, :ci, :request + def initialize(project, user, ci, request) @project = project @user = user diff --git a/spec/lib/gitlab/lfs/lfs_router_spec.rb b/spec/lib/gitlab/lfs/lfs_router_spec.rb index 8c5a27bf368..659facd6c19 100644 --- a/spec/lib/gitlab/lfs/lfs_router_spec.rb +++ b/spec/lib/gitlab/lfs/lfs_router_spec.rb @@ -83,6 +83,7 @@ describe Gitlab::Lfs::Router, lib: true do context 'with required headers' do before do + project.lfs_objects << lfs_object env['HTTP_X_SENDFILE_TYPE'] = "X-Sendfile" end @@ -94,7 +95,6 @@ describe Gitlab::Lfs::Router, lib: true do context 'when user has project access' do before do - project.lfs_objects << lfs_object project.team << [user, :master] end @@ -148,143 +148,145 @@ describe Gitlab::Lfs::Router, lib: true do end describe 'download' do - describe 'when user is authenticated' do - before do - body = { 'operation' => 'download', - 'objects' => [ - { 'oid' => sample_oid, - 'size' => sample_size - }] - }.to_json - env['rack.input'] = StringIO.new(body) - end + before do + body = { 'operation' => 'download', + 'objects' => [ + { 'oid' => sample_oid, + 'size' => sample_size + }] + }.to_json + env['rack.input'] = StringIO.new(body) + end - describe 'when user has download access' do + shared_examples 'an authorized requests' do + context 'when downloading an lfs object that is assigned to our project' do before do - @auth = authorize(user) - env["HTTP_AUTHORIZATION"] = @auth - project.team << [user, :reporter] + project.lfs_objects << lfs_object end - context 'when downloading an lfs object that is assigned to our project' do - before do - project.lfs_objects << lfs_object - end - - it 'responds with status 200 and href to download' do - response = lfs_router_auth.try_call - expect(response.first).to eq(200) - response_body = ActiveSupport::JSON.decode(response.last.first) + it 'responds with status 200 and href to download' do + response = router.try_call + expect(response.first).to eq(200) + response_body = ActiveSupport::JSON.decode(response.last.first) - expect(response_body).to eq('objects' => [ - { 'oid' => sample_oid, - 'size' => sample_size, - 'actions' => { - 'download' => { - 'href' => "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}", - 'header' => { 'Authorization' => @auth } - } + expect(response_body).to eq('objects' => [ + { 'oid' => sample_oid, + 'size' => sample_size, + 'actions' => { + 'download' => { + 'href' => "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}", + 'header' => { 'Authorization' => auth } } - }]) - end + } + }]) end + end - context 'when downloading an lfs object that is assigned to other project' do - before do - public_project.lfs_objects << lfs_object - end + context 'when downloading an lfs object that is assigned to other project' do + before do + public_project.lfs_objects << lfs_object + end - it 'responds with status 200 and error message' do - response = lfs_router_auth.try_call - expect(response.first).to eq(200) - response_body = ActiveSupport::JSON.decode(response.last.first) + it 'responds with status 200 and error message' do + response = router.try_call + expect(response.first).to eq(200) + response_body = ActiveSupport::JSON.decode(response.last.first) - expect(response_body).to eq('objects' => [ - { 'oid' => sample_oid, - 'size' => sample_size, - 'error' => { - 'code' => 404, - 'message' => "Object does not exist on the server or you don't have permissions to access it", - } - }]) - end + expect(response_body).to eq('objects' => [ + { 'oid' => sample_oid, + 'size' => sample_size, + 'error' => { + 'code' => 404, + 'message' => "Object does not exist on the server or you don't have permissions to access it", + } + }]) end + end - context 'when downloading a lfs object that does not exist' do - before do - body = { 'operation' => 'download', - 'objects' => [ - { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897', - 'size' => 1575078 - }] - }.to_json - env['rack.input'] = StringIO.new(body) - end + context 'when downloading a lfs object that does not exist' do + before do + body = { 'operation' => 'download', + 'objects' => [ + { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897', + 'size' => 1575078 + }] + }.to_json + env['rack.input'] = StringIO.new(body) + end - it "responds with status 200 and error message" do - response = lfs_router_auth.try_call - expect(response.first).to eq(200) - response_body = ActiveSupport::JSON.decode(response.last.first) + it "responds with status 200 and error message" do + response = router.try_call + expect(response.first).to eq(200) + response_body = ActiveSupport::JSON.decode(response.last.first) - expect(response_body).to eq('objects' => [ - { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897', - 'size' => 1575078, - 'error' => { - 'code' => 404, - 'message' => "Object does not exist on the server or you don't have permissions to access it", - } - }]) - end + expect(response_body).to eq('objects' => [ + { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897', + 'size' => 1575078, + 'error' => { + 'code' => 404, + 'message' => "Object does not exist on the server or you don't have permissions to access it", + } + }]) end + end - context 'when downloading one new and one existing lfs object' do - before do - body = { 'operation' => 'download', - 'objects' => [ - { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897', - 'size' => 1575078 - }, - { 'oid' => sample_oid, - 'size' => sample_size - } - ] - }.to_json - env['rack.input'] = StringIO.new(body) - project.lfs_objects << lfs_object - end + context 'when downloading one new and one existing lfs object' do + before do + body = { 'operation' => 'download', + 'objects' => [ + { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897', + 'size' => 1575078 + }, + { 'oid' => sample_oid, + 'size' => sample_size + } + ] + }.to_json + env['rack.input'] = StringIO.new(body) + project.lfs_objects << lfs_object + end - it "responds with status 200 with upload hypermedia link for the new object" do - response = lfs_router_auth.try_call - expect(response.first).to eq(200) - response_body = ActiveSupport::JSON.decode(response.last.first) + it "responds with status 200 with upload hypermedia link for the new object" do + response = router.try_call + expect(response.first).to eq(200) + response_body = ActiveSupport::JSON.decode(response.last.first) - expect(response_body).to eq('objects' => [ - { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897', - 'size' => 1575078, - 'error' => { - 'code' => 404, - 'message' => "Object does not exist on the server or you don't have permissions to access it", - } - }, - { 'oid' => sample_oid, - 'size' => sample_size, - 'actions' => { - 'download' => { - 'href' => "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}", - 'header' => { 'Authorization' => @auth } - } + expect(response_body).to eq('objects' => [ + { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897', + 'size' => 1575078, + 'error' => { + 'code' => 404, + 'message' => "Object does not exist on the server or you don't have permissions to access it", + } + }, + { 'oid' => sample_oid, + 'size' => sample_size, + 'actions' => { + 'download' => { + 'href' => "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}", + 'header' => { 'Authorization' => auth } } - }]) - end + } + }]) end end + end + + context 'when user is authenticated' do + let(:auth) { authorize(user) } + + before do + env["HTTP_AUTHORIZATION"] = auth + project.team << [user, role] + end + + it_behaves_like 'an authorized requests' do + let(:role) { :reporter } + let(:router) { lfs_router_auth } + end context 'when user does is not member of the project' do - before do - @auth = authorize(user) - env["HTTP_AUTHORIZATION"] = @auth - project.team << [user, :guest] - end + let(:role) { :guest } it 'responds with 403' do expect(lfs_router_auth.try_call.first).to eq(403) @@ -292,11 +294,7 @@ describe Gitlab::Lfs::Router, lib: true do end context 'when user does not have download access' do - before do - @auth = authorize(user) - env["HTTP_AUTHORIZATION"] = @auth - project.team << [user, :guest] - end + let(:role) { :guest } it 'responds with 403' do expect(lfs_router_auth.try_call.first).to eq(403) @@ -304,18 +302,19 @@ describe Gitlab::Lfs::Router, lib: true do end end - context 'when user is not authenticated' do + context 'when CI is authorized' do + let(:auth) { 'gitlab-ci-token:password' } + before do - body = { 'operation' => 'download', - 'objects' => [ - { 'oid' => sample_oid, - 'size' => sample_size - }], + env["HTTP_AUTHORIZATION"] = auth + end - }.to_json - env['rack.input'] = StringIO.new(body) + it_behaves_like 'an authorized requests' do + let(:router) { lfs_router_ci_auth } end + end + context 'when user is not authenticated' do describe 'is accessing public project' do before do public_project.lfs_objects << lfs_object @@ -352,17 +351,17 @@ describe Gitlab::Lfs::Router, lib: true do end describe 'upload' do - describe 'when user is authenticated' do - before do - body = { 'operation' => 'upload', - 'objects' => [ - { 'oid' => sample_oid, - 'size' => sample_size - }] - }.to_json - env['rack.input'] = StringIO.new(body) - end + before do + body = { 'operation' => 'upload', + 'objects' => [ + { 'oid' => sample_oid, + 'size' => sample_size + }] + }.to_json + env['rack.input'] = StringIO.new(body) + end + describe 'when request is authenticated' do describe 'when user has project push access' do before do @auth = authorize(user) @@ -454,15 +453,15 @@ describe Gitlab::Lfs::Router, lib: true do expect(lfs_router_auth.try_call.first).to eq(403) end end - end - context 'when user is not authenticated' do - before do - env['rack.input'] = StringIO.new( - { 'objects' => [], 'operation' => 'upload' }.to_json - ) + context 'when CI is authorized' do + it 'responds with 401' do + expect(lfs_router_ci_auth.try_call.first).to eq(401) + end end + end + context 'when user is not authenticated' do context 'when user has push access' do before do project.team << [user, :master] @@ -479,6 +478,18 @@ describe Gitlab::Lfs::Router, lib: true do end end end + + context 'when CI is authorized' do + let(:auth) { 'gitlab-ci-token:password' } + + before do + env["HTTP_AUTHORIZATION"] = auth + end + + it "responds with status 403" do + expect(lfs_router_public_ci_auth.try_call.first).to eq(401) + end + end end describe 'unsupported' do @@ -504,13 +515,68 @@ describe Gitlab::Lfs::Router, lib: true do env['REQUEST_METHOD'] = 'PUT' end - describe 'to one project' do - describe 'when user has push access to the project' do + shared_examples 'unauthorized' do + context 'and request is sent by gitlab-workhorse to authorize the request' do + before do + header_for_upload_authorize(router.project) + end + + it 'responds with status 401' do + expect(router.try_call.first).to eq(401) + end + end + + context 'and request is sent by gitlab-workhorse to finalize the upload' do + before do + headers_for_upload_finalize(router.project) + end + + it 'responds with status 401' do + expect(router.try_call.first).to eq(401) + end + end + + context 'and request is sent with a malformed headers' do before do - project.team << [user, :master] + env["PATH_INFO"] = "#{router.project.repository.path_with_namespace}.git/gitlab-lfs/objects/#{sample_oid}/#{sample_size}" + env["HTTP_X_GITLAB_LFS_TMP"] = "cat /etc/passwd" end - describe 'when user is authenticated' do + it 'does not recognize it as a valid lfs command' do + expect(router.try_call).to eq(nil) + end + end + end + + shared_examples 'forbidden' do + context 'and request is sent by gitlab-workhorse to authorize the request' do + before do + header_for_upload_authorize(router.project) + end + + it 'responds with 403' do + expect(router.try_call.first).to eq(403) + end + end + + context 'and request is sent by gitlab-workhorse to finalize the upload' do + before do + headers_for_upload_finalize(router.project) + end + + it 'responds with 403' do + expect(router.try_call.first).to eq(403) + end + end + end + + describe 'to one project' do + describe 'when user is authenticated' do + describe 'when user has push access to the project' do + before do + project.team << [user, :developer] + end + context 'and request is sent by gitlab-workhorse to authorize the request' do before do header_for_upload_authorize(project) @@ -538,100 +604,35 @@ describe Gitlab::Lfs::Router, lib: true do end end - describe 'when user is unauthenticated' do - let(:lfs_router_noauth) { new_lfs_router(project) } - - context 'and request is sent by gitlab-workhorse to authorize the request' do - before do - header_for_upload_authorize(project) - end - - it 'responds with status 401' do - expect(lfs_router_noauth.try_call.first).to eq(401) - end - end - - context 'and request is sent by gitlab-workhorse to finalize the upload' do - before do - headers_for_upload_finalize(project) - end - - it 'responds with status 401' do - expect(lfs_router_noauth.try_call.first).to eq(401) - end - end + describe 'and user does not have push access' do + let(:router) { lfs_router_auth } - context 'and request is sent with a malformed headers' do - before do - env["PATH_INFO"] = "#{project.repository.path_with_namespace}.git/gitlab-lfs/objects/#{sample_oid}/#{sample_size}" - env["HTTP_X_GITLAB_LFS_TMP"] = "cat /etc/passwd" - end - - it 'does not recognize it as a valid lfs command' do - expect(lfs_router_noauth.try_call).to eq(nil) - end - end + it_behaves_like 'forbidden' end end - describe 'and user does not have push access' do - describe 'when user is authenticated' do - context 'and request is sent by gitlab-workhorse to authorize the request' do - before do - header_for_upload_authorize(project) - end - - it 'responds with 403' do - expect(lfs_router_auth.try_call.first).to eq(403) - end - end + context 'when CI is authenticated' do + let(:router) { lfs_router_ci_auth } - context 'and request is sent by gitlab-workhorse to finalize the upload' do - before do - headers_for_upload_finalize(project) - end - - it 'responds with 403' do - expect(lfs_router_auth.try_call.first).to eq(403) - end - end - end - - describe 'when user is unauthenticated' do - let(:lfs_router_noauth) { new_lfs_router(project) } - - context 'and request is sent by gitlab-workhorse to authorize the request' do - before do - header_for_upload_authorize(project) - end - - it 'responds with 401' do - expect(lfs_router_noauth.try_call.first).to eq(401) - end - end + it_behaves_like 'unauthorized' + end - context 'and request is sent by gitlab-workhorse to finalize the upload' do - before do - headers_for_upload_finalize(project) - end + context 'for unauthenticated' do + let(:router) { new_lfs_router(project) } - it 'responds with 401' do - expect(lfs_router_noauth.try_call.first).to eq(401) - end - end - end + it_behaves_like 'unauthorized' end end - describe "to a forked project" do + describe 'to a forked project' do let(:forked_project) { fork_project(public_project, user) } - describe 'when user has push access to the project' do - before do - forked_project.team << [user_two, :master] - end + describe 'when user is authenticated' do + describe 'when user has push access to the project' do + before do + forked_project.team << [user_two, :developer] + end - describe 'when user is authenticated' do context 'and request is sent by gitlab-workhorse to authorize the request' do before do header_for_upload_authorize(forked_project) @@ -659,73 +660,23 @@ describe Gitlab::Lfs::Router, lib: true do end end - describe 'when user is unauthenticated' do - context 'and request is sent by gitlab-workhorse to authorize the request' do - before do - header_for_upload_authorize(forked_project) - end - - it 'responds with status 401' do - expect(lfs_router_forked_noauth.try_call.first).to eq(401) - end - end - - context 'and request is sent by gitlab-workhorse to finalize the upload' do - before do - headers_for_upload_finalize(forked_project) - end + describe 'and user does not have push access' do + let(:router) { lfs_router_forked_auth } - it 'responds with status 401' do - expect(lfs_router_forked_noauth.try_call.first).to eq(401) - end - end + it_behaves_like 'forbidden' end end - describe 'and user does not have push access' do - describe 'when user is authenticated' do - context 'and request is sent by gitlab-workhorse to authorize the request' do - before do - header_for_upload_authorize(forked_project) - end - - it 'responds with 403' do - expect(lfs_router_forked_auth.try_call.first).to eq(403) - end - end - - context 'and request is sent by gitlab-workhorse to finalize the upload' do - before do - headers_for_upload_finalize(forked_project) - end - - it 'responds with 403' do - expect(lfs_router_forked_auth.try_call.first).to eq(403) - end - end - end + context 'when CI is authenticated' do + let(:router) { lfs_router_forked_ci_auth } - describe 'when user is unauthenticated' do - context 'and request is sent by gitlab-workhorse to authorize the request' do - before do - header_for_upload_authorize(forked_project) - end - - it 'responds with 401' do - expect(lfs_router_forked_noauth.try_call.first).to eq(401) - end - end + it_behaves_like 'unauthorized' + end - context 'and request is sent by gitlab-workhorse to finalize the upload' do - before do - headers_for_upload_finalize(forked_project) - end + context 'for unauthenticated' do + let(:router) { lfs_router_forked_noauth } - it 'responds with 401' do - expect(lfs_router_forked_noauth.try_call.first).to eq(401) - end - end - end + it_behaves_like 'unauthorized' end describe 'and second project not related to fork or a source project' do -- cgit v1.2.1 From ef1e3d0df741b842e17b31ec222751850d3c7e94 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Fri, 17 Jun 2016 12:15:08 -0500 Subject: Add tooltip on pin/unpin nav --- app/assets/javascripts/application.js.coffee | 2 ++ app/views/layouts/_page.html.haml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/application.js.coffee b/app/assets/javascripts/application.js.coffee index 4529c514555..d9fcbf3d573 100644 --- a/app/assets/javascripts/application.js.coffee +++ b/app/assets/javascripts/application.js.coffee @@ -278,7 +278,9 @@ $ -> $('.navbar-fixed-top') .removeClass('header-pinned-nav') .toggleClass('header-collapsed header-expanded') + $('.pin-nav-btn').attr('data-original-title', 'Pin sidebar').tooltip('fixTitle').tooltip('setContent') else $.cookie 'pin_nav', 'true', { path: '/' } $('.page-with-sidebar').addClass('page-sidebar-pinned') $('.navbar-fixed-top').addClass('header-pinned-nav') + $('.pin-nav-btn').attr('data-original-title', 'Unpin sidebar').tooltip('fixTitle').tooltip('setContent') diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml index 199ab3c38c3..2234bf79c87 100644 --- a/app/views/layouts/_page.html.haml +++ b/app/views/layouts/_page.html.haml @@ -13,7 +13,7 @@ = image_tag avatar_icon(current_user, 60), alt: 'Profile', class: 'avatar avatar s36' .username = current_user.username - = link_to '#', class: "nav-header-btn text-center pin-nav-btn #{'is-active' if pinned_nav?} js-nav-pin", title: 'Pin/Unpin navigation' do + = link_to '#', class: "nav-header-btn text-center pin-nav-btn has-tooltip #{'is-active' if pinned_nav?} js-nav-pin", title: pinned_nav? ? "Unpin navigation" : "Pin Navigation", data: {placement: 'right', container: 'body'} do %span.sr-only Toggle navigation pinning = icon('thumb-tack') - if defined?(nav) && nav -- cgit v1.2.1 From 10220ef1e8a98e53172a5f5d22a08cae31e25c45 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Fri, 17 Jun 2016 12:17:24 -0500 Subject: Update CHANGELOG --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index e2d65c632dc..55a30d24670 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -138,6 +138,7 @@ v 8.9.0 (unreleased) - ExtractsPath get ref_names from repository cache, if not there access git. - Cache user todo counts from TodoService - Ensure Todos counters doesn't count Todos for projects pending delete + - Add tooltip to pin/unpin navbar v 8.8.5 - Import GitHub repositories respecting the API rate limit !4166 -- cgit v1.2.1 From 3beff9e4a119a0a292018458613d9bdf77c2c52b Mon Sep 17 00:00:00 2001 From: Alfredo Sumaran Date: Tue, 21 Jun 2016 04:57:14 -0500 Subject: Fix tooltip title and persist state --- app/assets/javascripts/application.js.coffee | 40 +++++++++++++++++++--------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/app/assets/javascripts/application.js.coffee b/app/assets/javascripts/application.js.coffee index d9fcbf3d573..397892d15c0 100644 --- a/app/assets/javascripts/application.js.coffee +++ b/app/assets/javascripts/application.js.coffee @@ -268,19 +268,33 @@ $ -> .on 'click', '.js-nav-pin', (e) -> e.preventDefault() + $pinBtn = $(e.currentTarget) + $page = $ '.page-with-sidebar' + $topNav = $ '.navbar-fixed-top' + $tooltip = $ "##{$pinBtn.attr('aria-describedby')}" + doPinNav = not $page.is('.page-sidebar-pinned') + tooltipText = 'Pin navigation' + $(this).toggleClass 'is-active' - if $.cookie('pin_nav') is 'true' - $.cookie 'pin_nav', 'false', { path: '/' } - $('.page-with-sidebar') - .removeClass('page-sidebar-pinned') - .toggleClass('page-sidebar-collapsed page-sidebar-expanded') - $('.navbar-fixed-top') - .removeClass('header-pinned-nav') - .toggleClass('header-collapsed header-expanded') - $('.pin-nav-btn').attr('data-original-title', 'Pin sidebar').tooltip('fixTitle').tooltip('setContent') + if doPinNav + $page.addClass('page-sidebar-pinned') + $topNav.addClass('header-pinned-nav') else - $.cookie 'pin_nav', 'true', { path: '/' } - $('.page-with-sidebar').addClass('page-sidebar-pinned') - $('.navbar-fixed-top').addClass('header-pinned-nav') - $('.pin-nav-btn').attr('data-original-title', 'Unpin sidebar').tooltip('fixTitle').tooltip('setContent') + $tooltip.remove() # Remove it immediately when collapsing the sidebar + $page.removeClass('page-sidebar-pinned') + .toggleClass('page-sidebar-collapsed page-sidebar-expanded') + $topNav.removeClass('header-pinned-nav') + .toggleClass('header-collapsed header-expanded') + + # Save settings + $.cookie 'pin_nav', doPinNav, { path: '/' } + + if $.cookie('pin_nav') is 'true' or doPinNav + tooltipText = 'Unpin navigation' + + # Update tooltip text immediately + $tooltip.find('.tooltip-inner').text(tooltipText) + + # Persist tooltip title + $pinBtn.attr('title', tooltipText).tooltip('fixTitle') -- cgit v1.2.1 From 85a5e42576fdbdef804dcab9b4ed2ad1d2bda23e Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Tue, 21 Jun 2016 11:12:28 +0100 Subject: Moved new environment link to below blank state text --- app/views/projects/environments/index.html.haml | 6 +++++- spec/features/environments_spec.rb | 6 +++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/views/projects/environments/index.html.haml b/app/views/projects/environments/index.html.haml index bfd8a11ce93..89b0e1b39e0 100644 --- a/app/views/projects/environments/index.html.haml +++ b/app/views/projects/environments/index.html.haml @@ -15,7 +15,11 @@ You don't have any environments right now. %p.blank-state-text Environments are places where code gets deployed, such as staging or production. - = link_to "Read more", help_page_path("ci", "environments"), class: "btn btn-success" + %br + = succeed "." do + = link_to "Read more about environments", help_page_path("ci", "environments") + = link_to new_namespace_project_environment_path(@project.namespace, @project), class: 'btn btn-create' do + New environment - else .table-holder %table.table.environments diff --git a/spec/features/environments_spec.rb b/spec/features/environments_spec.rb index 40fea5211e9..f9e066ade54 100644 --- a/spec/features/environments_spec.rb +++ b/spec/features/environments_spec.rb @@ -20,7 +20,7 @@ feature 'Environments', feature: true do context 'without environments' do scenario 'does show no environments' do - expect(page).to have_content('No environments to show') + expect(page).to have_content('You don\'t have any environments right now.') end end @@ -33,7 +33,7 @@ feature 'Environments', feature: true do context 'without deployments' do scenario 'does show no deployments' do - expect(page).to have_content('No deployments yet') + expect(page).to have_content('You don\'t have any deployments right now.') end end @@ -61,7 +61,7 @@ feature 'Environments', feature: true do context 'without deployments' do scenario 'does show no deployments' do - expect(page).to have_content('No deployments for') + expect(page).to have_content('You don\'t have any deployments right now.') end end -- cgit v1.2.1 From 62d16e515f6e9c82d3342172d77681472fecfa15 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Tue, 21 Jun 2016 09:58:03 +0100 Subject: Updated tests to not look for flash message --- app/views/profiles/notifications/show.html.haml | 2 +- features/steps/profile/notifications.rb | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/app/views/profiles/notifications/show.html.haml b/app/views/profiles/notifications/show.html.haml index 5afd83a522e..f77738f97f5 100644 --- a/app/views/profiles/notifications/show.html.haml +++ b/app/views/profiles/notifications/show.html.haml @@ -28,7 +28,7 @@ = label_tag :global_notification_level, "Global notification level", class: "label-light" %br .clearfix - .form-group.pull-left + .form-group.pull-left.global-notification-setting = render 'shared/notifications/button', notification_setting: @global_notification_setting, left_align: true .clearfix diff --git a/features/steps/profile/notifications.rb b/features/steps/profile/notifications.rb index 979f4692d5a..7e339443b75 100644 --- a/features/steps/profile/notifications.rb +++ b/features/steps/profile/notifications.rb @@ -15,8 +15,6 @@ class Spinach::Features::ProfileNotifications < Spinach::FeatureSteps end step 'I should see Notification saved message' do - page.within '.flash-container' do - expect(page).to have_content 'Notification settings saved' - end + expect(page).to have_content 'On mention' end end -- cgit v1.2.1 From c207b9e0512f630b646d9e62f75ca13a188cf83b Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Tue, 21 Jun 2016 11:52:51 +0100 Subject: Tests update --- app/views/projects/environments/index.html.haml | 5 +++-- spec/features/environments_spec.rb | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/views/projects/environments/index.html.haml b/app/views/projects/environments/index.html.haml index 89b0e1b39e0..a03f117291f 100644 --- a/app/views/projects/environments/index.html.haml +++ b/app/views/projects/environments/index.html.haml @@ -18,8 +18,9 @@ %br = succeed "." do = link_to "Read more about environments", help_page_path("ci", "environments") - = link_to new_namespace_project_environment_path(@project.namespace, @project), class: 'btn btn-create' do - New environment + - if can?(current_user, :create_environment, @project) + = link_to new_namespace_project_environment_path(@project.namespace, @project), class: 'btn btn-create' do + New environment - else .table-holder %table.table.environments diff --git a/spec/features/environments_spec.rb b/spec/features/environments_spec.rb index f9e066ade54..7fb28f4174b 100644 --- a/spec/features/environments_spec.rb +++ b/spec/features/environments_spec.rb @@ -33,7 +33,7 @@ feature 'Environments', feature: true do context 'without deployments' do scenario 'does show no deployments' do - expect(page).to have_content('You don\'t have any deployments right now.') + expect(page).to have_content('No deployments yet') end end @@ -108,7 +108,7 @@ feature 'Environments', feature: true do end scenario 'does create a new pipeline' do - expect(page).to have_content('production') + expect(page).to have_content('Production') end end -- cgit v1.2.1 From bfce7349ea7c2efcbeb3fb34a207aad65d3129e3 Mon Sep 17 00:00:00 2001 From: Paco Guzman Date: Mon, 20 Jun 2016 17:49:15 +0200 Subject: Cache Participable#participants in instance variable --- CHANGELOG | 1 + app/models/concerns/participable.rb | 10 ++++++++++ spec/models/concerns/participable_spec.rb | 10 ++++++++++ 3 files changed, 21 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 1cf8730cda1..310cb448cfd 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -135,6 +135,7 @@ v 8.9.0 (unreleased) - Update tanuki logo highlight/loading colors - Remove explicit Gitlab::Metrics.action assignments, are already automatic. - Use Git cached counters for branches and tags on project page + - Cache participable participants in an instance variable. - Filter parameters for request_uri value on instrumented transactions. - Remove duplicated keys add UNIQUE index to keys fingerprint column - ExtractsPath get ref_names from repository cache, if not there access git. diff --git a/app/models/concerns/participable.rb b/app/models/concerns/participable.rb index 9056722f45e..9822844357d 100644 --- a/app/models/concerns/participable.rb +++ b/app/models/concerns/participable.rb @@ -53,6 +53,16 @@ module Participable # # Returns an Array of User instances. def participants(current_user = nil) + @participants ||= Hash.new do |hash, user| + hash[user] = raw_participants(user) + end + + @participants[current_user] + end + + private + + def raw_participants(current_user = nil) current_user ||= author ext = Gitlab::ReferenceExtractor.new(project, current_user) participants = Set.new diff --git a/spec/models/concerns/participable_spec.rb b/spec/models/concerns/participable_spec.rb index 7e4ea0f2d66..a9f4ef9ee5e 100644 --- a/spec/models/concerns/participable_spec.rb +++ b/spec/models/concerns/participable_spec.rb @@ -37,6 +37,16 @@ describe Participable, models: true do expect(participants).to include(user3) end + it 'caches the raw list of participants' do + instance = model.new + user1 = build(:user) + + expect(instance).to receive(:raw_participants).once + + instance.participants(user1) + instance.participants(user1) + end + it 'supports attributes returning another Participable' do other_model = Class.new { include Participable } -- cgit v1.2.1 From 70606bf0c13212eb4dabf4314b783830dd01dbfc Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Tue, 21 Jun 2016 13:08:10 +0200 Subject: Show proper image ID on registry page --- CHANGELOG | 1 + app/views/projects/container_registry/_tag.html.haml | 6 +++--- lib/container_registry/tag.rb | 1 + spec/features/container_registry_spec.rb | 3 ++- spec/fixtures/container_registry/tag_manifest.json | 17 ++++++++++++++++- 5 files changed, 23 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 44e6a194745..321529d45a6 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -19,6 +19,7 @@ v 8.9.0 (unreleased) - Don't show 'Leave Project' to group members - Fix wiki page events' webhook to point to the wiki repository - Don't show tags for revert and cherry-pick operations + - Show image ID on registry page - Fix issue todo not remove when leave project !4150 (Long Nguyen) - Allow customisable text on the 'nearly there' page after a user signs up - Bump recaptcha gem to 3.0.0 to remove deprecated stoken support diff --git a/app/views/projects/container_registry/_tag.html.haml b/app/views/projects/container_registry/_tag.html.haml index f35faa6afb5..10822b6184c 100644 --- a/app/views/projects/container_registry/_tag.html.haml +++ b/app/views/projects/container_registry/_tag.html.haml @@ -3,9 +3,9 @@ = escape_once(tag.name) = clipboard_button(clipboard_text: "docker pull #{tag.path}") %td - - if layer = tag.layers.first - %span.has-tooltip{ title: "#{layer.revision}" } - = layer.short_revision + - if tag.revision + %span.has-tooltip{ title: "#{tag.revision}" } + = tag.short_revision - else \- %td diff --git a/lib/container_registry/tag.rb b/lib/container_registry/tag.rb index 7a0929d774e..708d01b95a1 100644 --- a/lib/container_registry/tag.rb +++ b/lib/container_registry/tag.rb @@ -3,6 +3,7 @@ module ContainerRegistry attr_reader :repository, :name delegate :registry, :client, to: :repository + delegate :revision, :short_revision, to: :config_blob, allow_nil: true def initialize(repository, name) @repository, @name = repository, name diff --git a/spec/features/container_registry_spec.rb b/spec/features/container_registry_spec.rb index 53b4f027117..203e55a36f2 100644 --- a/spec/features/container_registry_spec.rb +++ b/spec/features/container_registry_spec.rb @@ -26,7 +26,8 @@ describe "Container Registry" do end context 'when there are tags' do - it { expect(page).to have_content(tag_name)} + it { expect(page).to have_content(tag_name) } + it { expect(page).to have_content('d7a513a66') } end end diff --git a/spec/fixtures/container_registry/tag_manifest.json b/spec/fixtures/container_registry/tag_manifest.json index 1b6008e2872..8d1b874c29b 100644 --- a/spec/fixtures/container_registry/tag_manifest.json +++ b/spec/fixtures/container_registry/tag_manifest.json @@ -1 +1,16 @@ -{"schemaVersion":2,"mediaType":"application/vnd.docker.distribution.manifest.v2+json","config":{"mediaType":"application/octet-stream","size":1145,"digest":"sha256:d7a513a663c1a6dcdba9ed832ca53c02ac2af0c333322cd6ca92936d1d9917ac"},"layers":[{"mediaType":"application/vnd.docker.image.rootfs.diff.tar.gzip","size":2319870,"digest":"sha256:420890c9e918b6668faaedd9000e220190f2493b0693ee563ebd7b4cc754a57d"}]} +{ + "schemaVersion": 2, + "mediaType": "application/vnd.docker.distribution.manifest.v2+json", + "config": { + "mediaType": "application/octet-stream", + "size": 1145, + "digest": "sha256:d7a513a663c1a6dcdba9ed832ca53c02ac2af0c333322cd6ca92936d1d9917ac" + }, + "layers": [ + { + "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", + "size": 2319870, + "digest": "sha256:420890c9e918b6668faaedd9000e220190f2493b0693ee563ebd7b4cc754a57d" + } + ] +} -- cgit v1.2.1 From c6b4106401a2b89b3525571287b404728d824f18 Mon Sep 17 00:00:00 2001 From: Valery Sizov Date: Tue, 21 Jun 2016 14:27:20 +0300 Subject: Fix on-hover state for 'Edit' button on tree view --- app/helpers/blob_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb index 5b54b34070c..a7186f2b2c2 100644 --- a/app/helpers/blob_helper.rb +++ b/app/helpers/blob_helper.rb @@ -29,7 +29,7 @@ module BlobHelper if !on_top_of_branch?(project, ref) button_tag "Edit", class: "btn disabled has-tooltip btn-file-option", title: "You can only edit files when you are on a branch", data: { container: 'body' } elsif can_edit_blob?(blob, project, ref) - link_to "Edit", edit_path, class: 'btn btn-file-option' + link_to "Edit", edit_path, class: 'btn btn-sm' elsif can?(current_user, :fork_project, project) continue_params = { to: edit_path, -- cgit v1.2.1 From 8888dfaa8f862750aaf4565a41f7941cdf3f1a29 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Tue, 21 Jun 2016 13:35:37 +0200 Subject: add missing import source --- config/initializers/1_settings.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb index 09ffc319065..c6dc1e4ab38 100644 --- a/config/initializers/1_settings.rb +++ b/config/initializers/1_settings.rb @@ -215,7 +215,7 @@ Settings.gitlab.default_projects_features['container_registry'] = true if Settin Settings.gitlab.default_projects_features['visibility_level'] = Settings.send(:verify_constant, Gitlab::VisibilityLevel, Settings.gitlab.default_projects_features['visibility_level'], Gitlab::VisibilityLevel::PRIVATE) Settings.gitlab['repository_downloads_path'] = File.join(Settings.shared['path'], 'cache/archive') if Settings.gitlab['repository_downloads_path'].nil? Settings.gitlab['restricted_signup_domains'] ||= [] -Settings.gitlab['import_sources'] ||= ['github','bitbucket','gitlab','gitorious','google_code','fogbugz','git'] +Settings.gitlab['import_sources'] ||= %w[github bitbucket gitlab gitorious google_code fogbugz git gitlab_project] Settings.gitlab['trusted_proxies'] ||= [] -- cgit v1.2.1 From dd08202a247b8ad379f1481bc6c0f9008f35aba9 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Tue, 21 Jun 2016 14:26:57 +0200 Subject: Fix builds API response not including commit data --- app/models/commit_status.rb | 8 ++++++++ lib/api/entities.rb | 6 +----- spec/models/build_spec.rb | 13 ++++++++++++- spec/models/commit_status_spec.rb | 19 +++++++++++++++---- spec/requests/api/builds_spec.rb | 11 ++++++++--- 5 files changed, 44 insertions(+), 13 deletions(-) diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb index ab13db4b297..bb74ff2c5f6 100644 --- a/app/models/commit_status.rb +++ b/app/models/commit_status.rb @@ -90,4 +90,12 @@ class CommitStatus < ActiveRecord::Base def stuck? false end + + ## + # Deprecated, this should be removed in 9.0 in favor of exposing + # entire pipeline in API. + # + def commit + pipeline.try(:commit_data) + end end diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 0ee96d4c67b..5a23a18fe9c 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -445,11 +445,7 @@ module API expose :created_at, :started_at, :finished_at expose :user, with: User expose :artifacts_file, using: BuildArtifactFile, if: -> (build, opts) { build.artifacts? } - expose :commit, with: RepoCommit do |repo_obj, _options| - if repo_obj.respond_to?(:commit) - repo_obj.commit.commit_data - end - end + expose :commit, with: RepoCommit expose :runner, with: Runner end diff --git a/spec/models/build_spec.rb b/spec/models/build_spec.rb index 479b7309579..8154001cf46 100644 --- a/spec/models/build_spec.rb +++ b/spec/models/build_spec.rb @@ -2,7 +2,12 @@ require 'spec_helper' describe Ci::Build, models: true do let(:project) { create(:project) } - let(:pipeline) { create(:ci_pipeline, project: project) } + + let(:pipeline) do + create(:ci_pipeline, project: project, + sha: project.commit.id) + end + let(:build) { create(:ci_build, pipeline: pipeline) } it { is_expected.to validate_presence_of :ref } @@ -658,4 +663,10 @@ describe Ci::Build, models: true do end end end + + describe '#commit' do + it 'returns commit pipeline has been created for' do + expect(build.commit).to eq project.commit + end + end end diff --git a/spec/models/commit_status_spec.rb b/spec/models/commit_status_spec.rb index 8fb605fff8a..96397d7c8a9 100644 --- a/spec/models/commit_status_spec.rb +++ b/spec/models/commit_status_spec.rb @@ -1,8 +1,13 @@ require 'spec_helper' describe CommitStatus, models: true do - let(:pipeline) { FactoryGirl.create :ci_pipeline } - let(:commit_status) { FactoryGirl.create :commit_status, pipeline: pipeline } + let(:project) { create(:project) } + + let(:pipeline) do + create(:ci_pipeline, project: project, sha: project.commit.id) + end + + let(:commit_status) { create(:commit_status, pipeline: pipeline) } it { is_expected.to belong_to(:pipeline) } it { is_expected.to belong_to(:user) } @@ -13,7 +18,7 @@ describe CommitStatus, models: true do it { is_expected.to delegate_method(:sha).to(:pipeline) } it { is_expected.to delegate_method(:short_sha).to(:pipeline) } - + it { is_expected.to respond_to :success? } it { is_expected.to respond_to :failed? } it { is_expected.to respond_to :running? } @@ -116,7 +121,7 @@ describe CommitStatus, models: true do it { is_expected.to be > 0.0 } end end - + describe :latest do subject { CommitStatus.latest.order(:id) } @@ -198,4 +203,10 @@ describe CommitStatus, models: true do end end end + + describe '#commit' do + it 'returns commit pipeline has been created for' do + expect(commit_status.commit).to eq project.commit + end + end end diff --git a/spec/requests/api/builds_spec.rb b/spec/requests/api/builds_spec.rb index ac85f340922..47e9253a10c 100644 --- a/spec/requests/api/builds_spec.rb +++ b/spec/requests/api/builds_spec.rb @@ -9,8 +9,8 @@ describe API::API, api: true do let!(:project) { create(:project, creator_id: user.id) } let!(:developer) { create(:project_member, :developer, user: user, project: project) } let!(:reporter) { create(:project_member, :reporter, user: user2, project: project) } - let(:pipeline) { create(:ci_pipeline, project: project)} - let(:build) { create(:ci_build, pipeline: pipeline) } + let!(:pipeline) { create(:ci_pipeline, project: project, sha: project.commit.id) } + let!(:build) { create(:ci_build, pipeline: pipeline) } describe 'GET /projects/:id/builds ' do let(:query) { '' } @@ -23,6 +23,11 @@ describe API::API, api: true do expect(json_response).to be_an Array end + it 'returns correct values' do + expect(json_response).not_to be_empty + expect(json_response.first['commit']['id']).to eq project.commit.id + end + context 'filter project with one scope element' do let(:query) { 'scope=pending' } @@ -132,7 +137,7 @@ describe API::API, api: true do describe 'GET /projects/:id/builds/:build_id/trace' do let(:build) { create(:ci_build, :trace, pipeline: pipeline) } - + before { get api("/projects/#{project.id}/builds/#{build.id}/trace", api_user) } context 'authorized user' do -- cgit v1.2.1 From d9a64e9f4107c68257db7dc76d25e5ecc883d7b1 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Tue, 21 Jun 2016 14:33:13 +0200 Subject: Add Changelog entry for builds API commit data fix --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 2f42aa34990..6098d4b030b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ Please view this file on the master branch, on stable branches it's out of date. v 8.9.0 (unreleased) + - Fix builds API response not including commit data - Fix error when CI job variables key specified but not defined - Fix pipeline status when there are no builds in pipeline - Fix Error 500 when using closes_issues API with an external issue tracker -- cgit v1.2.1 From 92984783db82e98cae06c08c680fd9c766ac52f8 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Tue, 21 Jun 2016 14:43:37 +0200 Subject: Rename commit_data in Pipeline to commit --- app/controllers/projects/pipelines_controller.rb | 2 +- app/models/ci/pipeline.rb | 8 ++++---- app/models/commit_status.rb | 10 ++-------- app/views/projects/ci/pipelines/_pipeline.html.haml | 4 ++-- 4 files changed, 9 insertions(+), 15 deletions(-) diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb index 127bd1a4318..487963fdcd7 100644 --- a/app/controllers/projects/pipelines_controller.rb +++ b/app/controllers/projects/pipelines_controller.rb @@ -54,6 +54,6 @@ class Projects::PipelinesController < Projects::ApplicationController end def commit - @commit ||= @pipeline.commit_data + @commit ||= @pipeline.commit end end diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 5b264ecffc5..ca5a685dd11 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -37,22 +37,22 @@ module Ci end def git_author_name - commit_data.author_name if commit_data + commit.try(:author_name) end def git_author_email - commit_data.author_email if commit_data + commit.try(:author_email) end def git_commit_message - commit_data.message if commit_data + commit.try(:message) end def short_sha Ci::Pipeline.truncate_sha(sha) end - def commit_data + def commit @commit ||= project.commit(sha) rescue nil diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb index bb74ff2c5f6..e437e3417a8 100644 --- a/app/models/commit_status.rb +++ b/app/models/commit_status.rb @@ -8,6 +8,8 @@ class CommitStatus < ActiveRecord::Base belongs_to :pipeline, class_name: 'Ci::Pipeline', foreign_key: :commit_id, touch: true belongs_to :user + delegate :commit, to: :pipeline + validates :pipeline, presence: true, unless: :importing? validates_presence_of :name @@ -90,12 +92,4 @@ class CommitStatus < ActiveRecord::Base def stuck? false end - - ## - # Deprecated, this should be removed in 9.0 in favor of exposing - # entire pipeline in API. - # - def commit - pipeline.try(:commit_data) - end end diff --git a/app/views/projects/ci/pipelines/_pipeline.html.haml b/app/views/projects/ci/pipelines/_pipeline.html.haml index b8d8758fd2b..e38d1ff5ff0 100644 --- a/app/views/projects/ci/pipelines/_pipeline.html.haml +++ b/app/views/projects/ci/pipelines/_pipeline.html.haml @@ -24,8 +24,8 @@ %span.label.label-warning stuck %p.commit-title - - if commit_data = pipeline.commit_data - = link_to_gfm truncate(commit_data.title, length: 60), namespace_project_commit_path(@project.namespace, @project, commit_data.id), class: "commit-row-message" + - if commit = pipeline.commit + = link_to_gfm truncate(commit.title, length: 60), namespace_project_commit_path(@project.namespace, @project, commit.id), class: "commit-row-message" - else Cant find HEAD commit for this branch -- cgit v1.2.1 From ca696175dbbf664f25a87a300b99f2b97fa5db70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Rodr=C3=ADguez?= Date: Tue, 21 Jun 2016 10:53:16 -0400 Subject: Optimize Banzai::Filter::RelativeLinkFilter A lot of git operations were being repeated, for example, to build a url you would ask if the path was a Tree, which would call a recursive routine in Gitlab::Git::Tree#where, then ask if the path was a Blob, which would call a recursive routine at Gitlab::Git::Blob#find, making reference to the same git objects several times. Now we call Rugged::Tree#path, which allows us to determine the type of the path in one pass. Some other minor improvement added, like saving commonly used references instead of calculating them each time. --- CHANGELOG | 1 + app/models/commit.rb | 26 +++++++++++ lib/banzai/filter/relative_link_filter.rb | 51 ++++++---------------- .../lib/banzai/filter/relative_link_filter_spec.rb | 7 +-- spec/models/commit_spec.rb | 12 +++++ 5 files changed, 55 insertions(+), 42 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 3c80936468b..5a123d90670 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -8,6 +8,7 @@ v 8.9.0 (unreleased) - Bulk assign/unassign labels to issues. - Ability to prioritize labels !4009 / !3205 (Thijs Wouters) - Show Star and Fork buttons on mobile. + - Performance improvements on RelativeLinkFilter - Fix endless redirections when accessing user OAuth applications when they are disabled - Allow enabling wiki page events from Webhook management UI - Bump rouge to 1.11.0 diff --git a/app/models/commit.rb b/app/models/commit.rb index d69d518fadd..174ccbaea6c 100644 --- a/app/models/commit.rb +++ b/app/models/commit.rb @@ -271,6 +271,32 @@ class Commit merged_merge_request ? 'merge request' : 'commit' end + # Get the URI type of the given path + # + # Used to build URLs to files in the repository in GFM. + # + # path - String path to check + # + # Examples: + # + # uri_type('doc/README.md') # => :blob + # uri_type('doc/logo.png') # => :raw + # uri_type('doc/api') # => :tree + # uri_type('not/found') # => :nil + # + # Returns a symbol + def uri_type(path) + entry = @raw.tree.path(path) + if entry[:type] == :blob + blob = Gitlab::Git::Blob.new(name: entry[:name]) + blob.image? ? :raw : :blob + else + entry[:type] + end + rescue Rugged::TreeError + nil + end + private def repo_changes diff --git a/lib/banzai/filter/relative_link_filter.rb b/lib/banzai/filter/relative_link_filter.rb index ea21c7b041c..c78da404607 100644 --- a/lib/banzai/filter/relative_link_filter.rb +++ b/lib/banzai/filter/relative_link_filter.rb @@ -14,6 +14,8 @@ module Banzai def call return doc unless linkable_files? + @uri_types = {} + doc.search('a:not(.gfm)').each do |el| process_link_attr el.attribute('href') end @@ -48,7 +50,7 @@ module Banzai uri.path = [ relative_url_root, context[:project].path_with_namespace, - path_type(file_path), + uri_type(file_path), ref || context[:project].default_branch, # if no ref exists, point to the default branch file_path ].compact.join('/').squeeze('/').chomp('/') @@ -87,7 +89,7 @@ module Banzai return path unless request_path parts = request_path.split('/') - parts.pop if path_type(request_path) != 'tree' + parts.pop if uri_type(request_path) != :tree while path.start_with?('../') parts.pop @@ -98,45 +100,20 @@ module Banzai end def file_exists?(path) - return false if path.nil? - repository.blob_at(current_sha, path).present? || - repository.tree(current_sha, path).entries.any? - end - - # Get the type of the given path - # - # path - String path to check - # - # Examples: - # - # path_type('doc/README.md') # => 'blob' - # path_type('doc/logo.png') # => 'raw' - # path_type('doc/api') # => 'tree' - # - # Returns a String - def path_type(path) - unescaped_path = Addressable::URI.unescape(path) - - if tree?(unescaped_path) - 'tree' - elsif image?(unescaped_path) - 'raw' - else - 'blob' - end + path.present? && !!uri_type(path) end - def tree?(path) - repository.tree(current_sha, path).entries.any? - end + def uri_type(path) + @uri_types[path] ||= begin + unescaped_path = Addressable::URI.unescape(path) - def image?(path) - repository.blob_at(current_sha, path).try(:image?) + current_commit.uri_type(unescaped_path) + end end - def current_sha - context[:commit].try(:id) || - ref ? repository.commit(ref).try(:sha) : repository.head_commit.sha + def current_commit + @current_commit ||= context[:commit] || + ref ? repository.commit(ref) : repository.head_commit end def relative_url_root @@ -148,7 +125,7 @@ module Banzai end def repository - context[:project].try(:repository) + @repository ||= context[:project].try(:repository) end end end diff --git a/spec/lib/banzai/filter/relative_link_filter_spec.rb b/spec/lib/banzai/filter/relative_link_filter_spec.rb index 0e6685f0ffb..b9e4a4eaf0e 100644 --- a/spec/lib/banzai/filter/relative_link_filter_spec.rb +++ b/spec/lib/banzai/filter/relative_link_filter_spec.rb @@ -132,11 +132,8 @@ describe Banzai::Filter::RelativeLinkFilter, lib: true do path = 'files/images/한글.png' escaped = Addressable::URI.escape(path) - # Stub these methods so the file doesn't actually need to be in the repo - allow_any_instance_of(described_class). - to receive(:file_exists?).and_return(true) - allow_any_instance_of(described_class). - to receive(:image?).with(path).and_return(true) + # Stub this method so the file doesn't actually need to be in the repo + allow_any_instance_of(described_class).to receive(:uri_type).and_return(:raw) doc = filter(image(escaped)) expect(doc.at_css('img')['src']).to match '/raw/' diff --git a/spec/models/commit_spec.rb b/spec/models/commit_spec.rb index beca8708c9d..ba02d5fe977 100644 --- a/spec/models/commit_spec.rb +++ b/spec/models/commit_spec.rb @@ -207,4 +207,16 @@ eos expect(commit.participants).to include(note1.author, note2.author) end end + + describe '#uri_type' do + it 'returns the URI type at the given path' do + expect(commit.uri_type('files/html')).to be(:tree) + expect(commit.uri_type('files/images/logo-black.png')).to be(:raw) + expect(commit.uri_type('files/js/application.js')).to be(:blob) + end + + it "returns nil if the path doesn't exists" do + expect(commit.uri_type('this/path/doesnt/exist')).to be_nil + end + end end -- cgit v1.2.1 From 59fc1816d3df8f9ac27542eac46f93ae85e328ae Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Tue, 21 Jun 2016 07:54:02 -0700 Subject: Rename Repo -> Repository --- app/views/layouts/nav/_project.html.haml | 4 ++-- features/project/active_tab.feature | 30 ++++++++++++++--------------- features/project/shortcuts.feature | 6 +++--- features/steps/project/project_find_file.rb | 4 ++-- features/steps/shared/project_tab.rb | 4 ++-- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/app/views/layouts/nav/_project.html.haml b/app/views/layouts/nav/_project.html.haml index 068332205bb..c6f9cbc60e9 100644 --- a/app/views/layouts/nav/_project.html.haml +++ b/app/views/layouts/nav/_project.html.haml @@ -38,9 +38,9 @@ - if project_nav_tab? :files = nav_link(controller: %w(tree blob blame edit_tree new_tree find_file commit commits compare repositories tags branches releases network)) do - = link_to project_files_path(@project), title: 'Repo', class: 'shortcuts-tree' do + = link_to project_files_path(@project), title: 'Repository', class: 'shortcuts-tree' do %span - Repo + Repository - if project_nav_tab? :pipelines = nav_link(controller: [:pipelines, :builds, :environments]) do diff --git a/features/project/active_tab.feature b/features/project/active_tab.feature index db4507b9889..57dda9c2234 100644 --- a/features/project/active_tab.feature +++ b/features/project/active_tab.feature @@ -10,9 +10,9 @@ Feature: Project Active Tab Then the active main tab should be Home And no other main tabs should be active - Scenario: On Project Repo + Scenario: On Project Repository Given I visit my project's files page - Then the active main tab should be Repo + Then the active main tab should be Repository And no other main tabs should be active Scenario: On Project Issues @@ -59,46 +59,46 @@ Feature: Project Active Tab And no other sub navs should be active And the active main tab should be Settings - # Sub Tabs: Repo + # Sub Tabs: Repository - Scenario: On Project Repo/Files + Scenario: On Project Repository/Files Given I visit my project's files page Then the active sub tab should be Files And no other sub tabs should be active - And the active main tab should be Repo + And the active main tab should be Repository - Scenario: On Project Repo/Commits + Scenario: On Project Repository/Commits Given I visit my project's commits page Then the active sub tab should be Commits And no other sub tabs should be active - And the active main tab should be Repo + And the active main tab should be Repository - Scenario: On Project Repo/Network + Scenario: On Project Repository/Network Given I visit my project's network page Then the active sub tab should be Network And no other sub tabs should be active - And the active main tab should be Repo + And the active main tab should be Repository - Scenario: On Project Repo/Compare + Scenario: On Project Repository/Compare Given I visit my project's commits page And I click the "Compare" tab Then the active sub tab should be Compare And no other sub tabs should be active - And the active main tab should be Repo + And the active main tab should be Repository - Scenario: On Project Repo/Branches + Scenario: On Project Repository/Branches Given I visit my project's commits page And I click the "Branches" tab Then the active sub tab should be Branches And no other sub tabs should be active - And the active main tab should be Repo + And the active main tab should be Repository - Scenario: On Project Repo/Tags + Scenario: On Project Repository/Tags Given I visit my project's commits page And I click the "Tags" tab Then the active sub tab should be Tags And no other sub tabs should be active - And the active main tab should be Repo + And the active main tab should be Repository Scenario: On Project Issues/Browse Given I visit my project's issues page diff --git a/features/project/shortcuts.feature b/features/project/shortcuts.feature index aa5edaaa9d7..f71f69ef060 100644 --- a/features/project/shortcuts.feature +++ b/features/project/shortcuts.feature @@ -8,21 +8,21 @@ Feature: Project Shortcuts @javascript Scenario: Navigate to files tab Given I press "g" and "f" - Then the active main tab should be Repo + Then the active main tab should be Repository Then the active sub tab should be Files @javascript Scenario: Navigate to commits tab Given I visit my project's files page Given I press "g" and "c" - Then the active main tab should be Repo + Then the active main tab should be Repository Then the active sub tab should be Commits @javascript Scenario: Navigate to network tab Given I press "g" and "n" Then the active sub tab should be Network - And the active main tab should be Repo + And the active main tab should be Repository @javascript Scenario: Navigate to graphs tab diff --git a/features/steps/project/project_find_file.rb b/features/steps/project/project_find_file.rb index 9833eec3730..90771847909 100644 --- a/features/steps/project/project_find_file.rb +++ b/features/steps/project/project_find_file.rb @@ -13,12 +13,12 @@ class Spinach::Features::ProjectFindFile < Spinach::FeatureSteps end step 'I should see "find file" page' do - ensure_active_main_tab('Repo') + ensure_active_main_tab('Repository') expect(page).to have_selector('.file-finder-holder', count: 1) end step 'I fill in Find by path with "git"' do - ensure_active_main_tab('Repo') + ensure_active_main_tab('Repository') expect(page).to have_selector('.file-finder-holder', count: 1) end diff --git a/features/steps/shared/project_tab.rb b/features/steps/shared/project_tab.rb index 595913ff3d8..d6024212601 100644 --- a/features/steps/shared/project_tab.rb +++ b/features/steps/shared/project_tab.rb @@ -8,8 +8,8 @@ module SharedProjectTab ensure_active_main_tab('Project') end - step 'the active main tab should be Repo' do - ensure_active_main_tab('Repo') + step 'the active main tab should be Repository' do + ensure_active_main_tab('Repository') end step 'the active main tab should be Graphs' do -- cgit v1.2.1 From c89b0d9bf6a65175415ecd734f9053406aa69bca Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Tue, 21 Jun 2016 15:55:30 +0100 Subject: Fixed issue with navbar counts being misaligned Closes #18916 --- app/assets/stylesheets/framework/sidebar.scss | 1 - 1 file changed, 1 deletion(-) diff --git a/app/assets/stylesheets/framework/sidebar.scss b/app/assets/stylesheets/framework/sidebar.scss index a0bb3427af0..98f917ce69b 100644 --- a/app/assets/stylesheets/framework/sidebar.scss +++ b/app/assets/stylesheets/framework/sidebar.scss @@ -91,7 +91,6 @@ text-decoration: none; font-weight: normal; outline: none; - white-space: nowrap; &:hover, &:active, -- cgit v1.2.1 From d9a4ca5975b4fb91b147930d863f0bb4b9619a64 Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Tue, 21 Jun 2016 17:07:17 +0200 Subject: Move pre_process into render_result The method Banzai::Renderer.pre_process would always be called, regardless of whether the Markdown to render was already cached or not. In cache the document _was_ cached the output of the pre-processing pipeline was ignored resulting in it doing nothing but wasting CPU cycles. This commit moves Banzai::Renderer.pre_process into Banzai::Renderer.render_result so that it's _only_ used when needed. --- CHANGELOG | 1 + app/helpers/gitlab_markdown_helper.rb | 2 -- lib/banzai.rb | 4 ---- lib/banzai/renderer.rb | 8 ++------ 4 files changed, 3 insertions(+), 12 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index fde2b11d3c9..5790da35c1f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -14,6 +14,7 @@ v 8.9.0 (unreleased) - Fix issue with arrow keys not working in search autocomplete dropdown - Fix an issue where note polling stopped working if a window was in the background during a refresh. + - Pre-processing Markdown now only happens when needed - Make EmailsOnPushWorker use Sidekiq mailers queue - Redesign all Devise emails. !4297 - Don't show 'Leave Project' to group members diff --git a/app/helpers/gitlab_markdown_helper.rb b/app/helpers/gitlab_markdown_helper.rb index a0dafc52622..1a259656f31 100644 --- a/app/helpers/gitlab_markdown_helper.rb +++ b/app/helpers/gitlab_markdown_helper.rb @@ -50,8 +50,6 @@ module GitlabMarkdownHelper context[:project] ||= @project - text = Banzai.pre_process(text, context) - html = Banzai.render(text, context) context.merge!( diff --git a/lib/banzai.rb b/lib/banzai.rb index b467413a7dd..093382261ae 100644 --- a/lib/banzai.rb +++ b/lib/banzai.rb @@ -7,10 +7,6 @@ module Banzai Renderer.render_result(text, context) end - def self.pre_process(text, context) - Renderer.pre_process(text, context) - end - def self.post_process(html, context) Renderer.post_process(html, context) end diff --git a/lib/banzai/renderer.rb b/lib/banzai/renderer.rb index c14a9c4c722..6718acdef7e 100644 --- a/lib/banzai/renderer.rb +++ b/lib/banzai/renderer.rb @@ -30,13 +30,9 @@ module Banzai end def self.render_result(text, context = {}) - Pipeline[context[:pipeline]].call(text, context) - end + text = Pipeline[:pre_process].to_html(text, context) if text - def self.pre_process(text, context) - pipeline = Pipeline[:pre_process] - - pipeline.to_html(text, context) + Pipeline[context[:pipeline]].call(text, context) end # Perform post-processing on an HTML String -- cgit v1.2.1 From 4693b74801f9b473d270400b8954a90d389ddb54 Mon Sep 17 00:00:00 2001 From: Mark Pundsack Date: Tue, 21 Jun 2016 08:44:12 -0700 Subject: Clarify artifact expiry --- doc/ci/yaml/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md index d0fbcbe9988..179d6c867c1 100644 --- a/doc/ci/yaml/README.md +++ b/doc/ci/yaml/README.md @@ -724,8 +724,8 @@ time they are uploaded and stored on GitLab. You can use the **Keep** button on the build page to override expiration and keep artifacts forever. -By default, artifacts are deleted hourly (via a cron job), but they are not -accessible after expiry. +After expiry, artifacts are actually deleted hourly by default (via a cron job), +but they are not accessible after expiry. The value of `expire_in` is an elapsed time. Examples of parseable values: - '3 mins 4 sec' -- cgit v1.2.1 From c2d6981db4d6877821674357208ceed9a9a132c8 Mon Sep 17 00:00:00 2001 From: Alfredo Sumaran Date: Tue, 21 Jun 2016 11:02:53 -0500 Subject: Capitalize button text --- app/views/projects/show.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml index 5f041aedfc0..15f0d85194b 100644 --- a/app/views/projects/show.html.haml +++ b/app/views/projects/show.html.haml @@ -60,7 +60,7 @@ - unless @repository.gitlab_ci_yml %li.missing = link_to add_special_file_path(@project, file_name: '.gitlab-ci.yml') do - Set up CI + Set Up CI - if @repository.commit .content-block.second-block.white -- cgit v1.2.1 From 8e84153044059da618b6238da7b37fc627c3140d Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Wed, 15 Jun 2016 08:54:31 -0500 Subject: Style sub nav links in Graphs --- app/views/projects/graphs/_head.html.haml | 26 ++++---- app/views/projects/graphs/ci.html.haml | 25 ++++---- app/views/projects/graphs/commits.html.haml | 90 ++++++++++++++------------- app/views/projects/graphs/languages.html.haml | 36 ++++++----- app/views/projects/graphs/show.html.haml | 48 +++++++------- 5 files changed, 118 insertions(+), 107 deletions(-) diff --git a/app/views/projects/graphs/_head.html.haml b/app/views/projects/graphs/_head.html.haml index 8becaea246f..38af1459e8b 100644 --- a/app/views/projects/graphs/_head.html.haml +++ b/app/views/projects/graphs/_head.html.haml @@ -1,12 +1,14 @@ -- page_specific_javascripts asset_path("graphs/application.js") -%ul.nav-links - = nav_link(action: :show) do - = link_to 'Contributors', namespace_project_graph_path - = nav_link(action: :commits) do - = link_to 'Commits', commits_namespace_project_graph_path - = nav_link(action: :languages) do - = link_to 'Languages', languages_namespace_project_graph_path - - if @project.builds_enabled? - = nav_link(action: :ci) do - = link_to ci_namespace_project_graph_path do - Continuous Integration +%ul.nav-links.sub-nav + %div{ class: (container_class) } + + - page_specific_javascripts asset_path("graphs/application.js") + = nav_link(action: :show) do + = link_to 'Contributors', namespace_project_graph_path + = nav_link(action: :commits) do + = link_to 'Commits', commits_namespace_project_graph_path + = nav_link(action: :languages) do + = link_to 'Languages', languages_namespace_project_graph_path + - if @project.builds_enabled? + = nav_link(action: :ci) do + = link_to ci_namespace_project_graph_path do + Continuous Integration diff --git a/app/views/projects/graphs/ci.html.haml b/app/views/projects/graphs/ci.html.haml index 19ccc125ea8..6a40cff0e09 100644 --- a/app/views/projects/graphs/ci.html.haml +++ b/app/views/projects/graphs/ci.html.haml @@ -1,15 +1,18 @@ +- @no_container = true - page_title "Continuous Integration", "Graphs" = render 'head' -.row-content-block.append-bottom-default - .oneline - A collection of graphs for Continuous Integration -#charts.ci-charts - .row - .col-md-6 - = render 'projects/graphs/ci/overall' - .col-md-6 - = render 'projects/graphs/ci/build_times' +%div{ class: (container_class) } + .row-content-block.append-bottom-default + .oneline + A collection of graphs for Continuous Integration - %hr - = render 'projects/graphs/ci/builds' + #charts.ci-charts + .row + .col-md-6 + = render 'projects/graphs/ci/overall' + .col-md-6 + = render 'projects/graphs/ci/build_times' + + %hr + = render 'projects/graphs/ci/builds' diff --git a/app/views/projects/graphs/commits.html.haml b/app/views/projects/graphs/commits.html.haml index d9b2fb6c065..2b858c5e0f6 100644 --- a/app/views/projects/graphs/commits.html.haml +++ b/app/views/projects/graphs/commits.html.haml @@ -1,52 +1,54 @@ +- @no_container = true - page_title "Commits", "Graphs" = render 'head' -.row-content-block.append-bottom-default - .tree-ref-holder - = render 'shared/ref_switcher', destination: 'graphs_commits' - %ul.breadcrumb.repo-breadcrumb - = commits_breadcrumbs +%div{ class: (container_class) } + .row-content-block.append-bottom-default + .tree-ref-holder + = render 'shared/ref_switcher', destination: 'graphs_commits' + %ul.breadcrumb.repo-breadcrumb + = commits_breadcrumbs -%p.lead - Commit statistics for - %strong #{@ref} - #{@commits_graph.start_date.strftime('%b %d')} - #{@commits_graph.end_date.strftime('%b %d')} + %p.lead + Commit statistics for + %strong #{@ref} + #{@commits_graph.start_date.strftime('%b %d')} - #{@commits_graph.end_date.strftime('%b %d')} -.row - .col-md-6 - %ul - %li - %p.lead - %strong #{@commits_graph.commits.size} - commits during - %strong #{@commits_graph.duration} - days - %li - %p.lead - Average - %strong #{@commits_graph.commit_per_day} - commits per day - %li - %p.lead - Contributed by - %strong #{@commits_graph.authors} - authors - .col-md-6 - %div - %p.slead - Commits per day of month - %canvas#month-chart -.row - .col-md-6 - %div - %p.slead - Commits per day hour (UTC) - %canvas#hour-chart - .col-md-6 - %div - %p.slead - Commits per weekday - %canvas#weekday-chart + .row + .col-md-6 + %ul + %li + %p.lead + %strong #{@commits_graph.commits.size} + commits during + %strong #{@commits_graph.duration} + days + %li + %p.lead + Average + %strong #{@commits_graph.commit_per_day} + commits per day + %li + %p.lead + Contributed by + %strong #{@commits_graph.authors} + authors + .col-md-6 + %div + %p.slead + Commits per day of month + %canvas#month-chart + .row + .col-md-6 + %div + %p.slead + Commits per day hour (UTC) + %canvas#hour-chart + .col-md-6 + %div + %p.slead + Commits per weekday + %canvas#weekday-chart :javascript var responsiveChart = function (selector, data) { diff --git a/app/views/projects/graphs/languages.html.haml b/app/views/projects/graphs/languages.html.haml index 249c16f4709..415414a4ebb 100644 --- a/app/views/projects/graphs/languages.html.haml +++ b/app/views/projects/graphs/languages.html.haml @@ -1,24 +1,26 @@ +- @no_container = true - page_title "Languages", "Graphs" = render 'head' -.row-content-block.append-bottom-default - .oneline - Programming languages used in this repository +%div{ class: (container_class) } + .row-content-block.append-bottom-default + .oneline + Programming languages used in this repository -.row - .col-md-8 - %canvas#languages-chart{ height: 400 } - .col-md-4 - %ul.bordered-list - - @languages.each do |language| - %li - %span{ style: "color: #{language[:color]}" } - = icon('circle') -   - = language[:label] - .pull-right - = language[:value] - \% + .row + .col-md-8 + %canvas#languages-chart{ height: 400 } + .col-md-4 + %ul.bordered-list + - @languages.each do |language| + %li + %span{ style: "color: #{language[:color]}" } + = icon('circle') +   + = language[:label] + .pull-right + = language[:value] + \% :javascript var data = #{@languages.to_json}; diff --git a/app/views/projects/graphs/show.html.haml b/app/views/projects/graphs/show.html.haml index 33970e7b909..bdfde634f7c 100644 --- a/app/views/projects/graphs/show.html.haml +++ b/app/views/projects/graphs/show.html.haml @@ -1,29 +1,31 @@ +- @no_container = true - page_title "Contributors", "Graphs" = render 'head' -.row-content-block.append-bottom-default - .tree-ref-holder - = render 'shared/ref_switcher', destination: 'graphs' - %ul.breadcrumb.repo-breadcrumb - = commits_breadcrumbs - -.loading-graph - .center - %h3.page-title - %i.fa.fa-spinner.fa-spin - Building repository graph. - %p.slead Please wait a moment, this page will automatically refresh when ready. - -.stat-graph.hide - .header.clearfix - %h3#date_header.page-title - %p.light - Commits to #{@ref}, excluding merge commits. Limited to 6,000 commits. - %input#brush_change{:type => "hidden"} - .graphs - #contributors-master - #contributors.clearfix - %ol.contributors-list.clearfix +%div{ class: (container_class) } + .row-content-block.append-bottom-default + .tree-ref-holder + = render 'shared/ref_switcher', destination: 'graphs' + %ul.breadcrumb.repo-breadcrumb + = commits_breadcrumbs + + .loading-graph + .center + %h3.page-title + %i.fa.fa-spinner.fa-spin + Building repository graph. + %p.slead Please wait a moment, this page will automatically refresh when ready. + + .stat-graph.hide + .header.clearfix + %h3#date_header.page-title + %p.light + Commits to #{@ref}, excluding merge commits. Limited to 6,000 commits. + %input#brush_change{:type => "hidden"} + .graphs + #contributors-master + #contributors.clearfix + %ol.contributors-list.clearfix -- cgit v1.2.1 From a4c9b4fbe9cc6e0e91d43137db71d8d15d22e09a Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Wed, 15 Jun 2016 09:31:41 -0500 Subject: Style wiki sub nav links --- app/views/projects/graphs/_head.html.haml | 4 +-- app/views/projects/wikis/_nav.html.haml | 12 +++---- app/views/projects/wikis/_new.html.haml | 31 ++++++++-------- app/views/projects/wikis/edit.html.haml | 28 ++++++++------- app/views/projects/wikis/git_access.html.haml | 52 ++++++++++++++------------- app/views/projects/wikis/pages.html.haml | 18 +++++----- app/views/projects/wikis/show.html.haml | 34 +++++++++--------- 7 files changed, 95 insertions(+), 84 deletions(-) diff --git a/app/views/projects/graphs/_head.html.haml b/app/views/projects/graphs/_head.html.haml index 38af1459e8b..a388d9a0a61 100644 --- a/app/views/projects/graphs/_head.html.haml +++ b/app/views/projects/graphs/_head.html.haml @@ -1,5 +1,5 @@ -%ul.nav-links.sub-nav - %div{ class: (container_class) } +.nav-links.sub-nav + %ul{ class: (container_class) } - page_specific_javascripts asset_path("graphs/application.js") = nav_link(action: :show) do diff --git a/app/views/projects/wikis/_nav.html.haml b/app/views/projects/wikis/_nav.html.haml index 988fe024e28..f82c0fc0aff 100644 --- a/app/views/projects/wikis/_nav.html.haml +++ b/app/views/projects/wikis/_nav.html.haml @@ -1,5 +1,5 @@ -.top-area - %ul.nav-links +.nav-links.sub-nav + %ul{ class: (container_class) } = nav_link(html_options: {class: params[:id] == 'home' ? 'active' : '' }) do = link_to 'Home', namespace_project_wiki_path(@project.namespace, @project, :home) @@ -10,9 +10,9 @@ = link_to namespace_project_wikis_git_access_path(@project.namespace, @project) do Git Access - .nav-controls - if can?(current_user, :create_wiki, @project) - = link_to '#modal-new-wiki', class: "add-new-wiki btn btn-new", "data-toggle" => "modal" do - New Page + = nav_link do + = link_to '#modal-new-wiki', "data-toggle" => "modal" do + New Page -= render 'projects/wikis/new' + = render 'projects/wikis/new' diff --git a/app/views/projects/wikis/_new.html.haml b/app/views/projects/wikis/_new.html.haml index 919daf0a7b2..4f8abcdc8e1 100644 --- a/app/views/projects/wikis/_new.html.haml +++ b/app/views/projects/wikis/_new.html.haml @@ -1,14 +1,17 @@ -%div#modal-new-wiki.modal - .modal-dialog - .modal-content - .modal-header - %a.close{href: "#", "data-dismiss" => "modal"} × - %h3.page-title New Wiki Page - .modal-body - %form.new-wiki-page - .form-group - = label_tag :new_wiki_path do - %span Page slug - = text_field_tag :new_wiki_path, nil, placeholder: 'how-to-setup', class: 'form-control', required: true, :'data-wikis-path' => namespace_project_wikis_path(@project.namespace, @project), autofocus: true - .form-actions - = button_tag 'Create Page', class: 'build-new-wiki btn btn-create' +- @no_container = true + +%div{ class: (container_class) } + %div#modal-new-wiki.modal + .modal-dialog + .modal-content + .modal-header + %a.close{href: "#", "data-dismiss" => "modal"} × + %h3.page-title New Wiki Page + .modal-body + %form.new-wiki-page + .form-group + = label_tag :new_wiki_path do + %span Page slug + = text_field_tag :new_wiki_path, nil, placeholder: 'how-to-setup', class: 'form-control', required: true, :'data-wikis-path' => namespace_project_wikis_path(@project.namespace, @project), autofocus: true + .form-actions + = button_tag 'Create Page', class: 'build-new-wiki btn btn-create' diff --git a/app/views/projects/wikis/edit.html.haml b/app/views/projects/wikis/edit.html.haml index cbd69ee1a73..81cb709d053 100644 --- a/app/views/projects/wikis/edit.html.haml +++ b/app/views/projects/wikis/edit.html.haml @@ -1,19 +1,21 @@ +- @no_container = true - page_title "Edit", @page.title.capitalize, "Wiki" = render 'nav' -.top-area - .nav-text.wiki-page - %strong - - if @page.persisted? - = link_to @page.title.capitalize, namespace_project_wiki_path(@project.namespace, @project, @page) - - else - = @page.title.capitalize - %span.light - · - Edit Page +%div{ class: (container_class) } + .top-area + .nav-text.wiki-page + %strong + - if @page.persisted? + = link_to @page.title.capitalize, namespace_project_wiki_path(@project.namespace, @project, @page) + - else + = @page.title.capitalize + %span.light + · + Edit Page - .nav-controls - = render 'main_links' + .nav-controls + = render 'main_links' -= render 'form' + = render 'form' diff --git a/app/views/projects/wikis/git_access.html.haml b/app/views/projects/wikis/git_access.html.haml index ccceab6155e..e129df16123 100644 --- a/app/views/projects/wikis/git_access.html.haml +++ b/app/views/projects/wikis/git_access.html.haml @@ -1,32 +1,34 @@ +- @no_container = true - page_title "Git Access", "Wiki" = render 'nav' -.row-content-block - %span.oneline - Git access for - %strong= @project_wiki.path_with_namespace +%div{ class: (container_class) } + .row-content-block + %span.oneline + Git access for + %strong= @project_wiki.path_with_namespace - .pull-right - = render "shared/clone_panel", project: @project_wiki + .pull-right + = render "shared/clone_panel", project: @project_wiki -.git-empty.prepend-top-default - %fieldset - %legend Install Gollum: - %pre.dark - :preserve - gem install gollum + .git-empty.prepend-top-default + %fieldset + %legend Install Gollum: + %pre.dark + :preserve + gem install gollum - %legend Clone Your Wiki: - %pre.dark - :preserve - git clone #{ content_tag(:span, default_url_to_repo(@project_wiki), class: 'clone')} - cd #{h @project_wiki.path} + %legend Clone Your Wiki: + %pre.dark + :preserve + git clone #{ content_tag(:span, default_url_to_repo(@project_wiki), class: 'clone')} + cd #{h @project_wiki.path} - %legend Start Gollum And Edit Locally: - %pre.dark - :preserve - gollum - == Sinatra/1.3.5 has taken the stage on 4567 for development with backup from Thin - >> Thin web server (v1.5.0 codename Knife) - >> Maximum connections set to 1024 - >> Listening on 0.0.0.0:4567, CTRL+C to stop + %legend Start Gollum And Edit Locally: + %pre.dark + :preserve + gollum + == Sinatra/1.3.5 has taken the stage on 4567 for development with backup from Thin + >> Thin web server (v1.5.0 codename Knife) + >> Maximum connections set to 1024 + >> Listening on 0.0.0.0:4567, CTRL+C to stop diff --git a/app/views/projects/wikis/pages.html.haml b/app/views/projects/wikis/pages.html.haml index 2f6162fa3c5..81d9f391c1c 100644 --- a/app/views/projects/wikis/pages.html.haml +++ b/app/views/projects/wikis/pages.html.haml @@ -1,12 +1,14 @@ +- @no_container = true - page_title "Pages", "Wiki" = render 'nav' -%ul.content-list - - @wiki_pages.each do |wiki_page| - %li - = link_to wiki_page.title, namespace_project_wiki_path(@project.namespace, @project, wiki_page) - %small (#{wiki_page.format}) - .pull-right - %small Last edited #{time_ago_with_tooltip(wiki_page.commit.authored_date)} -= paginate @wiki_pages, theme: 'gitlab' +%div{ class: (container_class) } + %ul.content-list + - @wiki_pages.each do |wiki_page| + %li + = link_to wiki_page.title, namespace_project_wiki_path(@project.namespace, @project, wiki_page) + %small (#{wiki_page.format}) + .pull-right + %small Last edited #{time_ago_with_tooltip(wiki_page.commit.authored_date)} + = paginate @wiki_pages, theme: 'gitlab' diff --git a/app/views/projects/wikis/show.html.haml b/app/views/projects/wikis/show.html.haml index 9166c0edb3b..76f9b1ecd76 100644 --- a/app/views/projects/wikis/show.html.haml +++ b/app/views/projects/wikis/show.html.haml @@ -1,24 +1,26 @@ +- @no_container = true - page_title @page.title.capitalize, "Wiki" = render 'nav' -.top-area - .nav-text - %strong= @page.title.capitalize +%div{ class: (container_class) } + .top-area + .nav-text + %strong= @page.title.capitalize - %span.wiki-last-edit-by - · - last edited by #{@page.commit.author.name} #{time_ago_with_tooltip(@page.commit.authored_date)} + %span.wiki-last-edit-by + · + last edited by #{@page.commit.author.name} #{time_ago_with_tooltip(@page.commit.authored_date)} - .nav-controls - = render 'main_links' + .nav-controls + = render 'main_links' -- if @page.historical? - .warning_message - This is an old version of this page. - You can view the #{link_to "most recent version", namespace_project_wiki_path(@project.namespace, @project, @page)} or browse the #{link_to "history", namespace_project_wiki_history_path(@project.namespace, @project, @page)}. + - if @page.historical? + .warning_message + This is an old version of this page. + You can view the #{link_to "most recent version", namespace_project_wiki_path(@project.namespace, @project, @page)} or browse the #{link_to "history", namespace_project_wiki_history_path(@project.namespace, @project, @page)}. -.wiki-holder.prepend-top-default.append-bottom-default - .wiki - = preserve do - = render_wiki_content(@page) + .wiki-holder.prepend-top-default.append-bottom-default + .wiki + = preserve do + = render_wiki_content(@page) -- cgit v1.2.1 From 596b2f46c835e76748a3026ea080323406ad461c Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Wed, 15 Jun 2016 09:37:36 -0500 Subject: Update CHANGELOG --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 0c3aadc29d1..19edf7c75f9 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -148,6 +148,7 @@ v 8.9.0 (unreleased) - Ensure Todos counters doesn't count Todos for projects pending delete - Add left/right arrows horizontal navigation - Add tooltip to pin/unpin navbar + - Add new sub nav style to Wiki and Graphs sub navigation v 8.8.5 - Import GitHub repositories respecting the API rate limit !4166 -- cgit v1.2.1 From a02c3d09d3670c7b7543461bf4d3c4d5fc08f418 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Wed, 15 Jun 2016 12:01:58 -0500 Subject: Fix graph columns --- app/assets/stylesheets/pages/stat_graph.scss | 17 +++++++++++++---- app/views/projects/graphs/show.html.haml | 2 +- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/app/assets/stylesheets/pages/stat_graph.scss b/app/assets/stylesheets/pages/stat_graph.scss index 85a0304196c..4adf6193b8a 100644 --- a/app/assets/stylesheets/pages/stat_graph.scss +++ b/app/assets/stylesheets/pages/stat_graph.scss @@ -14,18 +14,27 @@ font-size: 10px; } +#contributors-master { + @include make-md-column(12); + + svg { + width: 100%; + } +} + #contributors { .contributors-list { margin: 0 0 10px; list-style: none; padding: 0; + + svg { + width: 100%; + } } .person { - &:nth-child(even) { - float: right; - } - float: left; + @include make-md-column(6); margin-top: 10px; } diff --git a/app/views/projects/graphs/show.html.haml b/app/views/projects/graphs/show.html.haml index bdfde634f7c..61706c1d0fe 100644 --- a/app/views/projects/graphs/show.html.haml +++ b/app/views/projects/graphs/show.html.haml @@ -22,7 +22,7 @@ %p.light Commits to #{@ref}, excluding merge commits. Limited to 6,000 commits. %input#brush_change{:type => "hidden"} - .graphs + .graphs.row #contributors-master #contributors.clearfix %ol.contributors-list.clearfix -- cgit v1.2.1 From 6f642fd423f32a05711e8cf97d79b57cd6e489f3 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Thu, 16 Jun 2016 09:09:58 -0500 Subject: Add new style for sub header block info --- app/assets/stylesheets/framework/blocks.scss | 11 +++++++++++ app/assets/stylesheets/framework/nav.scss | 4 ---- app/views/projects/graphs/ci.html.haml | 2 +- app/views/projects/graphs/commits.html.haml | 2 +- app/views/projects/graphs/languages.html.haml | 2 +- app/views/projects/graphs/show.html.haml | 2 +- app/views/projects/wikis/edit.html.haml | 2 +- app/views/projects/wikis/git_access.html.haml | 4 ++-- 8 files changed, 18 insertions(+), 11 deletions(-) diff --git a/app/assets/stylesheets/framework/blocks.scss b/app/assets/stylesheets/framework/blocks.scss index d5fe5bc2ef1..7626ac41e50 100644 --- a/app/assets/stylesheets/framework/blocks.scss +++ b/app/assets/stylesheets/framework/blocks.scss @@ -97,6 +97,17 @@ } } +.sub-header-block { + background-color: $white-light; + border-bottom: 1px solid $white-dark; + margin: 11px 0; + padding-bottom: 11px; + + .oneline { + line-height: 35px; + } +} + .cover-block { text-align: center; background: $background-color; diff --git a/app/assets/stylesheets/framework/nav.scss b/app/assets/stylesheets/framework/nav.scss index 694f09c0464..0281b06d3ba 100644 --- a/app/assets/stylesheets/framework/nav.scss +++ b/app/assets/stylesheets/framework/nav.scss @@ -111,10 +111,6 @@ width: 50%; line-height: 28px; - &.wiki-page { - padding: 16px 10px 11px; - } - /* Small devices (phones, tablets, 768px and lower) */ @media (max-width: $screen-sm-min) { width: 100%; diff --git a/app/views/projects/graphs/ci.html.haml b/app/views/projects/graphs/ci.html.haml index 6a40cff0e09..e695d3ae369 100644 --- a/app/views/projects/graphs/ci.html.haml +++ b/app/views/projects/graphs/ci.html.haml @@ -3,7 +3,7 @@ = render 'head' %div{ class: (container_class) } - .row-content-block.append-bottom-default + .sub-header-block .oneline A collection of graphs for Continuous Integration diff --git a/app/views/projects/graphs/commits.html.haml b/app/views/projects/graphs/commits.html.haml index 2b858c5e0f6..0daffe68f6f 100644 --- a/app/views/projects/graphs/commits.html.haml +++ b/app/views/projects/graphs/commits.html.haml @@ -3,7 +3,7 @@ = render 'head' %div{ class: (container_class) } - .row-content-block.append-bottom-default + .sub-header-block .tree-ref-holder = render 'shared/ref_switcher', destination: 'graphs_commits' %ul.breadcrumb.repo-breadcrumb diff --git a/app/views/projects/graphs/languages.html.haml b/app/views/projects/graphs/languages.html.haml index 415414a4ebb..6d97f552a8e 100644 --- a/app/views/projects/graphs/languages.html.haml +++ b/app/views/projects/graphs/languages.html.haml @@ -3,7 +3,7 @@ = render 'head' %div{ class: (container_class) } - .row-content-block.append-bottom-default + .sub-header-block .oneline Programming languages used in this repository diff --git a/app/views/projects/graphs/show.html.haml b/app/views/projects/graphs/show.html.haml index 61706c1d0fe..9f7e2a361ff 100644 --- a/app/views/projects/graphs/show.html.haml +++ b/app/views/projects/graphs/show.html.haml @@ -3,7 +3,7 @@ = render 'head' %div{ class: (container_class) } - .row-content-block.append-bottom-default + .sub-header-block .tree-ref-holder = render 'shared/ref_switcher', destination: 'graphs' %ul.breadcrumb.repo-breadcrumb diff --git a/app/views/projects/wikis/edit.html.haml b/app/views/projects/wikis/edit.html.haml index 81cb709d053..af9d23bbfb3 100644 --- a/app/views/projects/wikis/edit.html.haml +++ b/app/views/projects/wikis/edit.html.haml @@ -4,7 +4,7 @@ %div{ class: (container_class) } .top-area - .nav-text.wiki-page + .nav-text %strong - if @page.persisted? = link_to @page.title.capitalize, namespace_project_wiki_path(@project.namespace, @project, @page) diff --git a/app/views/projects/wikis/git_access.html.haml b/app/views/projects/wikis/git_access.html.haml index e129df16123..6caf7230f35 100644 --- a/app/views/projects/wikis/git_access.html.haml +++ b/app/views/projects/wikis/git_access.html.haml @@ -3,7 +3,7 @@ = render 'nav' %div{ class: (container_class) } - .row-content-block + .sub-header-block %span.oneline Git access for %strong= @project_wiki.path_with_namespace @@ -11,7 +11,7 @@ .pull-right = render "shared/clone_panel", project: @project_wiki - .git-empty.prepend-top-default + .prepend-top-default %fieldset %legend Install Gollum: %pre.dark -- cgit v1.2.1 From 1d7b809a01fcd4479191443598c364c367f17545 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Thu, 16 Jun 2016 09:57:42 -0500 Subject: Move new page link out of sub nav --- app/assets/stylesheets/framework/blocks.scss | 4 ++-- app/views/projects/wikis/_main_links.html.haml | 3 +++ app/views/projects/wikis/_nav.html.haml | 5 ----- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/app/assets/stylesheets/framework/blocks.scss b/app/assets/stylesheets/framework/blocks.scss index 7626ac41e50..4e0a788123d 100644 --- a/app/assets/stylesheets/framework/blocks.scss +++ b/app/assets/stylesheets/framework/blocks.scss @@ -100,8 +100,8 @@ .sub-header-block { background-color: $white-light; border-bottom: 1px solid $white-dark; - margin: 11px 0; - padding-bottom: 11px; + padding: 11px 0; + margin-bottom: 11px; .oneline { line-height: 35px; diff --git a/app/views/projects/wikis/_main_links.html.haml b/app/views/projects/wikis/_main_links.html.haml index 4faa547769b..4ea75dbbf0c 100644 --- a/app/views/projects/wikis/_main_links.html.haml +++ b/app/views/projects/wikis/_main_links.html.haml @@ -1,4 +1,7 @@ - if (@page && @page.persisted?) + - if can?(current_user, :create_wiki, @project) + = link_to '#modal-new-wiki', class: "add-new-wiki btn btn-new", "data-toggle" => "modal" do + New Page = link_to namespace_project_wiki_history_path(@project.namespace, @project, @page), class: "btn" do Page History - if can?(current_user, :create_wiki, @project) diff --git a/app/views/projects/wikis/_nav.html.haml b/app/views/projects/wikis/_nav.html.haml index f82c0fc0aff..f8ea479e0b1 100644 --- a/app/views/projects/wikis/_nav.html.haml +++ b/app/views/projects/wikis/_nav.html.haml @@ -10,9 +10,4 @@ = link_to namespace_project_wikis_git_access_path(@project.namespace, @project) do Git Access - - if can?(current_user, :create_wiki, @project) - = nav_link do - = link_to '#modal-new-wiki', "data-toggle" => "modal" do - New Page - = render 'projects/wikis/new' -- cgit v1.2.1 From 25ae737df0d8e3af9d40b60896ecb906237142ac Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Thu, 16 Jun 2016 12:21:23 -0500 Subject: Add new page button to wiki home --- app/views/projects/wikis/edit.html.haml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/views/projects/wikis/edit.html.haml b/app/views/projects/wikis/edit.html.haml index af9d23bbfb3..bf5d09d50c2 100644 --- a/app/views/projects/wikis/edit.html.haml +++ b/app/views/projects/wikis/edit.html.haml @@ -15,6 +15,9 @@ Edit Page .nav-controls + - if can?(current_user, :create_wiki, @project) + = link_to '#modal-new-wiki', class: "add-new-wiki btn btn-new", "data-toggle" => "modal" do + New Page = render 'main_links' -- cgit v1.2.1 From 1f7353ce38c2bcc957d10c35aadc4197668cc7f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Tue, 21 Jun 2016 18:25:44 +0200 Subject: Fix specs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémy Coutable --- features/admin/groups.feature | 7 ------- features/steps/admin/groups.rb | 8 +------- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/features/admin/groups.feature b/features/admin/groups.feature index ab7de7ac315..657e847cf4a 100644 --- a/features/admin/groups.feature +++ b/features/admin/groups.feature @@ -26,13 +26,6 @@ Feature: Admin Groups When I visit group page Then I should see project shared with group - @javascript - Scenario: Remove user from group - Given we have user "John Doe" in group - When I visit admin group page - And I remove user "John Doe" from group - Then I should not see "John Doe" in team list - @javascript Scenario: Invite user to a group by e-mail When I visit admin group page diff --git a/features/steps/admin/groups.rb b/features/steps/admin/groups.rb index e1f1db2872f..8613dc537cc 100644 --- a/features/steps/admin/groups.rb +++ b/features/steps/admin/groups.rb @@ -62,7 +62,7 @@ class Spinach::Features::AdminGroups < Spinach::FeatureSteps step 'I should see "johndoe@gitlab.com" in team list in every project as "Reporter"' do page.within ".group-users-list" do - expect(page).to have_content "johndoe@gitlab.com (invited)" + expect(page).to have_content "johndoe@gitlab.com – Invited by" expect(page).to have_content "Reporter" end end @@ -92,12 +92,6 @@ class Spinach::Features::AdminGroups < Spinach::FeatureSteps current_group.add_reporter(user_john) end - step 'I remove user "John Doe" from group' do - page.within "#user_#{user_john.id}" do - click_link 'Remove user from group' - end - end - step 'I should not see "John Doe" in team list' do page.within ".group-users-list" do expect(page).not_to have_content "John Doe" -- cgit v1.2.1 From 835e3b0ac66aa24e1e087c1cf87308efd2d22527 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Tue, 21 Jun 2016 16:47:29 +0000 Subject: Update mail_room to 0.8.0 to resolve #13357 Which includes the fix from: https://github.com/tpitale/mail_room/pull/73 --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index bc1223e1bbc..50a47bfd984 100644 --- a/Gemfile +++ b/Gemfile @@ -330,7 +330,7 @@ gem "newrelic_rpm", '~> 3.14' gem 'octokit', '~> 4.3.0' -gem "mail_room", "~> 0.7" +gem "mail_room", "~> 0.8" gem 'email_reply_parser', '~> 0.5.8' diff --git a/Gemfile.lock b/Gemfile.lock index 49e548fb94f..d20514e79e4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -398,7 +398,7 @@ GEM systemu (~> 2.6.2) mail (2.6.4) mime-types (>= 1.16, < 4) - mail_room (0.7.0) + mail_room (0.8.0) method_source (0.8.2) mime-types (2.99.2) mimemagic (0.3.0) @@ -899,7 +899,7 @@ DEPENDENCIES license_finder licensee (~> 8.0.0) loofah (~> 2.0.3) - mail_room (~> 0.7) + mail_room (~> 0.8) method_source (~> 0.8) minitest (~> 5.7.0) mousetrap-rails (~> 1.4.6) -- cgit v1.2.1 From cd28597c82f415dd1f106477492467bb9ade3ecc Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Tue, 22 Mar 2016 19:32:35 +0200 Subject: Refactor labels docs [ci skip] --- .../img/labels_assign_label_in_new_issue.png | Bin 0 -> 26380 bytes doc/workflow/img/labels_assign_label_sidebar.png | Bin 0 -> 30137 bytes .../img/labels_assign_label_sidebar_saved.png | Bin 0 -> 25488 bytes doc/workflow/img/labels_default.png | Bin 0 -> 58717 bytes doc/workflow/img/labels_description_tooltip.png | Bin 0 -> 39315 bytes doc/workflow/img/labels_filter.png | Bin 0 -> 86911 bytes doc/workflow/img/labels_generate.png | Bin 0 -> 29986 bytes doc/workflow/img/labels_new_label.png | Bin 0 -> 29671 bytes doc/workflow/img/labels_new_label_on_the_fly.png | Bin 0 -> 11586 bytes .../img/labels_new_label_on_the_fly_create.png | Bin 0 -> 20604 bytes doc/workflow/img/labels_subscribe.png | Bin 0 -> 50177 bytes doc/workflow/labels.md | 110 +++++++++++++++++++-- 12 files changed, 101 insertions(+), 9 deletions(-) create mode 100644 doc/workflow/img/labels_assign_label_in_new_issue.png create mode 100644 doc/workflow/img/labels_assign_label_sidebar.png create mode 100644 doc/workflow/img/labels_assign_label_sidebar_saved.png create mode 100644 doc/workflow/img/labels_default.png create mode 100644 doc/workflow/img/labels_description_tooltip.png create mode 100644 doc/workflow/img/labels_filter.png create mode 100644 doc/workflow/img/labels_generate.png create mode 100644 doc/workflow/img/labels_new_label.png create mode 100644 doc/workflow/img/labels_new_label_on_the_fly.png create mode 100644 doc/workflow/img/labels_new_label_on_the_fly_create.png create mode 100644 doc/workflow/img/labels_subscribe.png diff --git a/doc/workflow/img/labels_assign_label_in_new_issue.png b/doc/workflow/img/labels_assign_label_in_new_issue.png new file mode 100644 index 00000000000..72bbf9a0594 Binary files /dev/null and b/doc/workflow/img/labels_assign_label_in_new_issue.png differ diff --git a/doc/workflow/img/labels_assign_label_sidebar.png b/doc/workflow/img/labels_assign_label_sidebar.png new file mode 100644 index 00000000000..ffbbf5b8d21 Binary files /dev/null and b/doc/workflow/img/labels_assign_label_sidebar.png differ diff --git a/doc/workflow/img/labels_assign_label_sidebar_saved.png b/doc/workflow/img/labels_assign_label_sidebar_saved.png new file mode 100644 index 00000000000..2771b02735f Binary files /dev/null and b/doc/workflow/img/labels_assign_label_sidebar_saved.png differ diff --git a/doc/workflow/img/labels_default.png b/doc/workflow/img/labels_default.png new file mode 100644 index 00000000000..2d44eb4409b Binary files /dev/null and b/doc/workflow/img/labels_default.png differ diff --git a/doc/workflow/img/labels_description_tooltip.png b/doc/workflow/img/labels_description_tooltip.png new file mode 100644 index 00000000000..887ef5f43a8 Binary files /dev/null and b/doc/workflow/img/labels_description_tooltip.png differ diff --git a/doc/workflow/img/labels_filter.png b/doc/workflow/img/labels_filter.png new file mode 100644 index 00000000000..139b3b22e14 Binary files /dev/null and b/doc/workflow/img/labels_filter.png differ diff --git a/doc/workflow/img/labels_generate.png b/doc/workflow/img/labels_generate.png new file mode 100644 index 00000000000..78eff8525bf Binary files /dev/null and b/doc/workflow/img/labels_generate.png differ diff --git a/doc/workflow/img/labels_new_label.png b/doc/workflow/img/labels_new_label.png new file mode 100644 index 00000000000..6dc4fe8ce20 Binary files /dev/null and b/doc/workflow/img/labels_new_label.png differ diff --git a/doc/workflow/img/labels_new_label_on_the_fly.png b/doc/workflow/img/labels_new_label_on_the_fly.png new file mode 100644 index 00000000000..4559c56dbda Binary files /dev/null and b/doc/workflow/img/labels_new_label_on_the_fly.png differ diff --git a/doc/workflow/img/labels_new_label_on_the_fly_create.png b/doc/workflow/img/labels_new_label_on_the_fly_create.png new file mode 100644 index 00000000000..ee75bc6ec92 Binary files /dev/null and b/doc/workflow/img/labels_new_label_on_the_fly_create.png differ diff --git a/doc/workflow/img/labels_subscribe.png b/doc/workflow/img/labels_subscribe.png new file mode 100644 index 00000000000..f3c1a1b67e2 Binary files /dev/null and b/doc/workflow/img/labels_subscribe.png differ diff --git a/doc/workflow/labels.md b/doc/workflow/labels.md index 6e4840ca5ae..35d62573c51 100644 --- a/doc/workflow/labels.md +++ b/doc/workflow/labels.md @@ -1,18 +1,110 @@ # Labels -In GitLab, you can easily tag issues and Merge Requests. If you have permission level `Developer` or higher, you can manage labels. To create, edit or delete a label, go to a project and then to `Issues` and then `Labels`. +Labels provide an easy way to categorize the issues or merge requests based on +descriptive titles like `bug`, `documentation` or any other text you feel like +it. They can have different colors, a description, and are visible throughout +the issue tracker or inside each issue individually. -Here you can create a new label. +With labels, you can navigate the issue tracker and filter any bloated +information to visualize only the issues you are interested in. Let's see how +that works. -![new label](labels/label1.png) +## Create new labels -You can choose to set a color. +>**Note:** +A permission level of `Developer` or higher is required in order to manage +labels. -![label color](labels/label2.png) +Head over a single project and navigate to the label page by clicking on +**Labels** in the left sidebar. -If you want to change an existing label, press edit next to the listed label. -You will be presented with the same form as when creating a new label. +The first time you visit the **Labels** page you'll notice that there are no +labels created yet. -![edit label](labels/label3.png) +![Generate new labels](img/labels_generate.png) -You can add labels to Merge Requests when you create or edit them. +--- + +You can skip that and create a new label or click that link and GitLab will +generate a set of predefined labels for you. There 8 default generated labels +in total and you can see them in the screenshot below. + +![Default generated labels](img/labels_default.png) + +--- + +You can see that from the labels page you can have an overview of the number of +issues and merge requests assigned to each label. + +Creating a new label from scratch is as easy as pressing the **New label** +button. From there on you can choose the name, give it an optional description, +a color and you are set. + +When you are ready press the **Create label** button to create the new label. + +![New label](img/labels_new_label.png) + +## Create a new label right from the issue tracker + +>**Note:** +This feature was introduced in GitLab 8.6. + +There are times when you are already in the issue tracker searching for a +label, only to realize it doesn't exist. Instead of going to the **Labels** +page and being distracted from your original purpose, you can create new +labels on the fly. + +Just hit **New Label** from the dropdown list, provide a name, pick a color +and hit **Create**. + +![Create new label on the fly](img/labels_new_label_on_the_fly_create.png) +![New label on the fly](img/labels_new_label_on_the_fly.png) + +## Assigning labels to issues and merge requests + +There are generally two ways to assign a label to an issue or merge request. + +--- + +You can assign a label when you first create or edit an issue or merge request. + +![Assign label in new issue](img/labels_assign_label_in_new_issue.png) + +--- + +The second way is by using the right sidebar. Expand it and hit **Edit**. Start +typing the name of the label you are looking for to narrow down the list and +select it. Once done, click outside the sidebar area for the changes to take +effect. + +![Assign label in sidebar](img/labels_assign_label_sidebar.png) +![Save labels in sidebar](img/labels_assign_label_sidebar_saved.png) + +--- + +To remove labels, follow the same procedure like when adding them and hit the +little **x** mark next to each one. + +## Use labels to filter issues + +Once you start adding labels to your issues, you'll see the benefit of it. +Labels can have several uses, one of them being the quick filtering of issues +or merge requests. + +Pick an existing label from the dropdown _Label_ menu or click on an existing +label from the issue tracker. In the latter case, you also get to see the +label description like shown below. + +![Filter labels](img/labels_filter.png) + +## Subscribe to labels + +If you don’t want to miss issues or merge requests that are important to you, +simply subscribe to a label. You’ll get notified whenever the label gets added +to an issue or merge request, making sure you don’t miss a thing. + +![Subscribe to labels](img/labels_subscribe.png) + +If you work on a large or popular project, try subscribing only to the labels +that are relevant to you. You’ll notice it’ll be much easier to focus on what’s +important. -- cgit v1.2.1 From 67d6d964299972e1fc8adc062fa7aed2c3fd6512 Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Tue, 22 Mar 2016 20:20:48 +0200 Subject: Add info on tooltips [ci skip] --- doc/workflow/labels.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/workflow/labels.md b/doc/workflow/labels.md index 35d62573c51..93a14e7b8d7 100644 --- a/doc/workflow/labels.md +++ b/doc/workflow/labels.md @@ -97,6 +97,13 @@ label description like shown below. ![Filter labels](img/labels_filter.png) +--- + +And if you added a description to your label, you can see it by hovering your +mouse over the label in the issue tracker. + +![Label tooltips](img/labels_description_tooltip.png) + ## Subscribe to labels If you don’t want to miss issues or merge requests that are important to you, -- cgit v1.2.1 From 8195deb8a6debe3aa5a8f0573d0768dd257f7305 Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Tue, 21 Jun 2016 18:54:30 +0200 Subject: Move labels documentation to new location Due to https://gitlab.com/gitlab-org/gitlab-ce/issues/3349 --- doc/intro/README.md | 2 +- .../img/labels_assign_label_in_new_issue.png | Bin 0 -> 26380 bytes .../project/img/labels_assign_label_sidebar.png | Bin 0 -> 30137 bytes .../img/labels_assign_label_sidebar_saved.png | Bin 0 -> 25488 bytes doc/user/project/img/labels_default.png | Bin 0 -> 58717 bytes .../project/img/labels_description_tooltip.png | Bin 0 -> 39315 bytes doc/user/project/img/labels_filter.png | Bin 0 -> 86911 bytes doc/user/project/img/labels_generate.png | Bin 0 -> 29986 bytes doc/user/project/img/labels_new_label.png | Bin 0 -> 29671 bytes .../project/img/labels_new_label_on_the_fly.png | Bin 0 -> 11586 bytes .../img/labels_new_label_on_the_fly_create.png | Bin 0 -> 20604 bytes doc/user/project/img/labels_subscribe.png | Bin 0 -> 50177 bytes doc/user/project/labels.md | 117 +++++++++++++++++++++ doc/workflow/README.md | 2 +- .../img/labels_assign_label_in_new_issue.png | Bin 26380 -> 0 bytes doc/workflow/img/labels_assign_label_sidebar.png | Bin 30137 -> 0 bytes .../img/labels_assign_label_sidebar_saved.png | Bin 25488 -> 0 bytes doc/workflow/img/labels_default.png | Bin 58717 -> 0 bytes doc/workflow/img/labels_description_tooltip.png | Bin 39315 -> 0 bytes doc/workflow/img/labels_filter.png | Bin 86911 -> 0 bytes doc/workflow/img/labels_generate.png | Bin 29986 -> 0 bytes doc/workflow/img/labels_new_label.png | Bin 29671 -> 0 bytes doc/workflow/img/labels_new_label_on_the_fly.png | Bin 11586 -> 0 bytes .../img/labels_new_label_on_the_fly_create.png | Bin 20604 -> 0 bytes doc/workflow/img/labels_subscribe.png | Bin 50177 -> 0 bytes doc/workflow/labels.md | 116 +------------------- doc/workflow/labels/label1.png | Bin 5846 -> 0 bytes doc/workflow/labels/label2.png | Bin 16931 -> 0 bytes doc/workflow/labels/label3.png | Bin 19360 -> 0 bytes 29 files changed, 120 insertions(+), 117 deletions(-) create mode 100644 doc/user/project/img/labels_assign_label_in_new_issue.png create mode 100644 doc/user/project/img/labels_assign_label_sidebar.png create mode 100644 doc/user/project/img/labels_assign_label_sidebar_saved.png create mode 100644 doc/user/project/img/labels_default.png create mode 100644 doc/user/project/img/labels_description_tooltip.png create mode 100644 doc/user/project/img/labels_filter.png create mode 100644 doc/user/project/img/labels_generate.png create mode 100644 doc/user/project/img/labels_new_label.png create mode 100644 doc/user/project/img/labels_new_label_on_the_fly.png create mode 100644 doc/user/project/img/labels_new_label_on_the_fly_create.png create mode 100644 doc/user/project/img/labels_subscribe.png create mode 100644 doc/user/project/labels.md delete mode 100644 doc/workflow/img/labels_assign_label_in_new_issue.png delete mode 100644 doc/workflow/img/labels_assign_label_sidebar.png delete mode 100644 doc/workflow/img/labels_assign_label_sidebar_saved.png delete mode 100644 doc/workflow/img/labels_default.png delete mode 100644 doc/workflow/img/labels_description_tooltip.png delete mode 100644 doc/workflow/img/labels_filter.png delete mode 100644 doc/workflow/img/labels_generate.png delete mode 100644 doc/workflow/img/labels_new_label.png delete mode 100644 doc/workflow/img/labels_new_label_on_the_fly.png delete mode 100644 doc/workflow/img/labels_new_label_on_the_fly_create.png delete mode 100644 doc/workflow/img/labels_subscribe.png delete mode 100644 doc/workflow/labels/label1.png delete mode 100644 doc/workflow/labels/label2.png delete mode 100644 doc/workflow/labels/label3.png diff --git a/doc/intro/README.md b/doc/intro/README.md index 382d10aaf40..1850031eb26 100644 --- a/doc/intro/README.md +++ b/doc/intro/README.md @@ -12,7 +12,7 @@ Create projects and groups. Create issues, labels, milestones, cast your vote, and review issues. - [Create a new issue](../gitlab-basics/create-issue.md) -- [Assign labels to issues](../workflow/labels.md) +- [Assign labels to issues](../user/project/labels.md) - [Use milestones as an overview of your project's tracker](../workflow/milestones.md) - [Use voting to express your like/dislike to issues and merge requests](../workflow/award_emoji.md) diff --git a/doc/user/project/img/labels_assign_label_in_new_issue.png b/doc/user/project/img/labels_assign_label_in_new_issue.png new file mode 100644 index 00000000000..72bbf9a0594 Binary files /dev/null and b/doc/user/project/img/labels_assign_label_in_new_issue.png differ diff --git a/doc/user/project/img/labels_assign_label_sidebar.png b/doc/user/project/img/labels_assign_label_sidebar.png new file mode 100644 index 00000000000..ffbbf5b8d21 Binary files /dev/null and b/doc/user/project/img/labels_assign_label_sidebar.png differ diff --git a/doc/user/project/img/labels_assign_label_sidebar_saved.png b/doc/user/project/img/labels_assign_label_sidebar_saved.png new file mode 100644 index 00000000000..2771b02735f Binary files /dev/null and b/doc/user/project/img/labels_assign_label_sidebar_saved.png differ diff --git a/doc/user/project/img/labels_default.png b/doc/user/project/img/labels_default.png new file mode 100644 index 00000000000..2d44eb4409b Binary files /dev/null and b/doc/user/project/img/labels_default.png differ diff --git a/doc/user/project/img/labels_description_tooltip.png b/doc/user/project/img/labels_description_tooltip.png new file mode 100644 index 00000000000..887ef5f43a8 Binary files /dev/null and b/doc/user/project/img/labels_description_tooltip.png differ diff --git a/doc/user/project/img/labels_filter.png b/doc/user/project/img/labels_filter.png new file mode 100644 index 00000000000..139b3b22e14 Binary files /dev/null and b/doc/user/project/img/labels_filter.png differ diff --git a/doc/user/project/img/labels_generate.png b/doc/user/project/img/labels_generate.png new file mode 100644 index 00000000000..78eff8525bf Binary files /dev/null and b/doc/user/project/img/labels_generate.png differ diff --git a/doc/user/project/img/labels_new_label.png b/doc/user/project/img/labels_new_label.png new file mode 100644 index 00000000000..6dc4fe8ce20 Binary files /dev/null and b/doc/user/project/img/labels_new_label.png differ diff --git a/doc/user/project/img/labels_new_label_on_the_fly.png b/doc/user/project/img/labels_new_label_on_the_fly.png new file mode 100644 index 00000000000..4559c56dbda Binary files /dev/null and b/doc/user/project/img/labels_new_label_on_the_fly.png differ diff --git a/doc/user/project/img/labels_new_label_on_the_fly_create.png b/doc/user/project/img/labels_new_label_on_the_fly_create.png new file mode 100644 index 00000000000..ee75bc6ec92 Binary files /dev/null and b/doc/user/project/img/labels_new_label_on_the_fly_create.png differ diff --git a/doc/user/project/img/labels_subscribe.png b/doc/user/project/img/labels_subscribe.png new file mode 100644 index 00000000000..f3c1a1b67e2 Binary files /dev/null and b/doc/user/project/img/labels_subscribe.png differ diff --git a/doc/user/project/labels.md b/doc/user/project/labels.md new file mode 100644 index 00000000000..93a14e7b8d7 --- /dev/null +++ b/doc/user/project/labels.md @@ -0,0 +1,117 @@ +# Labels + +Labels provide an easy way to categorize the issues or merge requests based on +descriptive titles like `bug`, `documentation` or any other text you feel like +it. They can have different colors, a description, and are visible throughout +the issue tracker or inside each issue individually. + +With labels, you can navigate the issue tracker and filter any bloated +information to visualize only the issues you are interested in. Let's see how +that works. + +## Create new labels + +>**Note:** +A permission level of `Developer` or higher is required in order to manage +labels. + +Head over a single project and navigate to the label page by clicking on +**Labels** in the left sidebar. + +The first time you visit the **Labels** page you'll notice that there are no +labels created yet. + +![Generate new labels](img/labels_generate.png) + +--- + +You can skip that and create a new label or click that link and GitLab will +generate a set of predefined labels for you. There 8 default generated labels +in total and you can see them in the screenshot below. + +![Default generated labels](img/labels_default.png) + +--- + +You can see that from the labels page you can have an overview of the number of +issues and merge requests assigned to each label. + +Creating a new label from scratch is as easy as pressing the **New label** +button. From there on you can choose the name, give it an optional description, +a color and you are set. + +When you are ready press the **Create label** button to create the new label. + +![New label](img/labels_new_label.png) + +## Create a new label right from the issue tracker + +>**Note:** +This feature was introduced in GitLab 8.6. + +There are times when you are already in the issue tracker searching for a +label, only to realize it doesn't exist. Instead of going to the **Labels** +page and being distracted from your original purpose, you can create new +labels on the fly. + +Just hit **New Label** from the dropdown list, provide a name, pick a color +and hit **Create**. + +![Create new label on the fly](img/labels_new_label_on_the_fly_create.png) +![New label on the fly](img/labels_new_label_on_the_fly.png) + +## Assigning labels to issues and merge requests + +There are generally two ways to assign a label to an issue or merge request. + +--- + +You can assign a label when you first create or edit an issue or merge request. + +![Assign label in new issue](img/labels_assign_label_in_new_issue.png) + +--- + +The second way is by using the right sidebar. Expand it and hit **Edit**. Start +typing the name of the label you are looking for to narrow down the list and +select it. Once done, click outside the sidebar area for the changes to take +effect. + +![Assign label in sidebar](img/labels_assign_label_sidebar.png) +![Save labels in sidebar](img/labels_assign_label_sidebar_saved.png) + +--- + +To remove labels, follow the same procedure like when adding them and hit the +little **x** mark next to each one. + +## Use labels to filter issues + +Once you start adding labels to your issues, you'll see the benefit of it. +Labels can have several uses, one of them being the quick filtering of issues +or merge requests. + +Pick an existing label from the dropdown _Label_ menu or click on an existing +label from the issue tracker. In the latter case, you also get to see the +label description like shown below. + +![Filter labels](img/labels_filter.png) + +--- + +And if you added a description to your label, you can see it by hovering your +mouse over the label in the issue tracker. + +![Label tooltips](img/labels_description_tooltip.png) + +## Subscribe to labels + +If you don’t want to miss issues or merge requests that are important to you, +simply subscribe to a label. You’ll get notified whenever the label gets added +to an issue or merge request, making sure you don’t miss a thing. + +![Subscribe to labels](img/labels_subscribe.png) + +If you work on a large or popular project, try subscribing only to the labels +that are relevant to you. You’ll notice it’ll be much easier to focus on what’s +important. diff --git a/doc/workflow/README.md b/doc/workflow/README.md index 9efe41308dc..ddb2f7281b1 100644 --- a/doc/workflow/README.md +++ b/doc/workflow/README.md @@ -7,7 +7,7 @@ - [Groups](groups.md) - [Keyboard shortcuts](shortcuts.md) - [File finder](file_finder.md) -- [Labels](labels.md) +- [Labels](../user/project/labels.md) - [Notification emails](notifications.md) - [Project Features](project_features.md) - [Project forking workflow](forking_workflow.md) diff --git a/doc/workflow/img/labels_assign_label_in_new_issue.png b/doc/workflow/img/labels_assign_label_in_new_issue.png deleted file mode 100644 index 72bbf9a0594..00000000000 Binary files a/doc/workflow/img/labels_assign_label_in_new_issue.png and /dev/null differ diff --git a/doc/workflow/img/labels_assign_label_sidebar.png b/doc/workflow/img/labels_assign_label_sidebar.png deleted file mode 100644 index ffbbf5b8d21..00000000000 Binary files a/doc/workflow/img/labels_assign_label_sidebar.png and /dev/null differ diff --git a/doc/workflow/img/labels_assign_label_sidebar_saved.png b/doc/workflow/img/labels_assign_label_sidebar_saved.png deleted file mode 100644 index 2771b02735f..00000000000 Binary files a/doc/workflow/img/labels_assign_label_sidebar_saved.png and /dev/null differ diff --git a/doc/workflow/img/labels_default.png b/doc/workflow/img/labels_default.png deleted file mode 100644 index 2d44eb4409b..00000000000 Binary files a/doc/workflow/img/labels_default.png and /dev/null differ diff --git a/doc/workflow/img/labels_description_tooltip.png b/doc/workflow/img/labels_description_tooltip.png deleted file mode 100644 index 887ef5f43a8..00000000000 Binary files a/doc/workflow/img/labels_description_tooltip.png and /dev/null differ diff --git a/doc/workflow/img/labels_filter.png b/doc/workflow/img/labels_filter.png deleted file mode 100644 index 139b3b22e14..00000000000 Binary files a/doc/workflow/img/labels_filter.png and /dev/null differ diff --git a/doc/workflow/img/labels_generate.png b/doc/workflow/img/labels_generate.png deleted file mode 100644 index 78eff8525bf..00000000000 Binary files a/doc/workflow/img/labels_generate.png and /dev/null differ diff --git a/doc/workflow/img/labels_new_label.png b/doc/workflow/img/labels_new_label.png deleted file mode 100644 index 6dc4fe8ce20..00000000000 Binary files a/doc/workflow/img/labels_new_label.png and /dev/null differ diff --git a/doc/workflow/img/labels_new_label_on_the_fly.png b/doc/workflow/img/labels_new_label_on_the_fly.png deleted file mode 100644 index 4559c56dbda..00000000000 Binary files a/doc/workflow/img/labels_new_label_on_the_fly.png and /dev/null differ diff --git a/doc/workflow/img/labels_new_label_on_the_fly_create.png b/doc/workflow/img/labels_new_label_on_the_fly_create.png deleted file mode 100644 index ee75bc6ec92..00000000000 Binary files a/doc/workflow/img/labels_new_label_on_the_fly_create.png and /dev/null differ diff --git a/doc/workflow/img/labels_subscribe.png b/doc/workflow/img/labels_subscribe.png deleted file mode 100644 index f3c1a1b67e2..00000000000 Binary files a/doc/workflow/img/labels_subscribe.png and /dev/null differ diff --git a/doc/workflow/labels.md b/doc/workflow/labels.md index 93a14e7b8d7..5c09891dfdd 100644 --- a/doc/workflow/labels.md +++ b/doc/workflow/labels.md @@ -1,117 +1,3 @@ # Labels -Labels provide an easy way to categorize the issues or merge requests based on -descriptive titles like `bug`, `documentation` or any other text you feel like -it. They can have different colors, a description, and are visible throughout -the issue tracker or inside each issue individually. - -With labels, you can navigate the issue tracker and filter any bloated -information to visualize only the issues you are interested in. Let's see how -that works. - -## Create new labels - ->**Note:** -A permission level of `Developer` or higher is required in order to manage -labels. - -Head over a single project and navigate to the label page by clicking on -**Labels** in the left sidebar. - -The first time you visit the **Labels** page you'll notice that there are no -labels created yet. - -![Generate new labels](img/labels_generate.png) - ---- - -You can skip that and create a new label or click that link and GitLab will -generate a set of predefined labels for you. There 8 default generated labels -in total and you can see them in the screenshot below. - -![Default generated labels](img/labels_default.png) - ---- - -You can see that from the labels page you can have an overview of the number of -issues and merge requests assigned to each label. - -Creating a new label from scratch is as easy as pressing the **New label** -button. From there on you can choose the name, give it an optional description, -a color and you are set. - -When you are ready press the **Create label** button to create the new label. - -![New label](img/labels_new_label.png) - -## Create a new label right from the issue tracker - ->**Note:** -This feature was introduced in GitLab 8.6. - -There are times when you are already in the issue tracker searching for a -label, only to realize it doesn't exist. Instead of going to the **Labels** -page and being distracted from your original purpose, you can create new -labels on the fly. - -Just hit **New Label** from the dropdown list, provide a name, pick a color -and hit **Create**. - -![Create new label on the fly](img/labels_new_label_on_the_fly_create.png) -![New label on the fly](img/labels_new_label_on_the_fly.png) - -## Assigning labels to issues and merge requests - -There are generally two ways to assign a label to an issue or merge request. - ---- - -You can assign a label when you first create or edit an issue or merge request. - -![Assign label in new issue](img/labels_assign_label_in_new_issue.png) - ---- - -The second way is by using the right sidebar. Expand it and hit **Edit**. Start -typing the name of the label you are looking for to narrow down the list and -select it. Once done, click outside the sidebar area for the changes to take -effect. - -![Assign label in sidebar](img/labels_assign_label_sidebar.png) -![Save labels in sidebar](img/labels_assign_label_sidebar_saved.png) - ---- - -To remove labels, follow the same procedure like when adding them and hit the -little **x** mark next to each one. - -## Use labels to filter issues - -Once you start adding labels to your issues, you'll see the benefit of it. -Labels can have several uses, one of them being the quick filtering of issues -or merge requests. - -Pick an existing label from the dropdown _Label_ menu or click on an existing -label from the issue tracker. In the latter case, you also get to see the -label description like shown below. - -![Filter labels](img/labels_filter.png) - ---- - -And if you added a description to your label, you can see it by hovering your -mouse over the label in the issue tracker. - -![Label tooltips](img/labels_description_tooltip.png) - -## Subscribe to labels - -If you don’t want to miss issues or merge requests that are important to you, -simply subscribe to a label. You’ll get notified whenever the label gets added -to an issue or merge request, making sure you don’t miss a thing. - -![Subscribe to labels](img/labels_subscribe.png) - -If you work on a large or popular project, try subscribing only to the labels -that are relevant to you. You’ll notice it’ll be much easier to focus on what’s -important. +This document was moved to [user/project/labels.md](../user/project/labels.md). diff --git a/doc/workflow/labels/label1.png b/doc/workflow/labels/label1.png deleted file mode 100644 index cac661a34c8..00000000000 Binary files a/doc/workflow/labels/label1.png and /dev/null differ diff --git a/doc/workflow/labels/label2.png b/doc/workflow/labels/label2.png deleted file mode 100644 index 44d9fef86d4..00000000000 Binary files a/doc/workflow/labels/label2.png and /dev/null differ diff --git a/doc/workflow/labels/label3.png b/doc/workflow/labels/label3.png deleted file mode 100644 index e2fce11b7a4..00000000000 Binary files a/doc/workflow/labels/label3.png and /dev/null differ -- cgit v1.2.1 From b2f60bb9a118c366ad462241bd4842c52d872d5f Mon Sep 17 00:00:00 2001 From: Sean McGivern Date: Tue, 21 Jun 2016 17:54:41 +0100 Subject: Fix auto-MR-close text from branch name Rails's form helpers use the `$attr_before_type_cast` method where available, and this value only appears to be updated on assignment, not when the object is mutated in some other way: [1] pry(main)> mr = MergeRequest.new => # [2] pry(main)> mr.description = 'foo' => "foo" [3] pry(main)> mr.description << ' bar' => "foo bar" [4] pry(main)> mr.description => "foo bar" [5] pry(main)> mr.description_before_type_cast => "foo" [6] pry(main)> mr.description += ' bar' => "foo bar bar" [7] pry(main)> mr.description_before_type_cast => "foo bar bar" --- CHANGELOG | 1 + app/services/merge_requests/build_service.rb | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 0c3aadc29d1..374cc971ef3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -13,6 +13,7 @@ v 8.9.0 (unreleased) - Fix endless redirections when accessing user OAuth applications when they are disabled - Allow enabling wiki page events from Webhook management UI - Bump rouge to 1.11.0 + - Fix MR-auto-close text added to description - Fix issue with arrow keys not working in search autocomplete dropdown - Fix an issue where note polling stopped working if a window was in the background during a refresh. diff --git a/app/services/merge_requests/build_service.rb b/app/services/merge_requests/build_service.rb index 1b48899bb0a..7fe57747265 100644 --- a/app/services/merge_requests/build_service.rb +++ b/app/services/merge_requests/build_service.rb @@ -83,7 +83,7 @@ module MergeRequests closes_issue = "Closes ##{iid}" if merge_request.description.present? - merge_request.description << closes_issue.prepend("\n") + merge_request.description += closes_issue.prepend("\n") else merge_request.description = closes_issue end -- cgit v1.2.1 From 4b1e505ef8dc55d719c5dccfde75acff537e01b6 Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Tue, 21 Jun 2016 19:21:13 +0200 Subject: Add missing link to sidekiq metrics in API README [ci skip] --- doc/api/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/api/README.md b/doc/api/README.md index 73f44603688..288f7f9ee69 100644 --- a/doc/api/README.md +++ b/doc/api/README.md @@ -32,6 +32,7 @@ following locations: - [Services](services.md) - [Session](session.md) - [Settings](settings.md) +- [Sidekiq metrics](sidekiq_metrics.md) - [System Hooks](system_hooks.md) - [Tags](tags.md) - [Users](users.md) -- cgit v1.2.1 From e6ab0346f2772a8f16abaef22f69cf6dd049602f Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 17 Jun 2016 11:11:35 +0200 Subject: import/export docs --- doc/administration/img/export_1.png | Bin 0 -> 84637 bytes doc/administration/img/export_2.png | Bin 0 -> 13023 bytes doc/administration/img/export_3.png | Bin 0 -> 44012 bytes doc/administration/img/export_4.png | Bin 0 -> 86500 bytes doc/administration/img/import_1.png | Bin 0 -> 43574 bytes doc/administration/img/import_2.png | Bin 0 -> 46292 bytes doc/administration/import_export.md | 50 ++++++++++++++++++++++++++++++++++++ 7 files changed, 50 insertions(+) create mode 100644 doc/administration/img/export_1.png create mode 100644 doc/administration/img/export_2.png create mode 100644 doc/administration/img/export_3.png create mode 100644 doc/administration/img/export_4.png create mode 100644 doc/administration/img/import_1.png create mode 100644 doc/administration/img/import_2.png create mode 100644 doc/administration/import_export.md diff --git a/doc/administration/img/export_1.png b/doc/administration/img/export_1.png new file mode 100644 index 00000000000..1f7bdd21b0d Binary files /dev/null and b/doc/administration/img/export_1.png differ diff --git a/doc/administration/img/export_2.png b/doc/administration/img/export_2.png new file mode 100644 index 00000000000..ac866d7063d Binary files /dev/null and b/doc/administration/img/export_2.png differ diff --git a/doc/administration/img/export_3.png b/doc/administration/img/export_3.png new file mode 100644 index 00000000000..c123f83eb8e Binary files /dev/null and b/doc/administration/img/export_3.png differ diff --git a/doc/administration/img/export_4.png b/doc/administration/img/export_4.png new file mode 100644 index 00000000000..36568729abd Binary files /dev/null and b/doc/administration/img/export_4.png differ diff --git a/doc/administration/img/import_1.png b/doc/administration/img/import_1.png new file mode 100644 index 00000000000..b3a7f201018 Binary files /dev/null and b/doc/administration/img/import_1.png differ diff --git a/doc/administration/img/import_2.png b/doc/administration/img/import_2.png new file mode 100644 index 00000000000..f31832af3e1 Binary files /dev/null and b/doc/administration/img/import_2.png differ diff --git a/doc/administration/import_export.md b/doc/administration/import_export.md new file mode 100644 index 00000000000..b8ec12bbd05 --- /dev/null +++ b/doc/administration/import_export.md @@ -0,0 +1,50 @@ +# Project import/export + +Existing projects running on any GitLab instance or GitLab.com can be exported +with all its related data and moved into a new GitLab instance. + +## Requirements + +- You will need at least GitLab version 8.9 running on both instances +- Importing may not be possible if the import instance version is lower + than the exporter. + +## Exported contents + +* The following items will be exported: + * Project and wiki repositories + * Project uploads + * Project configuration including web hooks and services + * Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, + and other project entities +* The following items will NOT be exported: + * Build traces and artifacts + * LFS objects + +## Exporting a project and its data + +1. Go to the project settings page and find the Export button. + + ![export_1](./img/export_1.png) + +2. Once the export is generated, you should receive an e-mail with a link to download the file. + + ![export_3](./img/export_3.png) + +3. You can come back to project settings and download the file from there, or delete it so it +can be generated again. + + ![export_4](./img/export_4.png) + +## Import + +1. The new GitLab project import feature is at the far right of the import options on New Project. + + ![import_1](./img/import_1.png) + +2. After choosing a namespace or path, you can then select the file prevoiusly exported. + + ![import_2](./img/import_2.png) + + +3. Click on Import and the import now begins and you will see your newly imported project page soon. -- cgit v1.2.1 From 604fb8bdca2ab6fc247a2006dfa8c5b665b0fd26 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 17 Jun 2016 11:24:51 +0200 Subject: update docs --- doc/administration/import_export.md | 42 ++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/doc/administration/import_export.md b/doc/administration/import_export.md index b8ec12bbd05..adfb1993e76 100644 --- a/doc/administration/import_export.md +++ b/doc/administration/import_export.md @@ -3,48 +3,46 @@ Existing projects running on any GitLab instance or GitLab.com can be exported with all its related data and moved into a new GitLab instance. -## Requirements - -- You will need at least GitLab version 8.9 running on both instances -- Importing may not be possible if the import instance version is lower - than the exporter. +>**Note:** + - This feature was [introduced][ce-3050] in GitLab 8.9 + - Importing may not be possible if the import instance version is lower + than that of the exporter. ## Exported contents -* The following items will be exported: - * Project and wiki repositories - * Project uploads - * Project configuration including web hooks and services - * Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, +- The following items will be exported: + - Project and wiki repositories + - Project uploads + - Project configuration including web hooks and services + - Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, and other project entities -* The following items will NOT be exported: - * Build traces and artifacts - * LFS objects +- The following items will NOT be exported: + - Build traces and artifacts + - LFS objects ## Exporting a project and its data -1. Go to the project settings page and find the Export button. +1. Go to the project settings page and find the Export button ![export_1](./img/export_1.png) -2. Once the export is generated, you should receive an e-mail with a link to download the file. +1. Once the export is generated, you should receive an e-mail with a link to download the file ![export_3](./img/export_3.png) -3. You can come back to project settings and download the file from there, or delete it so it -can be generated again. +1. You can come back to project settings and download the file from there, or delete it so it +can be generated again ![export_4](./img/export_4.png) -## Import +## Importing the project -1. The new GitLab project import feature is at the far right of the import options on New Project. +1. The new GitLab project import feature is at the far right of the import options on New Project ![import_1](./img/import_1.png) -2. After choosing a namespace or path, you can then select the file prevoiusly exported. +1. After choosing a namespace or path, you can then select the file prevoiusly exported ![import_2](./img/import_2.png) - -3. Click on Import and the import now begins and you will see your newly imported project page soon. +1. Click on Import and the import now begins and you will see your newly imported project page soon -- cgit v1.2.1 From 6715402e2092f0def4b39ce5988138c0e10229ee Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 17 Jun 2016 12:12:14 +0200 Subject: added some extra nice tasks to have --- doc/administration/import_export.md | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/doc/administration/import_export.md b/doc/administration/import_export.md index adfb1993e76..950899dc04b 100644 --- a/doc/administration/import_export.md +++ b/doc/administration/import_export.md @@ -1,11 +1,11 @@ # Project import/export Existing projects running on any GitLab instance or GitLab.com can be exported -with all its related data and moved into a new GitLab instance. +with all its related data and be moved to a new GitLab instance. >**Note:** - This feature was [introduced][ce-3050] in GitLab 8.9 - - Importing may not be possible if the import instance version is lower + - Importing will not be possible if the import instance version is lower than that of the exporter. ## Exported contents @@ -41,8 +41,26 @@ can be generated again ![import_1](./img/import_1.png) -1. After choosing a namespace or path, you can then select the file prevoiusly exported +1. After choosing a namespace or path, you can then select the file exported previously ![import_2](./img/import_2.png) -1. Click on Import and the import now begins and you will see your newly imported project page soon +1. Click on Import to begin importing and you will see your newly imported project page soon + +[ce-3050]: https://gitlab.com/gitlab-org/gitlab-ce/issues/3050 + +## Advanced + +> The GitLab Import/Export version can be checked by using: + +```bash +cd /home/git/gitlab +sudo -u git -H bundle exec rake gitlab:import_export:version +``` + +> The current list of DB tables that will get exported can be listed by using: + +```bash +cd /home/git/gitlab +sudo -u git -H bundle exec rake gitlab:import_export:data RAILS_ENV=production +``` \ No newline at end of file -- cgit v1.2.1 From 3a7eb38a7889ee067c470ca8f6d964218844287e Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 17 Jun 2016 12:23:41 +0200 Subject: added nice to have - rake task and some changes to docs --- doc/README.md | 1 + doc/administration/import_export.md | 66 ------------------------------------ doc/workflow/import_export/README.md | 66 ++++++++++++++++++++++++++++++++++++ lib/tasks/gitlab/import_export.rake | 13 +++++++ 4 files changed, 80 insertions(+), 66 deletions(-) delete mode 100644 doc/administration/import_export.md create mode 100644 doc/workflow/import_export/README.md create mode 100644 lib/tasks/gitlab/import_export.rake diff --git a/doc/README.md b/doc/README.md index 5d89d0c9821..f51069b2c30 100644 --- a/doc/README.md +++ b/doc/README.md @@ -7,6 +7,7 @@ - [GitLab as OAuth2 authentication service provider](integration/oauth_provider.md). It allows you to login to other applications from GitLab. - [GitLab Basics](gitlab-basics/README.md) Find step by step how to start working on your commandline and on GitLab. - [Importing to GitLab](workflow/importing/README.md). +- [Importing and exporting projects between instances](workflow/import_export/README.md). - [Markdown](markdown/markdown.md) GitLab's advanced formatting system. - [Migrating from SVN](workflow/importing/migrating_from_svn.md) Convert a SVN repository to Git and GitLab - [Permissions](permissions/permissions.md) Learn what each role in a project (external/guest/reporter/developer/master/owner) can do. diff --git a/doc/administration/import_export.md b/doc/administration/import_export.md deleted file mode 100644 index 950899dc04b..00000000000 --- a/doc/administration/import_export.md +++ /dev/null @@ -1,66 +0,0 @@ -# Project import/export - -Existing projects running on any GitLab instance or GitLab.com can be exported -with all its related data and be moved to a new GitLab instance. - ->**Note:** - - This feature was [introduced][ce-3050] in GitLab 8.9 - - Importing will not be possible if the import instance version is lower - than that of the exporter. - -## Exported contents - -- The following items will be exported: - - Project and wiki repositories - - Project uploads - - Project configuration including web hooks and services - - Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, - and other project entities -- The following items will NOT be exported: - - Build traces and artifacts - - LFS objects - -## Exporting a project and its data - -1. Go to the project settings page and find the Export button - - ![export_1](./img/export_1.png) - -1. Once the export is generated, you should receive an e-mail with a link to download the file - - ![export_3](./img/export_3.png) - -1. You can come back to project settings and download the file from there, or delete it so it -can be generated again - - ![export_4](./img/export_4.png) - -## Importing the project - -1. The new GitLab project import feature is at the far right of the import options on New Project - - ![import_1](./img/import_1.png) - -1. After choosing a namespace or path, you can then select the file exported previously - - ![import_2](./img/import_2.png) - -1. Click on Import to begin importing and you will see your newly imported project page soon - -[ce-3050]: https://gitlab.com/gitlab-org/gitlab-ce/issues/3050 - -## Advanced - -> The GitLab Import/Export version can be checked by using: - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:import_export:version -``` - -> The current list of DB tables that will get exported can be listed by using: - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:import_export:data RAILS_ENV=production -``` \ No newline at end of file diff --git a/doc/workflow/import_export/README.md b/doc/workflow/import_export/README.md new file mode 100644 index 00000000000..5349cca7172 --- /dev/null +++ b/doc/workflow/import_export/README.md @@ -0,0 +1,66 @@ +# Project import/export + +Existing projects running on any GitLab instance or GitLab.com can be exported +with all its related data and be moved into a new GitLab instance. + +>**Note:** + - This feature was [introduced][ce-3050] in GitLab 8.9 + - Importing will not be possible if the import instance version is lower + than that of the exporter. + +## Exported contents + +- The following items will be exported: + - Project and wiki repositories + - Project uploads + - Project configuration including web hooks and services + - Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, + and other project entities +- The following items will NOT be exported: + - Build traces and artifacts + - LFS objects + +## Exporting a project and its data + +1. Go to the project settings page and find the Export button + + ![export_1](./img/export_1.png) + +1. Once the export is generated, you should receive an e-mail with a link to download the file + + ![export_3](./img/export_3.png) + +1. You can come back to project settings and download the file from there, or delete it so it +can be generated again + + ![export_4](./img/export_4.png) + +## Importing the project + +1. The new GitLab project import feature is at the far right of the import options on New Project + + ![import_1](./img/import_1.png) + +1. After choosing a namespace or path, you can then select the file exported previously + + ![import_2](./img/import_2.png) + +1. Click on Import to begin importing and you will see your newly imported project page soon + +[ce-3050]: https://gitlab.com/gitlab-org/gitlab-ce/issues/3050 + +## Advanced + +The GitLab Import/Export version can be checked by using: + +```bash +cd /home/git/gitlab +sudo -u git -H bundle exec rake gitlab:import_export:version RAILS_ENV=production +``` + +The current list of DB tables that will get exported can be listed by using: + +```bash +cd /home/git/gitlab +sudo -u git -H bundle exec rake gitlab:import_export:data RAILS_ENV=production +``` \ No newline at end of file diff --git a/lib/tasks/gitlab/import_export.rake b/lib/tasks/gitlab/import_export.rake new file mode 100644 index 00000000000..c2c6031db67 --- /dev/null +++ b/lib/tasks/gitlab/import_export.rake @@ -0,0 +1,13 @@ +namespace :gitlab do + namespace :import_export do + desc "GitLab | Show Import/Export version" + task version: :environment do + puts "Import/Export v#{Gitlab::ImportExport.version}" + end + + desc "GitLab | Display exported DB structure" + task data: :environment do + puts YAML.load_file(Gitlab::ImportExport.config_file)['project_tree'].to_yaml(:SortKeys => true) + end + end +end -- cgit v1.2.1 From dd94b8c75fdbed9198903b3e045138bd033a8b39 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 17 Jun 2016 12:27:22 +0200 Subject: moved link to bottom of the page --- doc/workflow/import_export/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/workflow/import_export/README.md b/doc/workflow/import_export/README.md index 5349cca7172..a9a8af33553 100644 --- a/doc/workflow/import_export/README.md +++ b/doc/workflow/import_export/README.md @@ -47,7 +47,6 @@ can be generated again 1. Click on Import to begin importing and you will see your newly imported project page soon -[ce-3050]: https://gitlab.com/gitlab-org/gitlab-ce/issues/3050 ## Advanced @@ -63,4 +62,6 @@ The current list of DB tables that will get exported can be listed by using: ```bash cd /home/git/gitlab sudo -u git -H bundle exec rake gitlab:import_export:data RAILS_ENV=production -``` \ No newline at end of file +``` + +[ce-3050]: https://gitlab.com/gitlab-org/gitlab-ce/issues/3050 -- cgit v1.2.1 From 3b888d48edae11ec559ea980407ed6d0159a2d78 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 17 Jun 2016 12:38:15 +0200 Subject: deleted images no longer needed --- doc/administration/img/export_1.png | Bin 84637 -> 0 bytes doc/administration/img/export_2.png | Bin 13023 -> 0 bytes doc/administration/img/export_3.png | Bin 44012 -> 0 bytes doc/administration/img/export_4.png | Bin 86500 -> 0 bytes doc/administration/img/import_1.png | Bin 43574 -> 0 bytes doc/administration/img/import_2.png | Bin 46292 -> 0 bytes doc/workflow/import_export/img/export_1.png | Bin 0 -> 84637 bytes doc/workflow/import_export/img/export_3.png | Bin 0 -> 44012 bytes doc/workflow/import_export/img/export_4.png | Bin 0 -> 86500 bytes doc/workflow/import_export/img/import_1.png | Bin 0 -> 43574 bytes doc/workflow/import_export/img/import_2.png | Bin 0 -> 46292 bytes 11 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 doc/administration/img/export_1.png delete mode 100644 doc/administration/img/export_2.png delete mode 100644 doc/administration/img/export_3.png delete mode 100644 doc/administration/img/export_4.png delete mode 100644 doc/administration/img/import_1.png delete mode 100644 doc/administration/img/import_2.png create mode 100644 doc/workflow/import_export/img/export_1.png create mode 100644 doc/workflow/import_export/img/export_3.png create mode 100644 doc/workflow/import_export/img/export_4.png create mode 100644 doc/workflow/import_export/img/import_1.png create mode 100644 doc/workflow/import_export/img/import_2.png diff --git a/doc/administration/img/export_1.png b/doc/administration/img/export_1.png deleted file mode 100644 index 1f7bdd21b0d..00000000000 Binary files a/doc/administration/img/export_1.png and /dev/null differ diff --git a/doc/administration/img/export_2.png b/doc/administration/img/export_2.png deleted file mode 100644 index ac866d7063d..00000000000 Binary files a/doc/administration/img/export_2.png and /dev/null differ diff --git a/doc/administration/img/export_3.png b/doc/administration/img/export_3.png deleted file mode 100644 index c123f83eb8e..00000000000 Binary files a/doc/administration/img/export_3.png and /dev/null differ diff --git a/doc/administration/img/export_4.png b/doc/administration/img/export_4.png deleted file mode 100644 index 36568729abd..00000000000 Binary files a/doc/administration/img/export_4.png and /dev/null differ diff --git a/doc/administration/img/import_1.png b/doc/administration/img/import_1.png deleted file mode 100644 index b3a7f201018..00000000000 Binary files a/doc/administration/img/import_1.png and /dev/null differ diff --git a/doc/administration/img/import_2.png b/doc/administration/img/import_2.png deleted file mode 100644 index f31832af3e1..00000000000 Binary files a/doc/administration/img/import_2.png and /dev/null differ diff --git a/doc/workflow/import_export/img/export_1.png b/doc/workflow/import_export/img/export_1.png new file mode 100644 index 00000000000..1f7bdd21b0d Binary files /dev/null and b/doc/workflow/import_export/img/export_1.png differ diff --git a/doc/workflow/import_export/img/export_3.png b/doc/workflow/import_export/img/export_3.png new file mode 100644 index 00000000000..c123f83eb8e Binary files /dev/null and b/doc/workflow/import_export/img/export_3.png differ diff --git a/doc/workflow/import_export/img/export_4.png b/doc/workflow/import_export/img/export_4.png new file mode 100644 index 00000000000..36568729abd Binary files /dev/null and b/doc/workflow/import_export/img/export_4.png differ diff --git a/doc/workflow/import_export/img/import_1.png b/doc/workflow/import_export/img/import_1.png new file mode 100644 index 00000000000..b3a7f201018 Binary files /dev/null and b/doc/workflow/import_export/img/import_1.png differ diff --git a/doc/workflow/import_export/img/import_2.png b/doc/workflow/import_export/img/import_2.png new file mode 100644 index 00000000000..f31832af3e1 Binary files /dev/null and b/doc/workflow/import_export/img/import_2.png differ -- cgit v1.2.1 From acc1ea9d9f4d69c9b25c947e47c3e501e1323139 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 17 Jun 2016 17:09:42 +0200 Subject: update screenshot with new changes --- doc/workflow/import_export/img/export_4.png | Bin 86500 -> 85600 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/doc/workflow/import_export/img/export_4.png b/doc/workflow/import_export/img/export_4.png index 36568729abd..a2f7f0085c1 100644 Binary files a/doc/workflow/import_export/img/export_4.png and b/doc/workflow/import_export/img/export_4.png differ -- cgit v1.2.1 From 8b7224d91e68af906f3877a82a5be10b99624da1 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Fri, 17 Jun 2016 18:05:51 +0200 Subject: updated based on feedback --- doc/workflow/import_export/README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/doc/workflow/import_export/README.md b/doc/workflow/import_export/README.md index a9a8af33553..618f9948e12 100644 --- a/doc/workflow/import_export/README.md +++ b/doc/workflow/import_export/README.md @@ -1,7 +1,7 @@ # Project import/export Existing projects running on any GitLab instance or GitLab.com can be exported -with all its related data and be moved into a new GitLab instance. +with all their related data and be moved into a new GitLab instance. >**Note:** - This feature was [introduced][ce-3050] in GitLab 8.9 @@ -53,15 +53,13 @@ can be generated again The GitLab Import/Export version can be checked by using: ```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:import_export:version RAILS_ENV=production +sudo gitlab-rake gitlab:import_export:version ``` The current list of DB tables that will get exported can be listed by using: ```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:import_export:data RAILS_ENV=production +sudo gitlab-rake gitlab:import_export:data ``` [ce-3050]: https://gitlab.com/gitlab-org/gitlab-ce/issues/3050 -- cgit v1.2.1 From 0c61fad74c877ff797578a3cb969c6e613b8df00 Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Tue, 21 Jun 2016 19:28:08 +0200 Subject: Move to new location Due to https://gitlab.com/gitlab-org/gitlab-ce/issues/3349 --- doc/README.md | 2 +- doc/user/project/settings/img/export_1.png | Bin 0 -> 84637 bytes doc/user/project/settings/img/export_3.png | Bin 0 -> 44012 bytes doc/user/project/settings/img/export_4.png | Bin 0 -> 85600 bytes doc/user/project/settings/img/import_1.png | Bin 0 -> 43574 bytes doc/user/project/settings/img/import_2.png | Bin 0 -> 46292 bytes doc/user/project/settings/import_export.md | 65 ++++++++++++++++++++++++++++ doc/workflow/import_export/img/export_1.png | Bin 84637 -> 0 bytes doc/workflow/import_export/img/export_3.png | Bin 44012 -> 0 bytes doc/workflow/import_export/img/export_4.png | Bin 85600 -> 0 bytes doc/workflow/import_export/img/import_1.png | Bin 43574 -> 0 bytes doc/workflow/import_export/img/import_2.png | Bin 46292 -> 0 bytes 12 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 doc/user/project/settings/img/export_1.png create mode 100644 doc/user/project/settings/img/export_3.png create mode 100644 doc/user/project/settings/img/export_4.png create mode 100644 doc/user/project/settings/img/import_1.png create mode 100644 doc/user/project/settings/img/import_2.png create mode 100644 doc/user/project/settings/import_export.md delete mode 100644 doc/workflow/import_export/img/export_1.png delete mode 100644 doc/workflow/import_export/img/export_3.png delete mode 100644 doc/workflow/import_export/img/export_4.png delete mode 100644 doc/workflow/import_export/img/import_1.png delete mode 100644 doc/workflow/import_export/img/import_2.png diff --git a/doc/README.md b/doc/README.md index f51069b2c30..495a99d5d9d 100644 --- a/doc/README.md +++ b/doc/README.md @@ -7,7 +7,7 @@ - [GitLab as OAuth2 authentication service provider](integration/oauth_provider.md). It allows you to login to other applications from GitLab. - [GitLab Basics](gitlab-basics/README.md) Find step by step how to start working on your commandline and on GitLab. - [Importing to GitLab](workflow/importing/README.md). -- [Importing and exporting projects between instances](workflow/import_export/README.md). +- [Importing and exporting projects between instances](user/project/settings/import_export.md). - [Markdown](markdown/markdown.md) GitLab's advanced formatting system. - [Migrating from SVN](workflow/importing/migrating_from_svn.md) Convert a SVN repository to Git and GitLab - [Permissions](permissions/permissions.md) Learn what each role in a project (external/guest/reporter/developer/master/owner) can do. diff --git a/doc/user/project/settings/img/export_1.png b/doc/user/project/settings/img/export_1.png new file mode 100644 index 00000000000..1f7bdd21b0d Binary files /dev/null and b/doc/user/project/settings/img/export_1.png differ diff --git a/doc/user/project/settings/img/export_3.png b/doc/user/project/settings/img/export_3.png new file mode 100644 index 00000000000..c123f83eb8e Binary files /dev/null and b/doc/user/project/settings/img/export_3.png differ diff --git a/doc/user/project/settings/img/export_4.png b/doc/user/project/settings/img/export_4.png new file mode 100644 index 00000000000..a2f7f0085c1 Binary files /dev/null and b/doc/user/project/settings/img/export_4.png differ diff --git a/doc/user/project/settings/img/import_1.png b/doc/user/project/settings/img/import_1.png new file mode 100644 index 00000000000..b3a7f201018 Binary files /dev/null and b/doc/user/project/settings/img/import_1.png differ diff --git a/doc/user/project/settings/img/import_2.png b/doc/user/project/settings/img/import_2.png new file mode 100644 index 00000000000..f31832af3e1 Binary files /dev/null and b/doc/user/project/settings/img/import_2.png differ diff --git a/doc/user/project/settings/import_export.md b/doc/user/project/settings/import_export.md new file mode 100644 index 00000000000..618f9948e12 --- /dev/null +++ b/doc/user/project/settings/import_export.md @@ -0,0 +1,65 @@ +# Project import/export + +Existing projects running on any GitLab instance or GitLab.com can be exported +with all their related data and be moved into a new GitLab instance. + +>**Note:** + - This feature was [introduced][ce-3050] in GitLab 8.9 + - Importing will not be possible if the import instance version is lower + than that of the exporter. + +## Exported contents + +- The following items will be exported: + - Project and wiki repositories + - Project uploads + - Project configuration including web hooks and services + - Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, + and other project entities +- The following items will NOT be exported: + - Build traces and artifacts + - LFS objects + +## Exporting a project and its data + +1. Go to the project settings page and find the Export button + + ![export_1](./img/export_1.png) + +1. Once the export is generated, you should receive an e-mail with a link to download the file + + ![export_3](./img/export_3.png) + +1. You can come back to project settings and download the file from there, or delete it so it +can be generated again + + ![export_4](./img/export_4.png) + +## Importing the project + +1. The new GitLab project import feature is at the far right of the import options on New Project + + ![import_1](./img/import_1.png) + +1. After choosing a namespace or path, you can then select the file exported previously + + ![import_2](./img/import_2.png) + +1. Click on Import to begin importing and you will see your newly imported project page soon + + +## Advanced + +The GitLab Import/Export version can be checked by using: + +```bash +sudo gitlab-rake gitlab:import_export:version +``` + +The current list of DB tables that will get exported can be listed by using: + +```bash +sudo gitlab-rake gitlab:import_export:data +``` + +[ce-3050]: https://gitlab.com/gitlab-org/gitlab-ce/issues/3050 diff --git a/doc/workflow/import_export/img/export_1.png b/doc/workflow/import_export/img/export_1.png deleted file mode 100644 index 1f7bdd21b0d..00000000000 Binary files a/doc/workflow/import_export/img/export_1.png and /dev/null differ diff --git a/doc/workflow/import_export/img/export_3.png b/doc/workflow/import_export/img/export_3.png deleted file mode 100644 index c123f83eb8e..00000000000 Binary files a/doc/workflow/import_export/img/export_3.png and /dev/null differ diff --git a/doc/workflow/import_export/img/export_4.png b/doc/workflow/import_export/img/export_4.png deleted file mode 100644 index a2f7f0085c1..00000000000 Binary files a/doc/workflow/import_export/img/export_4.png and /dev/null differ diff --git a/doc/workflow/import_export/img/import_1.png b/doc/workflow/import_export/img/import_1.png deleted file mode 100644 index b3a7f201018..00000000000 Binary files a/doc/workflow/import_export/img/import_1.png and /dev/null differ diff --git a/doc/workflow/import_export/img/import_2.png b/doc/workflow/import_export/img/import_2.png deleted file mode 100644 index f31832af3e1..00000000000 Binary files a/doc/workflow/import_export/img/import_2.png and /dev/null differ -- cgit v1.2.1 From 8b8cef4ca505c4787829d1c61efda4ad6f8608d5 Mon Sep 17 00:00:00 2001 From: DJ Mountney Date: Mon, 20 Jun 2016 15:38:02 -0700 Subject: Add documentation and examples for configuring cloud storage for registry images. --- doc/administration/container_registry.md | 75 +++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 2 deletions(-) diff --git a/doc/administration/container_registry.md b/doc/administration/container_registry.md index 7870669fa77..de225385c7a 100644 --- a/doc/administration/container_registry.md +++ b/doc/administration/container_registry.md @@ -22,6 +22,7 @@ You can read more about Docker Registry at https://docs.docker.com/registry/intr - [Disable Container Registry per project](#disable-container-registry-per-project) - [Disable Container Registry for new projects site-wide](#disable-container-registry-for-new-projects-site-wide) - [Container Registry storage path](#container-registry-storage-path) +- [Container Registry storage driver](#container-registry-storage-driver) - [Storage limitations](#storage-limitations) - [Changelog](#changelog) @@ -306,8 +307,12 @@ the Container Registry by themselves, follow the steps below. ## Container Registry storage path -To change the storage path where Docker images will be stored, follow the -steps below. +>**Note:** +For configuring storage in the cloud instead of the filesystem, see the +[storage driver configuration](#container-registry-storage-driver). + +If you want to store your images on the filesystem, you can change the storage +path for the Container Registry, follow the steps below. This path is accessible to: @@ -349,6 +354,72 @@ The default location where images are stored in source installations, is 1. Save the file and [restart GitLab][] for the changes to take effect. +## Container Registry storage driver + +You can configure the Container Registry to use a different storage backend by +configuring a different storage driver. By default the GitLab Container Registry +is configured to use the filesystem driver, which makes use of [storage path](#container-registry-storage-path) +configuration. + +The different supported drivers are: + +| Driver | Description | +|------------|-------------------------------------| +| filesystem | Uses a path on the local filesystem | +| azure | Microsoft Azure Blob Storage | +| gcs | Google Cloud Storage | +| s3 | Amazon Simple Storage Service | +| swift | OpenStack Swift Object Storage | +| oss | Aliyun OSS | + +Read more about the individual driver's config options in the +[Docker Registry docs][storage-config]. + +> **Warning** GitLab will not backup Docker images that are not stored on the +filesystem. Remember to enable backups with your object storage provider if +desired. + +--- + +**Omnibus GitLab installations** + +To configure the storage driver in Omnibus: + +1. Edit `/etc/gitlab/gitlab.rb`: + + ```ruby + registry['storage'] = { + 's3' => { + 'accesskey' => 's3-access-key', + 'secretkey' => 's3-secret-key-for-access-key', + 'bucket' => 'your-s3-bucket' + } + } + ``` + +1. Save the file and [reconfigure GitLab][] for the changes to take effect. + +--- + +**Installations from source** + +Configuring the storage driver is done in your registry config YML file created +when you [deployed your docker registry][registry-deploy]. + +Example: + +``` +storage: + s3: + accesskey: 'AKIAKIAKI' + secretkey: 'secret123' + bucket: 'gitlab-registry-bucket-AKIAKIAKI' + cache: + blobdescriptor: inmemory + delete: + enabled: true +``` + ## Storage limitations Currently, there is no storage limitation, which means a user can upload an -- cgit v1.2.1 From b2732f3af104fe31aed126505a5b7e4fa1a62f71 Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Tue, 21 Jun 2016 20:07:52 +0200 Subject: Refactor project import/export documentation --- .../raketasks/project_import_export.md | 28 ++++++++ .../project/settings/img/settings_edit_button.png | Bin 0 -> 19392 bytes doc/user/project/settings/import_export.md | 76 ++++++++++----------- 3 files changed, 66 insertions(+), 38 deletions(-) create mode 100644 doc/administration/raketasks/project_import_export.md create mode 100644 doc/user/project/settings/img/settings_edit_button.png diff --git a/doc/administration/raketasks/project_import_export.md b/doc/administration/raketasks/project_import_export.md new file mode 100644 index 00000000000..e5cb0308cbb --- /dev/null +++ b/doc/administration/raketasks/project_import_export.md @@ -0,0 +1,28 @@ +# Project import/export + +>**Note:** + - This feature was [introduced][ce-3050] in GitLab 8.9 + - Importing will not be possible if the import instance version is lower + than that of the exporter. + +The GitLab Import/Export version can be checked by using: + +```bash +# Omnibus installations +sudo gitlab-rake gitlab:import_export:version + +# Installations from source +bundle exec rake gitlab:import_export:version RAILS_ENV=production +``` + +The current list of DB tables that will get exported can be listed by using: + +```bash +# Omnibus installations +sudo gitlab-rake gitlab:import_export:data + +# Installations from source +bundle exec rake gitlab:import_export:data RAILS_ENV=production +``` + +[ce-3050]: https://gitlab.com/gitlab-org/gitlab-ce/issues/3050 diff --git a/doc/user/project/settings/img/settings_edit_button.png b/doc/user/project/settings/img/settings_edit_button.png new file mode 100644 index 00000000000..3c0cee536de Binary files /dev/null and b/doc/user/project/settings/img/settings_edit_button.png differ diff --git a/doc/user/project/settings/import_export.md b/doc/user/project/settings/import_export.md index 618f9948e12..7cc31e9dc4e 100644 --- a/doc/user/project/settings/import_export.md +++ b/doc/user/project/settings/import_export.md @@ -1,65 +1,65 @@ # Project import/export +>**Note:** + - This feature was [introduced][ce-3050] in GitLab 8.9 + - Importing will not be possible if the import instance version is lower + than that of the exporter. + - You can find some useful raketasks if you are an administrator in the + [project_import_export](../../../administration/raketasks/project_import_export.md) + raketask. + Existing projects running on any GitLab instance or GitLab.com can be exported with all their related data and be moved into a new GitLab instance. ->**Note:** - - This feature was [introduced][ce-3050] in GitLab 8.9 - - Importing will not be possible if the import instance version is lower - than that of the exporter. - ## Exported contents - -- The following items will be exported: - - Project and wiki repositories - - Project uploads - - Project configuration including web hooks and services - - Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, - and other project entities -- The following items will NOT be exported: - - Build traces and artifacts - - LFS objects -## Exporting a project and its data +The following items will be exported: -1. Go to the project settings page and find the Export button +- Project and wiki repositories +- Project uploads +- Project configuration including web hooks and services +- Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, + and other project entities - ![export_1](./img/export_1.png) +The following items will NOT be exported: -1. Once the export is generated, you should receive an e-mail with a link to download the file +- Build traces and artifacts +- LFS objects - ![export_3](./img/export_3.png) +## Exporting a project and its data -1. You can come back to project settings and download the file from there, or delete it so it -can be generated again +1. Go to the project settings page by clicking on **Edit Project** - ![export_4](./img/export_4.png) + ![Project settings button](img/settings_edit_button.png) -## Importing the project +1. Scroll down to find the **Export project** button -1. The new GitLab project import feature is at the far right of the import options on New Project + ![export_1](./img/export_1.png) - ![import_1](./img/import_1.png) +1. Once the export is generated, you should receive an e-mail with a link to + download the file -1. After choosing a namespace or path, you can then select the file exported previously + ![export_3](./img/export_3.png) - ![import_2](./img/import_2.png) +1. Alternatively, you can come back to the project settings and download the + file from there, or generate a new export -1. Click on Import to begin importing and you will see your newly imported project page soon + ![export_4](./img/export_4.png) +## Importing the project -## Advanced +1. The new GitLab project import feature is at the far right of the import + options when creating a New Project. Make sure you are in the right namespace + and you have entered a project name. Click on **GitLab export** -The GitLab Import/Export version can be checked by using: + ![import_1](./img/import_1.png) -```bash -sudo gitlab-rake gitlab:import_export:version -``` +1. You can see where the project will be imported to. You can now select file + exported previously -The current list of DB tables that will get exported can be listed by using: + ![import_2](./img/import_2.png) -```bash -sudo gitlab-rake gitlab:import_export:data -``` +1. Click on **Import project** to begin importing. Your newly imported project + page will appear soon [ce-3050]: https://gitlab.com/gitlab-org/gitlab-ce/issues/3050 -- cgit v1.2.1 From 795b8b3073c3ee65921ec01b5e1cd2524705a7ef Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Tue, 21 Jun 2016 13:16:28 -0500 Subject: Update gray block under subnav to match other pages --- app/assets/stylesheets/framework/blocks.scss | 16 +++++++++++++ app/views/projects/compare/index.html.haml | 2 +- app/views/projects/compare/show.html.haml | 36 ++++++++++++++-------------- 3 files changed, 35 insertions(+), 19 deletions(-) diff --git a/app/assets/stylesheets/framework/blocks.scss b/app/assets/stylesheets/framework/blocks.scss index d5fe5bc2ef1..38023818709 100644 --- a/app/assets/stylesheets/framework/blocks.scss +++ b/app/assets/stylesheets/framework/blocks.scss @@ -97,6 +97,22 @@ } } +.sub-header-block { + background-color: $white-light; + border-bottom: 1px solid $white-dark; + padding: 11px 0; + margin-bottom: 11px; + + .oneline { + line-height: 35px; + } + + &.no-bottom-space { + border-bottom: 0; + margin-bottom: 0; + } +} + .cover-block { text-align: center; background: $background-color; diff --git a/app/views/projects/compare/index.html.haml b/app/views/projects/compare/index.html.haml index c322942aeba..b22285c11e0 100644 --- a/app/views/projects/compare/index.html.haml +++ b/app/views/projects/compare/index.html.haml @@ -3,7 +3,7 @@ = render "projects/commits/head" %div{ class: (container_class) } - .row-content-block.second-block.content-component-block + .sub-header-block Compare branches, tags or commit ranges. %br Fill input field with commit id like diff --git a/app/views/projects/compare/show.html.haml b/app/views/projects/compare/show.html.haml index cdc34f51d6d..f4ec7b767f6 100644 --- a/app/views/projects/compare/show.html.haml +++ b/app/views/projects/compare/show.html.haml @@ -1,24 +1,24 @@ +- @no_container = true - page_title "#{params[:from]}...#{params[:to]}" = render "projects/commits/head" +%div{ class: (container_class) } + .sub-header-block.no-bottom-space + = render "form" -.row-content-block - = render "form" - -- if @commits.present? - .prepend-top-default + - if @commits.present? = render "projects/commits/commit_list" = render "projects/diffs/diffs", diffs: @diffs, project: @project, diff_refs: @diff_refs -- else - .light-well.prepend-top-default - .center - %h4 - There isn't anything to compare. - %p.slead - - if params[:to] == params[:from] - %span.label-branch #{params[:from]} - and - %span.label-branch #{params[:to]} - are the same. - - else - You'll need to use different branch names to get a valid comparison. + - else + .light-well + .center + %h4 + There isn't anything to compare. + %p.slead + - if params[:to] == params[:from] + %span.label-branch #{params[:from]} + and + %span.label-branch #{params[:to]} + are the same. + - else + You'll need to use different branch names to get a valid comparison. -- cgit v1.2.1 From 07b3bf9ec3900324195566c0d4aeb05abfdb9277 Mon Sep 17 00:00:00 2001 From: Connor Shea Date: Tue, 21 Jun 2016 10:00:08 -0600 Subject: Fix Network graph links. Resolves #18894. --- app/views/projects/network/show.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/projects/network/show.html.haml b/app/views/projects/network/show.html.haml index e4ab064eda8..de767e1979d 100644 --- a/app/views/projects/network/show.html.haml +++ b/app/views/projects/network/show.html.haml @@ -15,5 +15,5 @@ = check_box_tag :filter_ref, 1, @options[:filter_ref] %span Begin with the selected commit - .network-graph{ data: { url: '#{escape_javascript(@url)}', commit_url: '#{escape_javascript(@commit_url)}', ref: '#{escape_javascript(@ref)}', commit_id: '#{escape_javascript(@commit.id)}' } } + .network-graph{ data: { url: "#{@url}", commit_url: "#{@commit_url}", ref: "#{@ref}", commit_id: "#{@commit.id}" } } = spinner nil, true -- cgit v1.2.1 From 91a112cba452857a80233986be359a3a4f9a288c Mon Sep 17 00:00:00 2001 From: Connor Shea Date: Tue, 21 Jun 2016 12:35:55 -0600 Subject: Remove unnecessary string interpolation. --- app/views/projects/network/show.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/projects/network/show.html.haml b/app/views/projects/network/show.html.haml index de767e1979d..593af319a47 100644 --- a/app/views/projects/network/show.html.haml +++ b/app/views/projects/network/show.html.haml @@ -15,5 +15,5 @@ = check_box_tag :filter_ref, 1, @options[:filter_ref] %span Begin with the selected commit - .network-graph{ data: { url: "#{@url}", commit_url: "#{@commit_url}", ref: "#{@ref}", commit_id: "#{@commit.id}" } } + .network-graph{ data: { url: @url, commit_url: @commit_url, ref: @ref, commit_id: @commit.id } } = spinner nil, true -- cgit v1.2.1 From a6faaace0503c27884808740e002c201b8893375 Mon Sep 17 00:00:00 2001 From: Connor Shea Date: Tue, 21 Jun 2016 14:10:00 -0600 Subject: Expand on Award Emoji documentation, update/add screenshots. [ci skip] --- doc/workflow/award_emoji.md | 45 ++++++++++++++++------- doc/workflow/award_emoji.png | Bin 6620 -> 16926 bytes doc/workflow/img/award_emoji_comment_awarded.png | Bin 0 -> 64317 bytes doc/workflow/img/award_emoji_comment_picker.png | Bin 0 -> 250861 bytes 4 files changed, 31 insertions(+), 14 deletions(-) create mode 100644 doc/workflow/img/award_emoji_comment_awarded.png create mode 100644 doc/workflow/img/award_emoji_comment_picker.png diff --git a/doc/workflow/award_emoji.md b/doc/workflow/award_emoji.md index 70b35c58be6..e6f8b792707 100644 --- a/doc/workflow/award_emoji.md +++ b/doc/workflow/award_emoji.md @@ -1,28 +1,26 @@ -# Award emojis +# Award emoji >**Note:** This feature was [introduced][1825] in GitLab 8.2. When you're collaborating online, you get fewer opportunities for high-fives -and thumbs-ups. In order to make virtual celebrations easier, you can now vote -on issues and merge requests using emoji! +and thumbs-ups. Emoji can be awarded to issues and merge requests, making +virtual celebrations easier. ![Award emoji](img/award_emoji_select.png) -This makes it much easier to give and receive feedback, without a long comment -thread. Any comment that contains only the thumbs up or down emojis is -converted to a vote and depicted in the emoji area. - -You can then use that functionality to sort issues and merge requests based on -popularity. +Award emoji make it much easier to give and receive feedback without a long +comment thread. Comments that are only emoji will automatically become +award emoji. ## Sort issues and merge requests on vote count >**Note:** This feature was [introduced][2871] in GitLab 8.5. -You can quickly sort the issues or merge requests by the number of votes they -have received. The sort option can be found in the right dropdown menu. +You can quickly sort issues and merge requests by the number of votes they +have received. The sort options can be found in the dropdown menu as "Most +popular" and "Least popular". ![Votes sort options](img/award_emoji_votes_sort_options.png) @@ -40,9 +38,28 @@ Sort by least popular issues/merge requests. --- -The number of upvotes and downvotes is not summed up. That means that an issue -with 18 upvotes and 5 downvotes is considered more popular than an issue with -17 upvotes and no downvotes. +The total number of votes is not summed up. An issue with 18 upvotes and 5 +downvotes is considered more popular than an issue with 17 upvotes and no +downvotes. + +## Award emoji for comments + +>**Note:** +This feature was [introduced][4291] in GitLab 8.9. + +Award emoji can also be applied to individual comments when you want to +celebrate an accomplishment or agree with an opinion. + +To add an award emoji, click the smile in the top right of the comment and pick +an emoji from the dropdown. + +![Picking an emoji for a comment](img/award_emoji_comment_picker.png) + +![An award emoji has been applied to a comment](img/award_emoji_comment_awarded.png) + +If you want to remove an award emoji, just click the emoji again and the vote +will be removed. [2871]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/2781 [1825]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/1825 +[4291]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/4291 diff --git a/doc/workflow/award_emoji.png b/doc/workflow/award_emoji.png index fb26ee04393..3408ed95841 100644 Binary files a/doc/workflow/award_emoji.png and b/doc/workflow/award_emoji.png differ diff --git a/doc/workflow/img/award_emoji_comment_awarded.png b/doc/workflow/img/award_emoji_comment_awarded.png new file mode 100644 index 00000000000..67697831869 Binary files /dev/null and b/doc/workflow/img/award_emoji_comment_awarded.png differ diff --git a/doc/workflow/img/award_emoji_comment_picker.png b/doc/workflow/img/award_emoji_comment_picker.png new file mode 100644 index 00000000000..d9c3faecdca Binary files /dev/null and b/doc/workflow/img/award_emoji_comment_picker.png differ -- cgit v1.2.1 From 76c6b9c8d87f8e89b046becdfa055845642aef4a Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 21 Jun 2016 23:54:00 +0300 Subject: Put wiki page history content into container Signed-off-by: Dmitriy Zaporozhets --- app/views/projects/wikis/history.html.haml | 66 +++++++++++++++--------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/app/views/projects/wikis/history.html.haml b/app/views/projects/wikis/history.html.haml index 45460ed9f41..630ee35b70b 100644 --- a/app/views/projects/wikis/history.html.haml +++ b/app/views/projects/wikis/history.html.haml @@ -1,37 +1,37 @@ - page_title "History", @page.title.capitalize, "Wiki" = render 'nav' +%div{ class: (container_class) } + .top-area + .nav-text + %strong + = link_to @page.title.capitalize, namespace_project_wiki_path(@project.namespace, @project, @page) + %span.light + · + History -.top-area - .nav-text - %strong - = link_to @page.title.capitalize, namespace_project_wiki_path(@project.namespace, @project, @page) - %span.light - · - History - -.table-holder - %table.table - %thead - %tr - %th Page version - %th Author - %th Commit Message - %th Last updated - %th Format - %tbody - - @page.versions.each_with_index do |version, index| - - commit = version + .table-holder + %table.table + %thead %tr - %td - = link_to project_wiki_path_with_version(@project, @page, - commit.id, index == 0) do - = truncate_sha(commit.id) - %td - = commit.author.name - %td - = commit.message - %td - #{time_ago_with_tooltip(version.authored_date)} - %td - %strong - = @page.page.wiki.page(@page.page.name, commit.id).try(:format) + %th Page version + %th Author + %th Commit Message + %th Last updated + %th Format + %tbody + - @page.versions.each_with_index do |version, index| + - commit = version + %tr + %td + = link_to project_wiki_path_with_version(@project, @page, + commit.id, index == 0) do + = truncate_sha(commit.id) + %td + = commit.author.name + %td + = commit.message + %td + #{time_ago_with_tooltip(version.authored_date)} + %td + %strong + = @page.page.wiki.page(@page.page.name, commit.id).try(:format) -- cgit v1.2.1 From 82b32c286ab519b94d6b5d5467b05b43b9b31fc9 Mon Sep 17 00:00:00 2001 From: Mark Pundsack Date: Tue, 21 Jun 2016 22:15:21 -0700 Subject: Fix link --- doc/ci/quick_start/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/ci/quick_start/README.md b/doc/ci/quick_start/README.md index c32b69aad8b..7fa1a478f34 100644 --- a/doc/ci/quick_start/README.md +++ b/doc/ci/quick_start/README.md @@ -241,4 +241,4 @@ CI with various languages. [runner]: ../runners/README.md [enabled]: ../enable_or_disable_ci.md [stages]: ../yaml/README.md#stages -[pipeline]: ../definitions/README.md#pipelines +[pipeline]: ../pipelines.md -- cgit v1.2.1 From d19379e00d95a3153bfe608ba0404cdbf82d5246 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 22 Jun 2016 07:39:08 +0200 Subject: fix typo --- app/views/notify/project_was_not_exported_email.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/notify/project_was_not_exported_email.html.haml b/app/views/notify/project_was_not_exported_email.html.haml index c9e9ade2cf1..c888da29c17 100644 --- a/app/views/notify/project_was_not_exported_email.html.haml +++ b/app/views/notify/project_was_not_exported_email.html.haml @@ -6,4 +6,4 @@ %ul - @errors.each do |error| %li - error + #{error} -- cgit v1.2.1 From 6eaf34685ef6a4f2d43efce8529c1434e16a28e2 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 22 Jun 2016 06:06:50 +0000 Subject: Add note about settings --- doc/administration/raketasks/project_import_export.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/administration/raketasks/project_import_export.md b/doc/administration/raketasks/project_import_export.md index e5cb0308cbb..f64f10d3260 100644 --- a/doc/administration/raketasks/project_import_export.md +++ b/doc/administration/raketasks/project_import_export.md @@ -4,6 +4,8 @@ - This feature was [introduced][ce-3050] in GitLab 8.9 - Importing will not be possible if the import instance version is lower than that of the exporter. + - For existing installations, the project import option has to be enabled in + application settings (admin area). The GitLab Import/Export version can be checked by using: -- cgit v1.2.1 From 5adc08596287ccb28e0b6489896b71d4943750ae Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 22 Jun 2016 08:48:18 +0200 Subject: refactor to use haml instead --- app/views/notify/project_was_not_exported_email.text.erb | 6 ------ app/views/notify/project_was_not_exported_email.text.haml | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-) delete mode 100644 app/views/notify/project_was_not_exported_email.text.erb create mode 100644 app/views/notify/project_was_not_exported_email.text.haml diff --git a/app/views/notify/project_was_not_exported_email.text.erb b/app/views/notify/project_was_not_exported_email.text.erb deleted file mode 100644 index a07f6edacf7..00000000000 --- a/app/views/notify/project_was_not_exported_email.text.erb +++ /dev/null @@ -1,6 +0,0 @@ -Project <%= @project.name %> couldn't be exported. - -The errors we encountered were: - -- @errors.each do |error| -<%= error %> \ No newline at end of file diff --git a/app/views/notify/project_was_not_exported_email.text.haml b/app/views/notify/project_was_not_exported_email.text.haml new file mode 100644 index 00000000000..b27cb620b9e --- /dev/null +++ b/app/views/notify/project_was_not_exported_email.text.haml @@ -0,0 +1,6 @@ += "Project #{@project.name} couldn't be exported." + += "The errors we encountered were:" + +- @errors.each do |error| + #{error} \ No newline at end of file -- cgit v1.2.1 From c0237a824b714dde69c4697d244a33539f6185d3 Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Wed, 22 Jun 2016 10:28:01 +0200 Subject: Remove old doc --- doc/workflow/import_export/README.md | 65 ------------------------------------ 1 file changed, 65 deletions(-) delete mode 100644 doc/workflow/import_export/README.md diff --git a/doc/workflow/import_export/README.md b/doc/workflow/import_export/README.md deleted file mode 100644 index 618f9948e12..00000000000 --- a/doc/workflow/import_export/README.md +++ /dev/null @@ -1,65 +0,0 @@ -# Project import/export - -Existing projects running on any GitLab instance or GitLab.com can be exported -with all their related data and be moved into a new GitLab instance. - ->**Note:** - - This feature was [introduced][ce-3050] in GitLab 8.9 - - Importing will not be possible if the import instance version is lower - than that of the exporter. - -## Exported contents - -- The following items will be exported: - - Project and wiki repositories - - Project uploads - - Project configuration including web hooks and services - - Issues with comments, merge requests with diffs and comments, labels, milestones, snippets, - and other project entities -- The following items will NOT be exported: - - Build traces and artifacts - - LFS objects - -## Exporting a project and its data - -1. Go to the project settings page and find the Export button - - ![export_1](./img/export_1.png) - -1. Once the export is generated, you should receive an e-mail with a link to download the file - - ![export_3](./img/export_3.png) - -1. You can come back to project settings and download the file from there, or delete it so it -can be generated again - - ![export_4](./img/export_4.png) - -## Importing the project - -1. The new GitLab project import feature is at the far right of the import options on New Project - - ![import_1](./img/import_1.png) - -1. After choosing a namespace or path, you can then select the file exported previously - - ![import_2](./img/import_2.png) - -1. Click on Import to begin importing and you will see your newly imported project page soon - - -## Advanced - -The GitLab Import/Export version can be checked by using: - -```bash -sudo gitlab-rake gitlab:import_export:version -``` - -The current list of DB tables that will get exported can be listed by using: - -```bash -sudo gitlab-rake gitlab:import_export:data -``` - -[ce-3050]: https://gitlab.com/gitlab-org/gitlab-ce/issues/3050 -- cgit v1.2.1 From e023e66c9f60201e7454bd11c7094f12340f1c47 Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Wed, 22 Jun 2016 11:05:34 +0200 Subject: Add note about enabling import/export in existing installations --- doc/administration/raketasks/project_import_export.md | 2 +- doc/user/project/settings/import_export.md | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/doc/administration/raketasks/project_import_export.md b/doc/administration/raketasks/project_import_export.md index f64f10d3260..c19ad7bfe34 100644 --- a/doc/administration/raketasks/project_import_export.md +++ b/doc/administration/raketasks/project_import_export.md @@ -5,7 +5,7 @@ - Importing will not be possible if the import instance version is lower than that of the exporter. - For existing installations, the project import option has to be enabled in - application settings (admin area). + application settings (`/admin/application_settings`) under 'Import sources'. The GitLab Import/Export version can be checked by using: diff --git a/doc/user/project/settings/import_export.md b/doc/user/project/settings/import_export.md index 7cc31e9dc4e..fa82d49172a 100644 --- a/doc/user/project/settings/import_export.md +++ b/doc/user/project/settings/import_export.md @@ -4,8 +4,12 @@ - This feature was [introduced][ce-3050] in GitLab 8.9 - Importing will not be possible if the import instance version is lower than that of the exporter. + - For existing installations, the project import option has to be enabled in + application settings (`/admin/application_settings`) under 'Import sources'. + Ask your administrator if you don't see the **GitLab export** button when + creating a new project. - You can find some useful raketasks if you are an administrator in the - [project_import_export](../../../administration/raketasks/project_import_export.md) + [import_export](../../../administration/raketasks/project_import_export.md) raketask. Existing projects running on any GitLab instance or GitLab.com can be exported -- cgit v1.2.1 From 10016715c1eb5b2eea7b5fbadcd72dc4104f6f49 Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Wed, 22 Jun 2016 11:15:28 +0200 Subject: Add colons in item lists --- doc/user/project/settings/import_export.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/doc/user/project/settings/import_export.md b/doc/user/project/settings/import_export.md index fa82d49172a..382f6e699db 100644 --- a/doc/user/project/settings/import_export.md +++ b/doc/user/project/settings/import_export.md @@ -32,21 +32,22 @@ The following items will NOT be exported: ## Exporting a project and its data -1. Go to the project settings page by clicking on **Edit Project** +1. Go to the project settings page by clicking on **Edit Project**: ![Project settings button](img/settings_edit_button.png) -1. Scroll down to find the **Export project** button +1. Scroll down to find the **Export project** button: ![export_1](./img/export_1.png) 1. Once the export is generated, you should receive an e-mail with a link to - download the file + download the file: ![export_3](./img/export_3.png) 1. Alternatively, you can come back to the project settings and download the - file from there, or generate a new export + file from there, or generate a new export. Once the file available, the page + should show the **Download export** button: ![export_4](./img/export_4.png) @@ -54,16 +55,16 @@ The following items will NOT be exported: 1. The new GitLab project import feature is at the far right of the import options when creating a New Project. Make sure you are in the right namespace - and you have entered a project name. Click on **GitLab export** + and you have entered a project name. Click on **GitLab export**: ![import_1](./img/import_1.png) 1. You can see where the project will be imported to. You can now select file - exported previously + exported previously: ![import_2](./img/import_2.png) 1. Click on **Import project** to begin importing. Your newly imported project - page will appear soon + page will appear soon: [ce-3050]: https://gitlab.com/gitlab-org/gitlab-ce/issues/3050 -- cgit v1.2.1 From a41b468816e499b96d9dab8f3cc3a41a11bd9ac5 Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Wed, 22 Jun 2016 11:31:07 +0200 Subject: Add note about the shared directory --- doc/administration/raketasks/project_import_export.md | 3 +++ doc/user/project/settings/import_export.md | 7 +++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/doc/administration/raketasks/project_import_export.md b/doc/administration/raketasks/project_import_export.md index c19ad7bfe34..c212059b9d5 100644 --- a/doc/administration/raketasks/project_import_export.md +++ b/doc/administration/raketasks/project_import_export.md @@ -6,6 +6,8 @@ than that of the exporter. - For existing installations, the project import option has to be enabled in application settings (`/admin/application_settings`) under 'Import sources'. + - The exports are stored in a temporary [shared directory][tmp] and are deleted + every 24 hours by a specific worker. The GitLab Import/Export version can be checked by using: @@ -28,3 +30,4 @@ bundle exec rake gitlab:import_export:data RAILS_ENV=production ``` [ce-3050]: https://gitlab.com/gitlab-org/gitlab-ce/issues/3050 +[tmp]: ../../development/shared_files.md diff --git a/doc/user/project/settings/import_export.md b/doc/user/project/settings/import_export.md index 382f6e699db..a460ff453db 100644 --- a/doc/user/project/settings/import_export.md +++ b/doc/user/project/settings/import_export.md @@ -1,6 +1,6 @@ # Project import/export ->**Note:** +>**Notes:** - This feature was [introduced][ce-3050] in GitLab 8.9 - Importing will not be possible if the import instance version is lower than that of the exporter. @@ -11,6 +11,8 @@ - You can find some useful raketasks if you are an administrator in the [import_export](../../../administration/raketasks/project_import_export.md) raketask. + - The exports are stored in a temporary [shared directory][tmp] and are deleted + every 24 hours by a specific worker. Existing projects running on any GitLab instance or GitLab.com can be exported with all their related data and be moved into a new GitLab instance. @@ -65,6 +67,7 @@ The following items will NOT be exported: ![import_2](./img/import_2.png) 1. Click on **Import project** to begin importing. Your newly imported project - page will appear soon: + page will appear soon. [ce-3050]: https://gitlab.com/gitlab-org/gitlab-ce/issues/3050 +[tmp]: ../../../development/shared_files.md -- cgit v1.2.1 From 51b51de77d9507e41467985bb34a6ee69ee99f3c Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Wed, 22 Jun 2016 11:41:50 +0200 Subject: Give images proper names --- doc/user/project/settings/img/export_1.png | Bin 84637 -> 0 bytes doc/user/project/settings/img/export_3.png | Bin 44012 -> 0 bytes doc/user/project/settings/img/export_4.png | Bin 85600 -> 0 bytes doc/user/project/settings/img/import_1.png | Bin 43574 -> 0 bytes doc/user/project/settings/img/import_2.png | Bin 46292 -> 0 bytes .../settings/img/import_export_download_export.png | Bin 0 -> 85600 bytes .../settings/img/import_export_export_button.png | Bin 0 -> 84637 bytes .../project/settings/img/import_export_mail_link.png | Bin 0 -> 44012 bytes .../project/settings/img/import_export_new_project.png | Bin 0 -> 43574 bytes .../project/settings/img/import_export_select_file.png | Bin 0 -> 46292 bytes doc/user/project/settings/import_export.md | 10 +++++----- 11 files changed, 5 insertions(+), 5 deletions(-) delete mode 100644 doc/user/project/settings/img/export_1.png delete mode 100644 doc/user/project/settings/img/export_3.png delete mode 100644 doc/user/project/settings/img/export_4.png delete mode 100644 doc/user/project/settings/img/import_1.png delete mode 100644 doc/user/project/settings/img/import_2.png create mode 100644 doc/user/project/settings/img/import_export_download_export.png create mode 100644 doc/user/project/settings/img/import_export_export_button.png create mode 100644 doc/user/project/settings/img/import_export_mail_link.png create mode 100644 doc/user/project/settings/img/import_export_new_project.png create mode 100644 doc/user/project/settings/img/import_export_select_file.png diff --git a/doc/user/project/settings/img/export_1.png b/doc/user/project/settings/img/export_1.png deleted file mode 100644 index 1f7bdd21b0d..00000000000 Binary files a/doc/user/project/settings/img/export_1.png and /dev/null differ diff --git a/doc/user/project/settings/img/export_3.png b/doc/user/project/settings/img/export_3.png deleted file mode 100644 index c123f83eb8e..00000000000 Binary files a/doc/user/project/settings/img/export_3.png and /dev/null differ diff --git a/doc/user/project/settings/img/export_4.png b/doc/user/project/settings/img/export_4.png deleted file mode 100644 index a2f7f0085c1..00000000000 Binary files a/doc/user/project/settings/img/export_4.png and /dev/null differ diff --git a/doc/user/project/settings/img/import_1.png b/doc/user/project/settings/img/import_1.png deleted file mode 100644 index b3a7f201018..00000000000 Binary files a/doc/user/project/settings/img/import_1.png and /dev/null differ diff --git a/doc/user/project/settings/img/import_2.png b/doc/user/project/settings/img/import_2.png deleted file mode 100644 index f31832af3e1..00000000000 Binary files a/doc/user/project/settings/img/import_2.png and /dev/null differ diff --git a/doc/user/project/settings/img/import_export_download_export.png b/doc/user/project/settings/img/import_export_download_export.png new file mode 100644 index 00000000000..a2f7f0085c1 Binary files /dev/null and b/doc/user/project/settings/img/import_export_download_export.png differ diff --git a/doc/user/project/settings/img/import_export_export_button.png b/doc/user/project/settings/img/import_export_export_button.png new file mode 100644 index 00000000000..1f7bdd21b0d Binary files /dev/null and b/doc/user/project/settings/img/import_export_export_button.png differ diff --git a/doc/user/project/settings/img/import_export_mail_link.png b/doc/user/project/settings/img/import_export_mail_link.png new file mode 100644 index 00000000000..c123f83eb8e Binary files /dev/null and b/doc/user/project/settings/img/import_export_mail_link.png differ diff --git a/doc/user/project/settings/img/import_export_new_project.png b/doc/user/project/settings/img/import_export_new_project.png new file mode 100644 index 00000000000..b3a7f201018 Binary files /dev/null and b/doc/user/project/settings/img/import_export_new_project.png differ diff --git a/doc/user/project/settings/img/import_export_select_file.png b/doc/user/project/settings/img/import_export_select_file.png new file mode 100644 index 00000000000..f31832af3e1 Binary files /dev/null and b/doc/user/project/settings/img/import_export_select_file.png differ diff --git a/doc/user/project/settings/import_export.md b/doc/user/project/settings/import_export.md index a460ff453db..38e9786123d 100644 --- a/doc/user/project/settings/import_export.md +++ b/doc/user/project/settings/import_export.md @@ -40,18 +40,18 @@ The following items will NOT be exported: 1. Scroll down to find the **Export project** button: - ![export_1](./img/export_1.png) + ![Export button](img/import_export_export_button.png) 1. Once the export is generated, you should receive an e-mail with a link to download the file: - ![export_3](./img/export_3.png) + ![Email download link](img/import_export_mail_link.png) 1. Alternatively, you can come back to the project settings and download the file from there, or generate a new export. Once the file available, the page should show the **Download export** button: - ![export_4](./img/export_4.png) + ![Download export](img/import_export_download_export.png) ## Importing the project @@ -59,12 +59,12 @@ The following items will NOT be exported: options when creating a New Project. Make sure you are in the right namespace and you have entered a project name. Click on **GitLab export**: - ![import_1](./img/import_1.png) + ![New project](img/import_export_new_project.png) 1. You can see where the project will be imported to. You can now select file exported previously: - ![import_2](./img/import_2.png) + ![Select file](img/import_export_select_file.png) 1. Click on **Import project** to begin importing. Your newly imported project page will appear soon. -- cgit v1.2.1 From 78186c68ffc1180086c669726e14f815fda552d5 Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Wed, 22 Jun 2016 13:50:02 +0200 Subject: Refactor labels documentation - Add new images to match the new UI - Document the new prioritize feature --- .../img/labels_assign_label_in_new_issue.png | Bin 26380 -> 31126 bytes .../project/img/labels_assign_label_sidebar.png | Bin 30137 -> 31537 bytes .../img/labels_assign_label_sidebar_saved.png | Bin 25488 -> 28396 bytes doc/user/project/img/labels_default.png | Bin 58717 -> 80403 bytes .../project/img/labels_description_tooltip.png | Bin 39315 -> 22585 bytes doc/user/project/img/labels_filter.png | Bin 86911 -> 81536 bytes doc/user/project/img/labels_filter_by_priority.png | Bin 0 -> 60849 bytes doc/user/project/img/labels_generate.png | Bin 29986 -> 31608 bytes doc/user/project/img/labels_new_label.png | Bin 29671 -> 43265 bytes .../project/img/labels_new_label_on_the_fly.png | Bin 11586 -> 10416 bytes .../img/labels_new_label_on_the_fly_create.png | Bin 20604 -> 16151 bytes doc/user/project/img/labels_prioritize.png | Bin 0 -> 108751 bytes doc/user/project/img/labels_subscribe.png | Bin 50177 -> 11536 bytes doc/user/project/labels.md | 82 ++++++++++++++------- 14 files changed, 56 insertions(+), 26 deletions(-) create mode 100644 doc/user/project/img/labels_filter_by_priority.png create mode 100644 doc/user/project/img/labels_prioritize.png diff --git a/doc/user/project/img/labels_assign_label_in_new_issue.png b/doc/user/project/img/labels_assign_label_in_new_issue.png index 72bbf9a0594..e32a35f7cda 100644 Binary files a/doc/user/project/img/labels_assign_label_in_new_issue.png and b/doc/user/project/img/labels_assign_label_in_new_issue.png differ diff --git a/doc/user/project/img/labels_assign_label_sidebar.png b/doc/user/project/img/labels_assign_label_sidebar.png index ffbbf5b8d21..799443af889 100644 Binary files a/doc/user/project/img/labels_assign_label_sidebar.png and b/doc/user/project/img/labels_assign_label_sidebar.png differ diff --git a/doc/user/project/img/labels_assign_label_sidebar_saved.png b/doc/user/project/img/labels_assign_label_sidebar_saved.png index 2771b02735f..e7d8d69e60e 100644 Binary files a/doc/user/project/img/labels_assign_label_sidebar_saved.png and b/doc/user/project/img/labels_assign_label_sidebar_saved.png differ diff --git a/doc/user/project/img/labels_default.png b/doc/user/project/img/labels_default.png index 2d44eb4409b..ee0c9f889ad 100644 Binary files a/doc/user/project/img/labels_default.png and b/doc/user/project/img/labels_default.png differ diff --git a/doc/user/project/img/labels_description_tooltip.png b/doc/user/project/img/labels_description_tooltip.png index 887ef5f43a8..0d1e3e091fb 100644 Binary files a/doc/user/project/img/labels_description_tooltip.png and b/doc/user/project/img/labels_description_tooltip.png differ diff --git a/doc/user/project/img/labels_filter.png b/doc/user/project/img/labels_filter.png index 139b3b22e14..ed622be2d93 100644 Binary files a/doc/user/project/img/labels_filter.png and b/doc/user/project/img/labels_filter.png differ diff --git a/doc/user/project/img/labels_filter_by_priority.png b/doc/user/project/img/labels_filter_by_priority.png new file mode 100644 index 00000000000..c5a9e20919b Binary files /dev/null and b/doc/user/project/img/labels_filter_by_priority.png differ diff --git a/doc/user/project/img/labels_generate.png b/doc/user/project/img/labels_generate.png index 78eff8525bf..9579be4e231 100644 Binary files a/doc/user/project/img/labels_generate.png and b/doc/user/project/img/labels_generate.png differ diff --git a/doc/user/project/img/labels_new_label.png b/doc/user/project/img/labels_new_label.png index 6dc4fe8ce20..a916d3dceb5 100644 Binary files a/doc/user/project/img/labels_new_label.png and b/doc/user/project/img/labels_new_label.png differ diff --git a/doc/user/project/img/labels_new_label_on_the_fly.png b/doc/user/project/img/labels_new_label_on_the_fly.png index 4559c56dbda..80cc434239e 100644 Binary files a/doc/user/project/img/labels_new_label_on_the_fly.png and b/doc/user/project/img/labels_new_label_on_the_fly.png differ diff --git a/doc/user/project/img/labels_new_label_on_the_fly_create.png b/doc/user/project/img/labels_new_label_on_the_fly_create.png index ee75bc6ec92..c41090945eb 100644 Binary files a/doc/user/project/img/labels_new_label_on_the_fly_create.png and b/doc/user/project/img/labels_new_label_on_the_fly_create.png differ diff --git a/doc/user/project/img/labels_prioritize.png b/doc/user/project/img/labels_prioritize.png new file mode 100644 index 00000000000..8dfe72cf826 Binary files /dev/null and b/doc/user/project/img/labels_prioritize.png differ diff --git a/doc/user/project/img/labels_subscribe.png b/doc/user/project/img/labels_subscribe.png index f3c1a1b67e2..ea3db2bc0cf 100644 Binary files a/doc/user/project/img/labels_subscribe.png and b/doc/user/project/img/labels_subscribe.png differ diff --git a/doc/user/project/labels.md b/doc/user/project/labels.md index 93a14e7b8d7..4258185b7d0 100644 --- a/doc/user/project/labels.md +++ b/doc/user/project/labels.md @@ -15,11 +15,10 @@ that works. A permission level of `Developer` or higher is required in order to manage labels. -Head over a single project and navigate to the label page by clicking on -**Labels** in the left sidebar. +Head over a single project and navigate to **Issues > Labels**. -The first time you visit the **Labels** page you'll notice that there are no -labels created yet. +The first time you visit this page, you'll notice that there are no labels +created yet. ![Generate new labels](img/labels_generate.png) @@ -44,6 +43,48 @@ When you are ready press the **Create label** button to create the new label. ![New label](img/labels_new_label.png) +## Prioritize labels + +>**Notes:** + - This feature was introduced in GitLab 8.9. + - Priority sorting is based on the highest priority label only. This might + change in the future, follow the discussion in + https://gitlab.com/gitlab-org/gitlab-ce/issues/18554. + +Prioritized labels are like any other label, but sorted by priority. This allows +you to sort issues and merge requests by priority. + +To prioritize labels, navigate to your project's **Issues > Labels** and click +on the star icon next to them to put them in the priority list. Click on the +star icon again to remove them from the list. + +From there, you can drag them around to set the desired priority. Priority is +set from high to low with an ascending order. Labels with no priority, count as +having their priority set to null. + +![Prioritize labels](img/labels_prioritize.png) + +Now that you have labels prioritized, you can use the 'Priority' filter in the +issues or merge requests tracker. Those with the highest priority label, will +appear on top. + +![Filter labels by priority](img/labels_filter_by_priority.png) + +## Subscribe to labels + +If you don’t want to miss issues or merge requests that are important to you, +simply subscribe to a label. You’ll get notified whenever the label gets added +to an issue or merge request, making sure you don’t miss a thing. + +Go to your project's **Issues > Labels** area, find the label(s) you want to +subscribe to and click on the eye icon. Click again to unsubscribe. + +![Subscribe to labels](img/labels_subscribe.png) + +If you work on a large or popular project, try subscribing only to the labels +that are relevant to you. You’ll notice it’ll be much easier to focus on what’s +important. + ## Create a new label right from the issue tracker >**Note:** @@ -54,8 +95,8 @@ label, only to realize it doesn't exist. Instead of going to the **Labels** page and being distracted from your original purpose, you can create new labels on the fly. -Just hit **New Label** from the dropdown list, provide a name, pick a color -and hit **Create**. +Select **Create new** from the labels dropdown list, provide a name, pick a +color and hit **Create**. ![Create new label on the fly](img/labels_new_label_on_the_fly_create.png) ![New label on the fly](img/labels_new_label_on_the_fly.png) @@ -64,26 +105,25 @@ and hit **Create**. There are generally two ways to assign a label to an issue or merge request. ---- - You can assign a label when you first create or edit an issue or merge request. ![Assign label in new issue](img/labels_assign_label_in_new_issue.png) --- -The second way is by using the right sidebar. Expand it and hit **Edit**. Start -typing the name of the label you are looking for to narrow down the list and -select it. Once done, click outside the sidebar area for the changes to take -effect. +The second way is by using the right sidebar when inside an issue or merge +request. Expand it and hit **Edit** in the labels area. Start typing the name +of the label you are looking for to narrow down the list, and select it. You +can add more than one labels at once. When done, click outside the sidebar area +for the changes to take effect. ![Assign label in sidebar](img/labels_assign_label_sidebar.png) ![Save labels in sidebar](img/labels_assign_label_sidebar_saved.png) --- -To remove labels, follow the same procedure like when adding them and hit the -little **x** mark next to each one. +To remove labels, expand the left sidebar and unmark them from the labels list. +Simple as that. ## Use labels to filter issues @@ -100,18 +140,8 @@ label description like shown below. --- And if you added a description to your label, you can see it by hovering your -mouse over the label in the issue tracker. +mouse over the label in the issue tracker or wherever else the label is +rendered. ![Label tooltips](img/labels_description_tooltip.png) -## Subscribe to labels - -If you don’t want to miss issues or merge requests that are important to you, -simply subscribe to a label. You’ll get notified whenever the label gets added -to an issue or merge request, making sure you don’t miss a thing. - -![Subscribe to labels](img/labels_subscribe.png) - -If you work on a large or popular project, try subscribing only to the labels -that are relevant to you. You’ll notice it’ll be much easier to focus on what’s -important. -- cgit v1.2.1