Commit 9a7ada02 authored by Valery Sizov's avatar Valery Sizov

Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ce into ce_upstream

parents 51bdfb76 06c7d6f3
......@@ -193,7 +193,7 @@ Style/EmptyLineBetweenDefs:
# Don't use several empty lines in a row.
Style/EmptyLines:
Enabled: false
Enabled: true
# Keep blank lines around access modifiers.
Style/EmptyLinesAroundAccessModifier:
......
......@@ -10,6 +10,7 @@ v 8.10.0 (unreleased)
- Display last commit of deleted branch in push events !4699 (winniehell)
- Apply the trusted_proxies config to the rack request object for use with rack_attack
- Add Sidekiq queue duration to transaction metrics.
- Add a new column `artifacts_size` to table `ci_builds` !4964
- Let Workhorse serve format-patch diffs
- Make images fit to the size of the viewport !4810
- Fix check for New Branch button on Issue page !4630 (winniehell)
......@@ -31,12 +32,20 @@ v 8.10.0 (unreleased)
- Metrics for Rouge::Plugins::Redcarpet and Rouge::Formatters::HTMLGitlab
- Allow [ci skip] to be in any case and allow [skip ci]. !4785 (simon_w)
- Add basic system information like memory and disk usage to the admin panel
- Don't garbage collect commits that have related DB records like comments
- More descriptive message for git hooks and file locks
- Handle custom Git hook result in GitLab UI
v 8.9.4 (unreleased)
- Ensure references to private repos aren't shown to logged-out users
v 8.9.5 (unreleased)
- Improve the request / withdraw access button. !4860
- Fix assigning shared runners as admins. !4961
- Show "locked" label for locked runners on runners admin. !4961
- Downgrade to Redis 3.2.2 due to massive memory leak with Sidekiq
- Fixes issues importing events in Import/Export. Import/Export version bumped to 0.1.1
- Fix import button disabled when import process fail due to the namespace already been taken.
- Security: Update RedCloth to 4.3.2 (Takuya Noguchi)
v 8.9.4
- Fix privilege escalation issue with OAuth external users.
......
......@@ -117,7 +117,7 @@ gem 'html-pipeline', '~> 1.11.0'
gem 'task_list', '~> 1.0.2', require: 'task_list/railtie'
gem 'github-markup', '~> 1.3.1'
gem 'redcarpet', '~> 3.3.3'
gem 'RedCloth', '~> 4.2.9'
gem 'RedCloth', '~> 4.3.2'
gem 'rdoc', '~>3.6'
gem 'org-ruby', '~> 0.9.12'
gem 'creole', '~> 0.5.0'
......@@ -275,7 +275,7 @@ group :development do
gem "sdoc", '~> 0.3.20'
# thin instead webrick
gem 'thin', '~> 1.6.1'
gem 'thin', '~> 1.7.0'
end
group :development, :test do
......@@ -287,7 +287,7 @@ group :development, :test do
gem 'database_cleaner', '~> 1.4.0'
gem 'factory_girl_rails', '~> 4.6.0'
gem 'rspec-rails', '~> 3.4.0'
gem 'rspec-rails', '~> 3.5.0'
gem 'rspec-retry'
gem 'spinach-rails', '~> 0.2.1'
gem 'spinach-rerun-reporter', '~> 0.0.2'
......
GEM
remote: https://rubygems.org/
specs:
RedCloth (4.2.9)
RedCloth (4.3.2)
ace-rails-ap (4.0.2)
actionmailer (4.2.6)
actionpack (= 4.2.6)
......@@ -578,7 +578,7 @@ GEM
recaptcha (3.0.0)
json
redcarpet (3.3.3)
redis (3.3.0)
redis (3.2.2)
redis-actionpack (4.0.1)
actionpack (~> 4)
redis-rack (~> 1.5.0)
......@@ -609,29 +609,29 @@ GEM
chunky_png
rqrcode-rails3 (0.1.7)
rqrcode (>= 0.4.2)
rspec (3.4.0)
rspec-core (~> 3.4.0)
rspec-expectations (~> 3.4.0)
rspec-mocks (~> 3.4.0)
rspec-core (3.4.4)
rspec-support (~> 3.4.0)
rspec-expectations (3.4.0)
rspec (3.5.0)
rspec-core (~> 3.5.0)
rspec-expectations (~> 3.5.0)
rspec-mocks (~> 3.5.0)
rspec-core (3.5.0)
rspec-support (~> 3.5.0)
rspec-expectations (3.5.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.4.0)
rspec-mocks (3.4.1)
rspec-support (~> 3.5.0)
rspec-mocks (3.5.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.4.0)
rspec-rails (3.4.2)
actionpack (>= 3.0, < 4.3)
activesupport (>= 3.0, < 4.3)
railties (>= 3.0, < 4.3)
rspec-core (~> 3.4.0)
rspec-expectations (~> 3.4.0)
rspec-mocks (~> 3.4.0)
rspec-support (~> 3.4.0)
rspec-support (~> 3.5.0)
rspec-rails (3.5.0)
actionpack (>= 3.0)
activesupport (>= 3.0)
railties (>= 3.0)
rspec-core (~> 3.5.0)
rspec-expectations (~> 3.5.0)
rspec-mocks (~> 3.5.0)
rspec-support (~> 3.5.0)
rspec-retry (0.4.5)
rspec-core
rspec-support (3.4.1)
rspec-support (3.5.0)
rubocop (0.40.0)
parser (>= 2.3.1.0, < 3.0)
powerpack (~> 0.1)
......@@ -656,8 +656,8 @@ GEM
sanitize (2.1.0)
nokogiri (>= 1.4.4)
sass (3.4.22)
sass-rails (5.0.4)
railties (>= 4.0.0, < 5.0)
sass-rails (5.0.5)
railties (>= 4.0.0, < 6)
sass (~> 3.1)
sprockets (>= 2.8, < 4.0)
sprockets-rails (>= 2.0, < 4.0)
......@@ -671,9 +671,9 @@ GEM
sdoc (0.3.20)
json (>= 1.1.3)
rdoc (~> 3.10)
seed-fu (2.3.5)
activerecord (>= 3.1, < 4.3)
activesupport (>= 3.1, < 4.3)
seed-fu (2.3.6)
activerecord (>= 3.1)
activesupport (>= 3.1)
select2-rails (3.5.9.3)
thor (~> 0.14)
sentry-raven (1.1.0)
......@@ -684,10 +684,11 @@ GEM
rack
shoulda-matchers (2.8.0)
activesupport (>= 3.0.0)
sidekiq (4.1.2)
sidekiq (4.1.4)
concurrent-ruby (~> 1.0)
connection_pool (~> 2.2, >= 2.2.0)
redis (~> 3.2, >= 3.2.1)
sinatra (>= 1.4.7)
sidekiq-cron (0.4.0)
redis-namespace (>= 1.5.2)
rufus-scheduler (>= 2.0.24)
......@@ -698,8 +699,8 @@ GEM
json (~> 1.8)
simplecov-html (~> 0.10.0)
simplecov-html (0.10.0)
sinatra (1.4.6)
rack (~> 1.4)
sinatra (1.4.7)
rack (~> 1.5)
rack-protection (~> 1.4)
tilt (>= 1.3, < 3)
six (0.2.0)
......@@ -715,7 +716,7 @@ GEM
spinach (>= 0.4)
spinach-rerun-reporter (0.0.2)
spinach (~> 0.8)
spring (1.7.1)
spring (1.7.2)
spring-commands-rspec (1.0.4)
spring (>= 0.9.1)
spring-commands-spinach (1.1.0)
......@@ -749,10 +750,10 @@ GEM
temple (0.7.7)
test_after_commit (0.4.2)
activerecord (>= 3.2)
thin (1.6.4)
thin (1.7.0)
daemons (~> 1.0, >= 1.0.9)
eventmachine (~> 1.0, >= 1.0.4)
rack (~> 1.0)
rack (>= 1, < 3)
thor (0.19.1)
thread_safe (0.3.5)
tilt (2.0.5)
......@@ -829,7 +830,7 @@ PLATFORMS
ruby
DEPENDENCIES
RedCloth (~> 4.2.9)
RedCloth (~> 4.3.2)
ace-rails-ap (~> 4.0.2)
activerecord-session_store (~> 1.0.0)
acts-as-taggable-on (~> 3.4)
......@@ -969,7 +970,7 @@ DEPENDENCIES
responders (~> 2.0)
rouge (~> 1.11)
rqrcode-rails3 (~> 0.1.7)
rspec-rails (~> 3.4.0)
rspec-rails (~> 3.5.0)
rspec-retry
rubocop (~> 0.40.0)
rubocop-rspec (~> 1.5.0)
......@@ -1003,7 +1004,7 @@ DEPENDENCIES
teaspoon (~> 1.1.0)
teaspoon-jasmine (~> 2.2.0)
test_after_commit (~> 0.4.2)
thin (~> 1.6.1)
thin (~> 1.7.0)
tinder (~> 1.10.0)
turbolinks (~> 2.5.0)
u2f (~> 0.2.1)
......
......@@ -7,13 +7,16 @@ class @ImporterStatus
$('.js-add-to-import')
.off 'click'
.on 'click', (e) =>
new_namespace = null
$btn = $(e.currentTarget)
$tr = $btn.closest('tr')
$target_field = $tr.find('.import-target')
$namespace_input = $target_field.find('input')
id = $tr.attr('id').replace('repo_', '')
if $tr.find('.import-target input').length > 0
new_namespace = $tr.find('.import-target input').prop('value')
$tr.find('.import-target').empty().append("#{new_namespace} / #{$tr.find('.import-target').data('project_name')}")
new_namespace = null
if $namespace_input.length > 0
new_namespace = $namespace_input.prop('value')
$target_field.empty().append("#{new_namespace}/#{$target_field.data('project_name')}")
$btn
.disable()
......
......@@ -20,7 +20,8 @@
}
.open {
.dropdown-menu {
.dropdown-menu,
.dropdown-menu-nav {
display: block;
}
......@@ -66,7 +67,8 @@
}
}
.dropdown-menu {
.dropdown-menu,
.dropdown-menu-nav {
display: none;
position: absolute;
top: 100%;
......@@ -77,7 +79,7 @@
margin-bottom: 0;
font-size: 15px;
font-weight: normal;
padding: 10px 0;
padding: 8px 0;
background-color: $dropdown-bg;
border: 1px solid $dropdown-border-color;
border-radius: $border-radius-base;
......@@ -101,12 +103,12 @@
li {
text-align: left;
list-style: none;
padding: 0 10px;
padding: 0 8px;
}
.divider {
height: 1px;
margin: 8px 10px;
margin: 8px;
padding: 0;
background-color: $dropdown-divider-color;
}
......@@ -122,7 +124,7 @@
a {
display: block;
position: relative;
padding: 5px 10px;
padding: 5px 8px;
color: $dropdown-link-color;
line-height: initial;
text-overflow: ellipsis;
......
......@@ -60,7 +60,7 @@ header {
margin: ($header-height - 28) / 2 0;
margin-left: 10px;
height: 28px;
width: 28px;
min-width: 28px;
line-height: 28px;
text-align: center;
......@@ -241,14 +241,23 @@ header {
.navbar-collapse {
padding-left: 5px;
li {
.nav > li {
display: table-cell;
width: 1%;
a {
margin-left: 8px !important;
}
}
}
}
}
.header-user {
.dropdown-menu-nav {
width: 140px;
margin-top: -5px;
}
}
.header-user-avatar {
float: left;
margin-right: 5px;
border-radius: 50%;
}
......@@ -10,6 +10,7 @@ class Admin::GroupsController < Admin::ApplicationController
def show
@members = @group.members.order("access_level DESC").page(params[:members_page])
@requesters = @group.requesters
@projects = @group.projects.page(params[:projects_page])
end
......
......@@ -22,7 +22,6 @@ class Admin::HooksController < Admin::ApplicationController
redirect_to admin_hooks_path
end
def test
@hook = SystemHook.find(params[:hook_id])
data = {
......
......@@ -20,7 +20,8 @@ class Admin::ProjectsController < Admin::ApplicationController
@group_members = @group.members.order("access_level DESC").page(params[:group_members_page])
end
@project_members = @project.project_members.page(params[:project_members_page])
@project_members = @project.members.page(params[:project_members_page])
@requesters = @project.requesters
end
def transfer
......
......@@ -10,7 +10,7 @@ module MembershipActions
end
def approve_access_request
@member = membershipable.members.request.find(params[:id])
@member = membershipable.requesters.find(params[:id])
return render_403 unless can?(current_user, action_member_permission(:update, @member), @member)
......@@ -22,7 +22,8 @@ module MembershipActions
end
def leave
@member = membershipable.members.find_by(user_id: current_user)
@member = membershipable.members.find_by(user_id: current_user) ||
membershipable.requesters.find_by(user_id: current_user)
Members::DestroyService.new(@member, current_user).execute
source_type = @member.real_source_type.humanize(capitalize: false)
......
class ConfirmationsController < Devise::ConfirmationsController
def almost_there
flash[:notice] = nil
render layout: "devise_empty"
......
......@@ -7,7 +7,7 @@ class Groups::GroupMembersController < Groups::ApplicationController
def index
@project = @group.projects.find(params[:project_id]) if params[:project_id]
@members = @group.group_members
@members = @members.non_pending unless can?(current_user, :admin_group, @group)
@members = @members.non_invite unless can?(current_user, :admin_group, @group)
if params[:search].present?
users = @group.users.search(params[:search]).to_a
......@@ -15,6 +15,7 @@ class Groups::GroupMembersController < Groups::ApplicationController
end
@members = @members.order('access_level DESC').page(params[:page]).per(50)
@requesters = @group.requesters if can?(current_user, :admin_group, @group)
@group_member = @group.group_members.new
end
......@@ -46,7 +47,8 @@ class Groups::GroupMembersController < Groups::ApplicationController
end
def destroy
@group_member = @group.group_members.find(params[:id])
@group_member = @group.members.find_by(id: params[:id]) ||
@group.requesters.find_by(id: params[:id])
Members::DestroyService.new(@group_member, current_user).execute
log_audit_event(@group_member, action: :destroy)
......
class Import::BaseController < ApplicationController
private
def get_or_create_namespace
......
......@@ -5,7 +5,6 @@ class Import::FogbugzController < Import::BaseController
rescue_from Fogbugz::AuthenticationException, with: :fogbugz_unauthorized
def new
end
def callback
......@@ -22,7 +21,6 @@ class Import::FogbugzController < Import::BaseController
end
def new_user_map
end
def create_user_map
......
......@@ -44,5 +44,4 @@ class Import::GitoriousController < Import::BaseController
def verify_gitorious_import_enabled
render_404 unless gitorious_import_enabled?
end
end
......@@ -3,7 +3,6 @@ class Import::GoogleCodeController < Import::BaseController
before_action :user_map, only: [:new_user_map, :create_user_map]
def new
end
def callback
......@@ -34,7 +33,6 @@ class Import::GoogleCodeController < Import::BaseController
end
def new_user_map
end
def create_user_map
......
......@@ -5,7 +5,6 @@ class InvitesController < ApplicationController
respond_to :html
def show
end
def accept
......
......@@ -82,7 +82,6 @@ class Projects::IssuesController < Projects::ApplicationController
render json: @issue.to_json(include: [:milestone, :labels])
end
end
end
def create
......
......@@ -7,7 +7,6 @@ class Projects::NetworkController < Projects::ApplicationController
before_action :authorize_download_code!
def show
@url = namespace_project_network_path(@project.namespace, @project, @ref, @options.merge(format: :json))
@commit_url = namespace_project_commit_path(@project.namespace, @project, 'ae45ca32').gsub("ae45ca32", "%s")
......
......@@ -6,7 +6,7 @@ class Projects::ProjectMembersController < Projects::ApplicationController
def index
@project_members = @project.project_members
@project_members = @project_members.non_pending unless can?(current_user, :admin_project, @project)
@project_members = @project_members.non_invite unless can?(current_user, :admin_project, @project)
if params[:search].present?
users = @project.users.search(params[:search]).to_a
......@@ -19,7 +19,7 @@ class Projects::ProjectMembersController < Projects::ApplicationController
if @group
@group_members = @group.group_members
@group_members = @group_members.non_pending unless can?(current_user, :admin_group, @group)
@group_members = @group_members.non_invite unless can?(current_user, :admin_group, @group)
if params[:search].present?
users = @group.users.search(params[:search]).to_a
......@@ -29,6 +29,8 @@ class Projects::ProjectMembersController < Projects::ApplicationController
@group_members = @group_members.order('access_level DESC')
end
@requesters = @project.requesters if can?(current_user, :admin_project, @project)
@project_member = @project.project_members.new
@project_group_links = @project.project_group_links
end
......@@ -57,7 +59,8 @@ class Projects::ProjectMembersController < Projects::ApplicationController
end
def destroy
@project_member = @project.project_members.find(params[:id])
@project_member = @project.members.find_by(id: params[:id]) ||
@project.requesters.find_by(id: params[:id])
Members::DestroyService.new(@project_member, current_user).execute
......
......@@ -54,7 +54,7 @@ class Projects::SnippetsController < Projects::ApplicationController
def show
@note = @project.notes.new(noteable: @snippet)
@notes = @snippet.notes.fresh
@notes = Banzai::NoteRenderer.render(@snippet.notes.fresh, @project, current_user)
@noteable = @snippet
end
......
......@@ -133,5 +133,4 @@ class Projects::WikisController < Projects::ApplicationController
def wiki_params
params[:wiki].slice(:title, :content, :format, :message)
end
end
module EmailsHelper
# Google Actions
# https://developers.google.com/gmail/markup/reference/go-to-action
def email_action(url)
......
module IssuablesHelper
def sidebar_gutter_toggle_icon
sidebar_gutter_collapsed? ? icon('angle-double-left') : icon('angle-double-right')
end
......
......@@ -12,6 +12,17 @@ module MembersHelper
can?(current_user, action_member_permission(:admin, member), member.source)
end
def can_see_request_access_button?(source)
source_parent = source.respond_to?(:group) && source.group
return false if source_parent && source.group.members.exists?(user_id: current_user.id)
return false if source_parent && source.group.requesters.exists?(user_id: current_user.id)
return false if source.members.exists?(user_id: current_user.id)
return true if source.requesters.exists?(user_id: current_user.id)
true
end
def remove_member_message(member, user: nil)
user = current_user if defined?(current_user)
......
module SearchHelper
def search_autocomplete_opts(term)
return unless current_user
......
......@@ -19,6 +19,7 @@ module Ci
acts_as_taggable
before_save :update_artifacts_size, if: :artifacts_file_changed?
before_destroy { project }
after_create :execute_hooks
......@@ -330,7 +331,12 @@ module Ci
end
def artifacts_metadata_entry(path, **options)
Gitlab::Ci::Build::Artifacts::Metadata.new(artifacts_metadata.path, path, **options).to_entry
metadata = Gitlab::Ci::Build::Artifacts::Metadata.new(
artifacts_metadata.path,
path,
**options)
metadata.to_entry
end
def erase_artifacts!
......@@ -376,6 +382,14 @@ module Ci
private
def update_artifacts_size
self.artifacts_size = if artifacts_file.exists?
artifacts_file.size
else
nil
end
end
def erase_trace!
self.trace = nil
end
......
......@@ -16,6 +16,7 @@ module Ci
# Invalidate object and save if when touched
after_touch :update_state
after_save :keep_around_commits
def self.truncate_sha(sha)
sha[0...8]
......@@ -212,5 +213,10 @@ module Ci
self.duration = statuses.latest.duration
save
end
def keep_around_commits
project.repository.keep_around(self.sha)
project.repository.keep_around(self.before_sha)
end
end
end
module Ci
class TriggerRequest < ActiveRecord::Base
extend Ci::Model
belongs_to :trigger, class_name: 'Ci::Trigger'
belongs_to :pipeline, class_name: 'Ci::Pipeline', foreign_key: :commit_id
has_many :builds, class_name: 'Ci::Build'
......
......@@ -61,7 +61,6 @@ module Issuable
scope :references_project, -> { references(:project) }
scope :non_archived, -> { join_project.where(projects: { archived: false }) }
delegate :name,
:email,
to: :author,
......
......@@ -45,7 +45,7 @@ module Mentionable
def all_references(current_user = nil, text = nil, extractor: nil)
extractor ||= Gitlab::ReferenceExtractor.
new(project, current_user || author)
new(project, current_user)
if text
extractor.analyze(text, author: author)
......
......@@ -6,15 +6,16 @@ class Group < Namespace
include AccessRequestable
include Referable
has_many :group_members, dependent: :destroy, as: :source, class_name: 'GroupMember'
has_many :group_members, -> { where(requested_at: nil) }, dependent: :destroy, as: :source, class_name: 'GroupMember'
alias_method :members, :group_members
has_many :users, -> { where(members: { requested_at: nil }) }, through: :group_members
has_many :users, through: :group_members
has_many :owners,
-> { where(members: { requested_at: nil, access_level: Gitlab::Access::OWNER }) },
-> { where(members: { access_level: Gitlab::Access::OWNER }) },
through: :group_members,
source: :user
has_many :requesters, -> { where.not(requested_at: nil) }, dependent: :destroy, as: :source, class_name: 'GroupMember'
has_many :project_group_links, dependent: :destroy
has_many :shared_projects, through: :project_group_links, source: :project
has_many :ldap_group_links, foreign_key: 'group_id', dependent: :destroy
......
......@@ -31,8 +31,6 @@ class Member < ActiveRecord::Base
scope :invite, -> { where.not(invite_token: nil) }
scope :non_invite, -> { where(invite_token: nil) }
scope :request, -> { where.not(requested_at: nil) }
scope :non_request, -> { where(requested_at: nil) }
scope :non_pending, -> { non_request.non_invite }
scope :has_access, -> { where('access_level > 0') }
scope :guests, -> { where(access_level: GUEST) }
......
......@@ -15,7 +15,6 @@ class ProjectMember < Member
before_destroy :delete_member_todos
class << self
# Add users to project teams with passed access option
#
# access can be an integer representing a access code
......
......@@ -121,6 +121,8 @@ class MergeRequest < ActiveRecord::Base
scope :references_project, -> { references(:target_project) }
participant :approvers_left
after_save :keep_around_commit
def self.reference_prefix
'!'
......@@ -609,12 +611,12 @@ class MergeRequest < ActiveRecord::Base
"refs/merge-requests/#{iid}/head"
end
def ref_is_fetched?
File.exist?(File.join(project.repository.path_to_repo, ref_path))
def ref_fetched?
project.repository.ref_exists?(ref_path)
end
def ensure_ref_fetched
fetch_ref unless ref_is_fetched?
fetch_ref unless ref_fetched?
end
def in_locked_state
......@@ -693,4 +695,8 @@ class MergeRequest < ActiveRecord::Base
def can_be_cherry_picked?
merge_commit
end
def keep_around_commit
project.repository.keep_around(self.merge_commit_sha)
end
end
......@@ -24,6 +24,7 @@ class MergeRequestDiff < ActiveRecord::Base
serialize :st_diffs
after_create :reload_content, unless: :importing?
after_save :keep_around_commit
def reload_content
reload_commits
......@@ -145,7 +146,11 @@ class MergeRequestDiff < ActiveRecord::Base
end
new_attributes[:st_diffs] = new_diffs
new_attributes[:base_commit_sha] = self.repository.merge_base(self.head, self.base)
base_commit_sha = self.repository.merge_base(self.head, self.base)
new_attributes[:base_commit_sha] = base_commit_sha
self.repository.keep_around(base_commit_sha)
update_columns_serialized(new_attributes)
end
......@@ -217,4 +222,8 @@ class MergeRequestDiff < ActiveRecord::Base
update_columns(new_attributes.merge(updated_at: current_time_from_proper_timezone))
reload
end
def keep_around_commit
self.repository.keep_around(self.base_commit_sha)
end
end
......@@ -68,6 +68,7 @@ class Note < ActiveRecord::Base
end
before_validation :clear_blank_line_code!
after_save :keep_around_commit
class << self
def model_name
......@@ -221,4 +222,10 @@ class Note < ActiveRecord::Base
original_name = note.match(Banzai::Filter::EmojiFilter.emoji_pattern)[1]
Gitlab::AwardEmoji.normalize_emoji_name(original_name)
end
private
def keep_around_commit
project.repository.keep_around(self.commit_id)
end
end
......@@ -107,9 +107,13 @@ class Project < ActiveRecord::Base
has_many :snippets, dependent: :destroy, class_name: 'ProjectSnippet'
has_many :hooks, dependent: :destroy, class_name: 'ProjectHook'
has_many :protected_branches, dependent: :destroy
has_many :project_members, dependent: :destroy, as: :source, class_name: 'ProjectMember'
has_many :project_members, -> { where(requested_at: nil) }, dependent: :destroy, as: :source, class_name: 'ProjectMember'
alias_method :members, :project_members
has_many :users, -> { where(members: { requested_at: nil }) }, through: :project_members
has_many :users, through: :project_members
has_many :requesters, -> { where.not(requested_at: nil) }, dependent: :destroy, as: :source, class_name: 'ProjectMember'
has_many :deploy_keys_projects, dependent: :destroy
has_many :deploy_keys, through: :deploy_keys_projects
has_many :users_star_projects, dependent: :destroy
......
class BugzillaService < IssueTrackerService
prop_accessor :title, :description, :project_url, :issues_url, :new_issue_url
def title
......@@ -21,5 +20,4 @@ class BugzillaService < IssueTrackerService
def to_param
'bugzilla'
end
end
class CustomIssueTrackerService < IssueTrackerService
prop_accessor :title, :description, :project_url, :issues_url, :new_issue_url
def title
......@@ -31,5 +30,4 @@ class CustomIssueTrackerService < IssueTrackerService
{ type: 'text', name: 'new_issue_url', placeholder: 'New Issue url' }
]
end
end
class DroneCiService < CiService
prop_accessor :drone_url, :token, :enable_ssl_verification
validates :drone_url, presence: true, url: true, if: :activated?
......
class IssueTrackerService < Service
validates :project_url, :issues_url, :new_issue_url, presence: true, url: true, if: :activated?
default_value_for :category, 'issue_tracker'
......
......@@ -190,7 +190,6 @@ class JiraService < IssueTrackerService
end
end
def auth
require 'base64'
Base64.urlsafe_encode64("#{self.username}:#{self.password}")
......
class RedmineService < IssueTrackerService
prop_accessor :title, :description, :project_url, :issues_url, :new_issue_url
def title
......
......@@ -22,12 +22,12 @@ class ProjectTeam
end
def find_member(user_id)
member = project.members.non_request.find_by(user_id: user_id)
member = project.members.find_by(user_id: user_id)
# If user is not in project members
# we should check for group membership
if group && !member
member = group.members.non_request.find_by(user_id: user_id)
member = group.members.find_by(user_id: user_id)
end
member
......@@ -139,10 +139,10 @@ class ProjectTeam
def max_member_access(user_id)
access = []
access += project.members.non_request.where(user_id: user_id).has_access.pluck(:access_level)
access += project.members.where(user_id: user_id).has_access.pluck(:access_level)
if group
access += group.members.non_request.where(user_id: user_id).has_access.pluck(:access_level)
access += group.members.where(user_id: user_id).has_access.pluck(:access_level)
end
if project.invited_groups.any? && project.allowed_to_share_with_group?
......@@ -170,14 +170,14 @@ class ProjectTeam
end
def fetch_members(level = nil)
project_members = project.members.non_request
group_members = group ? group.members.non_request : []
project_members = project.members
group_members = group ? group.members : []
invited_members = []
if project.invited_groups.any? && project.allowed_to_share_with_group?
project.project_group_links.each do |group_link|
invited_group = group_link.group
im = invited_group.members.non_request
im = invited_group.members
if level
int_level = GroupMember.access_level_roles[level.to_s.singularize.titleize]
......
......@@ -255,6 +255,26 @@ class Repository
branch_names.include?(branch_name)
end
def ref_exists?(ref)
rugged.references.exist?(ref)
end
# Makes sure a commit is kept around when Git garbage collection runs.
# Git GC will delete commits from the repository that are no longer in any
# branches or tags, but we want to keep some of these commits around, for
# example if they have comments or CI builds.
def keep_around(sha)
return unless sha && commit(sha)
return if kept_around?(sha)
rugged.references.create(keep_around_ref_name(sha), sha)
end
def kept_around?(sha)
ref_exists?(keep_around_ref_name(sha))
end
def tag_names
cache.fetch(:tag_names) { raw_repository.tag_names }
end
......@@ -1003,7 +1023,6 @@ class Repository
merge_base(ancestor_id, descendant_id) == ancestor_id
end
def search_files(query, ref)
offset = 2
args = %W(#{Gitlab.config.git.bin_path} grep -i -I -n --before-context #{offset} --after-context #{offset} -E -e #{Regexp.escape(query)} #{ref || root_ref})
......@@ -1204,4 +1223,8 @@ class Repository
def tags_sorted_by_committed_date
tags.sort_by { |tag| commit(tag.target).committed_date }
end
def keep_around_ref_name(sha)
"refs/keep-around/#{sha}"
end
end
......@@ -9,6 +9,8 @@ class SentNotification < ActiveRecord::Base
validates :commit_id, presence: true, if: :for_commit?
validates :line_code, line_code: true, allow_blank: true
after_save :keep_around_commit
class << self
def reply_key
SecureRandom.hex(16)
......@@ -67,4 +69,10 @@ class SentNotification < ActiveRecord::Base
def to_param
self.reply_key
end
private
def keep_around_commit
project.repository.keep_around(self.commit_id)
end
end
......@@ -37,6 +37,8 @@ class Todo < ActiveRecord::Base
state :done
end
after_save :keep_around_commit
def build_failed?
action == BUILD_FAILED
end
......@@ -73,4 +75,10 @@ class Todo < ActiveRecord::Base
target.to_reference
end
end
private
def keep_around_commit
project.repository.keep_around(self.commit_id)
end
end
......@@ -889,7 +889,6 @@ class User < ActiveRecord::Base
projects.select(:id),
groups.joins(:shared_projects).select(:project_id)]
if min_access_level
scope = { access_level: Gitlab::Access.values.select { |access| access >= min_access_level } }
relations = [relations.shift] + relations.map { |relation| relation.where(members: scope) }
......
......@@ -34,8 +34,8 @@ class CreateBranchService < BaseService
else
error('Invalid reference name')
end
rescue GitHooksService::PreReceiveError
error('Branch creation was rejected by Git hook')
rescue GitHooksService::PreReceiveError => ex
error(ex.message)
end
def success(branch)
......
......@@ -2,7 +2,6 @@ require_relative 'base_service'
class CreateReleaseService < BaseService
def execute(tag_name, release_description)
repository = project.repository
existing_tag = repository.find_tag(tag_name)
......
......@@ -13,8 +13,8 @@ class CreateTagService < BaseService
new_tag = repository.add_tag(current_user, tag_name, target, message)
rescue Rugged::TagError
return error("Tag #{tag_name} already exists")
rescue GitHooksService::PreReceiveError
return error('Tag creation was rejected by Git hook')
rescue GitHooksService::PreReceiveError => ex
return error(ex.message)
end
if new_tag
......
......@@ -30,8 +30,8 @@ class DeleteBranchService < BaseService
else
error('Failed to remove branch')
end
rescue GitHooksService::PreReceiveError
error('Branch deletion was rejected by Git hook')
rescue GitHooksService::PreReceiveError => ex
error(ex.message)
end
def error(message, return_code = 400)
......
......@@ -9,8 +9,10 @@ class GitHooksService
@ref = ref
%w(pre-receive update).each do |hook_name|
unless run_hook(hook_name)
raise PreReceiveError.new("Git operation was rejected by #{hook_name} hook")
status, message = run_hook(hook_name)
unless status
raise PreReceiveError, message
end
end
......
module Issues
class BaseService < ::IssuableBaseService
def hook_data(issue, action)
issue_data = issue.to_hook_data(current_user)
issue_url = Gitlab::UrlBuilder.build(issue)
......
module MergeRequests
class BaseService < ::IssuableBaseService
def create_note(merge_request)
SystemNoteService.change_status(merge_request, merge_request.target_project, current_user, merge_request.state, nil)
end
......
......@@ -60,10 +60,13 @@ module MergeRequests
commit_id = repository.merge(current_user, merge_request.source_sha, merge_request.target_branch, options)
merge_request.update(merge_commit_sha: commit_id)
rescue GitHooksService::PreReceiveError => e
merge_request.update(merge_error: e.message)
false
rescue StandardError => e
merge_request.update(merge_error: "Something went wrong during merge")
Rails.logger.error(e.message)
return false
false
end
def after_merge
......
......@@ -40,6 +40,5 @@ module MergeRequests
error("Can't cancel the automatic merge", 406)
end
end
end
end
module Milestones
class DestroyService < Milestones::BaseService
def execute(milestone)
Milestone.transaction do
update_params = { milestone: nil }
......
module Projects
class DownloadService < BaseService
WHITELIST = [
/^[^.]+\.fogbugz.com$/
]
......
module Projects
module ImportExport
class ExportService < BaseService
def execute(_options = {})
@shared = Gitlab::ImportExport::Shared.new(relative_path: File.join(project.path_with_namespace, 'work'))
save_all
......
......@@ -293,7 +293,6 @@ class SystemNoteService
end
end
def self.cross_reference?(note_text)
note_text.start_with?(cross_reference_note_prefix)
end
......
......@@ -237,7 +237,7 @@ class TodoService
end
def filter_mentioned_users(project, target, author)
mentioned_users = target.mentioned_users
mentioned_users = target.mentioned_users(author)
mentioned_users = reject_users_without_access(mentioned_users, project, target)
mentioned_users.delete(author)
mentioned_users.uniq
......
......@@ -2,7 +2,6 @@ require_relative 'base_service'
class UpdateReleaseService < BaseService
def execute(tag_name, release_description)
repository = project.repository
existing_tag = repository.find_tag(tag_name)
......
module WikiPages
class BaseService < ::BaseService
def hook_data(page, action)
hook_data = {
object_kind: page.class.name.underscore,
......
......@@ -100,16 +100,16 @@
%hr
= button_tag 'Add users to group', class: "btn btn-create"
= render 'shared/members/requests', membership_source: @group, members: @members.request
= render 'shared/members/requests', membership_source: @group, requesters: @requesters
.panel.panel-default
.panel-heading
%strong= @group.name
group members
%span.badge= @group.members.non_request.size
%span.badge= @group.members.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 }
= render partial: 'shared/members/member', collection: @members, as: :member, locals: { show_controls: false }
.panel-footer
= paginate @members.non_request, param_name: 'members_page', theme: 'gitlab'
= paginate @members, param_name: 'members_page', theme: 'gitlab'
......@@ -137,16 +137,16 @@
.panel-heading
%strong= @group.name
group members
%span.badge= @group_members.non_request.size
%span.badge= @group_members.size
.pull-right
= link_to admin_group_path(@group), class: 'btn btn-xs' do
= 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 }
= render partial: 'shared/members/member', collection: @group_members, as: :member, locals: { show_controls: false }
.panel-footer
= paginate @group_members.non_request, param_name: 'group_members_page', theme: 'gitlab'
= paginate @group_members, param_name: 'group_members_page', theme: 'gitlab'
= render 'shared/members/requests', membership_source: @project, members: @project_members.request
= render 'shared/members/requests', membership_source: @project, requesters: @requesters
.panel.panel-default
.panel-heading
......@@ -156,6 +156,6 @@
.pull-right
= 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 }
= render partial: 'shared/members/member', collection: @project_members, as: :member, locals: { show_controls: false }
.panel-footer
= paginate @project_members.non_request, param_name: 'project_members_page', theme: 'gitlab'
= paginate @project_members, param_name: 'project_members_page', theme: 'gitlab'
- page_title "Members"
.group-members-page.prepend-top-default
<<<<<<< HEAD
- if current_user && can?(current_user, :admin_group_member, @group)
=======
- if can?(current_user, :admin_group_member, @group)
>>>>>>> 06c7d6f3a863a1ac8d9f47fed8423387d6e672a6
.panel.panel-default
.panel-heading
Add new user to group
......@@ -11,6 +15,7 @@
.new-group-member-holder
= render "new_group_member"
<<<<<<< HEAD
- if current_user && @group.ldap_synced?
.bs-callout.bs-callout-info
The members of this group are managed using LDAP and cannot be added, changed or removed here.
......@@ -32,12 +37,15 @@
- if current_user && can?(current_user, :admin_group_member, @group)
= render 'shared/members/requests', membership_source: @group, members: @members.request
=======
= render 'shared/members/requests', membership_source: @group, requesters: @requesters
>>>>>>> 06c7d6f3a863a1ac8d9f47fed8423387d6e672a6
.panel.panel-default
.panel-heading
%strong #{@group.name}
group members
%span.badge= @members.non_request.size
%span.badge= @members.size
.controls
= form_tag group_group_members_path(@group), method: :get, class: 'form-inline member-search-form' do
.form-group
......@@ -45,8 +53,8 @@
= button_tag class: 'btn', title: 'Search' do
= icon("search")
%ul.content-list
= render partial: 'shared/members/member', collection: @members.non_request, as: :member
= paginate @members.non_request, theme: 'gitlab'
= render partial: 'shared/members/member', collection: @members, as: :member
= paginate @members, theme: 'gitlab'
:javascript
$('form.member-search-form').on('submit', function(event) {
......
- if @already_been_taken
:plain
target_field = $("tr#repo_#{@repo_id} .import-target")
tr = $("tr#repo_#{@repo_id}")
target_field = tr.find(".import-target")
import_button = tr.find(".btn-import")
origin_target = target_field.text()
project_name = "#{@project_name}"
origin_namespace = "#{@target_namespace}"
......@@ -10,6 +12,7 @@
target_field.append("/" + project_name)
target_field.data("project_name", project_name)
target_field.find('input').prop("value", origin_namespace)
import_button.enable().removeClass('is-loading')
- elsif @access_denied
:plain
job = $("tr#repo_#{@repo_id}")
......
......@@ -42,9 +42,17 @@
= link_to sherlock_transactions_path, title: 'Sherlock Transactions',
data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= icon('tachometer fw')
%li
= link_to destroy_user_session_path, class: 'logout', method: :delete, title: 'Sign out', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= icon('sign-out')
%li.header-user.dropdown
= link_to current_user, class: "header-user-dropdown-toggle", data: { toggle: "dropdown" } do
= image_tag avatar_icon(current_user, 26), width: 26, height: 26, class: "header-user-avatar"
%span.caret
.dropdown-menu-nav.dropdown-menu-align-right
%ul
%li
= link_to "Profile", current_user
%li.divider
%li
= link_to "Sign out", destroy_user_session_path, method: :delete, class: "sign-out-link", title: 'Sign out'
- else
%li
%div
......
- if current_user
- can_edit = can?(current_user, :admin_group, @group)
- member = @group.members.non_request.find_by(user_id: current_user.id)
- member = @group.members.find_by(user_id: current_user.id)
- can_leave = member && can?(current_user, :destroy_group_member, member)
.controls
......
......@@ -7,7 +7,7 @@
%ul.dropdown-menu.dropdown-menu-align-right
- 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)
- member = @project.members.find_by(user_id: current_user.id)
- can_leave = member && can?(current_user, :destroy_project_member, member)
= render 'layouts/nav/project_settings', can_edit: can_edit
......
- @project_group_links.each do |group_links|
- shared_group = group_links.group
- shared_group_members = shared_group.members.non_request
- shared_group_members = shared_group.members
- shared_group_users_count = shared_group_members.size
.panel.panel-default
.panel-heading
......
......@@ -17,12 +17,12 @@
Users with access to this project are listed below.
= render "new_project_member"
= render 'shared/members/requests', membership_source: @project, members: @project_members.request
= render 'shared/members/requests', membership_source: @project, requesters: @requesters
= render 'team', members: @project_members.non_request
= render 'team', members: @project_members
- if @group
= render "group_members", members: @group_members.non_request
= render "group_members", members: @group_members
- if @project_group_links.any? && @project.allowed_to_share_with_group?
= render "shared_group_members"
- member = source.members.find_by(user_id: current_user.id)
- group_member = source.group.members.find_by(user_id: current_user.id) if source.respond_to?(:group) && source.group
- unless group_member
- if member
- if member.request?
= link_to 'Withdraw Access Request', polymorphic_path([:leave, source, :members]),
method: :delete,
data: { confirm: remove_member_message(member) },
class: 'btn'
- if can_see_request_access_button?(source)
- if requester = source.requesters.find_by(user_id: current_user.id)
= link_to 'Withdraw Access Request', polymorphic_path([:leave, source, :members]),
method: :delete,
data: { confirm: remove_member_message(requester) },
class: 'btn'
- else
= link_to 'Request Access', polymorphic_path([:request_access, source, :members]),
method: :post,
......
- if members.any?
- if requesters.any?
.panel.panel-default
.panel-heading
%strong= membership_source.name
access requests
%span.badge= members.size
%span.badge= requesters.size
%ul.content-list
= render partial: 'shared/members/member', collection: members, as: :member
= render partial: 'shared/members/member', collection: requesters, as: :member
......@@ -162,7 +162,6 @@ if Settings.ldap['enabled'] || Rails.env.test?
end
end
Settings['omniauth'] ||= Settingslogic.new({})
Settings.omniauth['enabled'] = false if Settings.omniauth['enabled'].nil?
Settings.omniauth['auto_sign_in_with_provider'] = false if Settings.omniauth['auto_sign_in_with_provider'].nil?
......@@ -256,7 +255,6 @@ Settings.gitlab['restricted_signup_domains'] ||= []
Settings.gitlab['import_sources'] ||= %w[github bitbucket gitlab gitorious google_code fogbugz git gitlab_project]
Settings.gitlab['trusted_proxies'] ||= []
#
# Elasticseacrh
#
......@@ -427,7 +425,6 @@ Settings.git['timeout'] ||= 10
Settings['satellites'] ||= Settingslogic.new({})
Settings.satellites['path'] = File.expand_path(Settings.satellites['path'] || "tmp/repo_satellites/", Rails.root)
#
# Kerberos
#
......
......@@ -141,7 +141,6 @@ Rails.application.routes.draw do
#
resources :notification_settings, only: [:create, :update]
#
# Import
#
......@@ -509,7 +508,6 @@ Rails.application.routes.draw do
resources :namespaces, path: '/', constraints: { id: /[a-zA-Z.0-9_\-]+/ }, only: [] do
resources(:projects, constraints: { id: /[a-zA-Z.0-9_\-]+(?<!\.atom)/ }, except:
[:new, :create, :index], path: "/") do
member do
put :transfer
delete :remove_fork
......
class AddArtifactsSizeToCiBuilds < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
def change
add_column(:ci_builds, :artifacts_size, :integer)
end
end
......@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20160621123729) do
ActiveRecord::Schema.define(version: 20160628085157) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
......@@ -189,6 +189,7 @@ ActiveRecord::Schema.define(version: 20160621123729) do
t.datetime "erased_at"
t.string "environment"
t.datetime "artifacts_expire_at"
t.integer "artifacts_size"
end
add_index "ci_builds", ["commit_id", "stage_idx", "created_at"], name: "index_ci_builds_on_commit_id_and_stage_idx_and_created_at", using: :btree
......
......@@ -3,9 +3,58 @@
Sometimes things don't work the way they should. Here are some tips on debugging issues out
in production.
## The GNU Project Debugger (gdb)
## Mail not working
`gdb` is a must-have tool for debugging issues. To install on Ubuntu/Debian:
A common problem is that mails are not being sent for some reason. Suppose you configured
an SMTP server, but you're not seeing mail delivered. Here's how to check the settings:
1. Run a Rails console:
```sh
sudo gitlab-rails console production
```
or for source installs:
```sh
bundle exec rails console production
```
2. Look at the ActionMailer `delivery_method` to make sure it matches what you
intended. If you configured SMTP, it should say `:smtp`. If you're using
Sendmail, it should say `:sendmail`:
```ruby
irb(main):001:0> ActionMailer::Base.delivery_method
=> :smtp
```
3. If you're using SMTP, check the mail settings:
```ruby
irb(main):002:0> ActionMailer::Base.smtp_settings
=> {:address=>"localhost", :port=>25, :domain=>"localhost.localdomain", :user_name=>nil, :password=>nil, :authentication=>nil, :enable_starttls_auto=>true}```
```
In the example above, the SMTP server is configured for the local machine. If this is intended, you may need to check your local mail
logs (e.g. `/var/log/mail.log`) for more details.
4. Send a test message via the console.
```ruby
irb(main):003:0> Notify.test_email('youremail@email.com', 'Hello World', 'This is a test message').deliver_now
```
If you do not receive an e-mail and/or see an error message, then check
your mail server settings.
## Advanced Issues
For more advanced issues, `gdb` is a must-have tool for debugging issues.
### The GNU Project Debugger (gdb)
To install on Ubuntu/Debian:
```
sudo apt-get install gdb
......
......@@ -448,7 +448,7 @@ Parameters:
- `merge_request_id` (required) - ID of MR
- `merge_commit_message` (optional) - Custom merge commit message
- `should_remove_source_branch` (optional) - if `true` removes the source branch
- `merged_when_build_succeeds` (optional) - if `true` the MR is merged when the build succeeds
- `merge_when_build_succeeds` (optional) - if `true` the MR is merged when the build succeeds
- `sha` (optional) - if present, then this SHA must match the HEAD of the source branch, otherwise the merge will fail
```json
......
......@@ -8,7 +8,7 @@ Asana - Teamwork without email
Set Asana service for a project.
> This service adds commit messages as comments to Asana tasks. Once enabled, commit messages are checked for Asana task URLs (for example, `https://app.asana.com/0/123456/987654`) or task IDs starting with # (for example, `#987654`). Every task ID found will get the commit comment added to it. You can also close a task with a message containing: `fix #123456`. You can find your Api Keys here: http://developer.asana.com/documentation/#api_keys
> This service adds commit messages as comments to Asana tasks. Once enabled, commit messages are checked for Asana task URLs (for example, `https://app.asana.com/0/123456/987654`) or task IDs starting with # (for example, `#987654`). Every task ID found will get the commit comment added to it. You can also close a task with a message containing: `fix #123456`. You can find your Api Keys here: https://asana.com/developers/documentation/getting-started/auth#api-key
```
PUT /projects/:id/services/asana
......
......@@ -16,5 +16,5 @@
- [Trigger builds through the API](triggers/README.md)
- [Build artifacts](build_artifacts/README.md)
- [User permissions](permissions/README.md)
- [API](../../api/ci/README.md)
- [API](../api/ci/README.md)
- [CI services (linked docker containers)](services/README.md)
......@@ -14,3 +14,4 @@
- [Blog post about using GitLab CI for iOS projects](https://about.gitlab.com/2016/03/10/setting-up-gitlab-ci-for-ios-projects/)
- [Repo's with examples for various languages](https://gitlab.com/groups/gitlab-examples)
- [The .gitlab-ci.yml file for GitLab itself](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/.gitlab-ci.yml)
- [A collection of useful .gitlab-ci.yml templates](https://gitlab.com/gitlab-org/gitlab-ci-yml)
......@@ -21,7 +21,7 @@ We currently use three CI services to test GitLab:
Core team has access to trigger builds if needed for GitLab CE.
We use [these build scripts](https://gitlab.com/gitlab-org/gitlab-ci/blob/master/doc/examples/build_script_gitlab_ce.md) for testing with GitLab CI.
We use [these build scripts](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/.gitlab-ci.yml) for testing with GitLab CI.
# Build configuration on [Semaphore](https://semaphoreapp.com/gitlabhq/gitlabhq/) for testing the [GitHub.com repo](https://github.com/gitlabhq/gitlabhq)
......
......@@ -127,9 +127,15 @@ The chosen OmniAuth provider is now active and can be used to sign in to GitLab
This setting was introduced with version 8.7 of GitLab
You can define which OmniAuth providers you want to be `external` so that all users
creating accounts via these providers will not be able to have access to internal
projects. You will need to use the full name of the provider, like `google_oauth2`
for Google. Refer to the examples for the full names of the supported providers.
**creating accounts, or logging in via these providers** will not be able to have
access to internal projects. You will need to use the full name of the provider,
like `google_oauth2` for Google. Refer to the examples for the full names of the
supported providers.
>**Note:**
If you decide to remove an OmniAuth provider from the external providers list
you will need to manually update the users that use this method to login, if you
want their accounts to be upgraded to full internal accounts.
**For Omnibus installations**
......
......@@ -17,7 +17,7 @@ Public projects can be cloned **without any** authentication.
They will also be listed on the public access directory (`/public`).
**Any logged in user** will have [Guest](../permissions/permissions)
**Any logged in user** will have [Guest](../permissions/permissions.md)
permissions on the repository.
### Internal projects
......@@ -27,8 +27,8 @@ Internal projects can be cloned by any logged in user.
They will also be listed on the public access directory (`/public`) for logged
in users.
Any logged in user will have [Guest](../permissions/permissions) permissions on
the repository.
Any logged in user will have [Guest](../permissions/permissions.md) permissions
on the repository.
### How to change project visibility
......
......@@ -17,10 +17,6 @@ cat ~/.ssh/id_rsa.pub
If you see a long string starting with `ssh-rsa`, you can skip the `ssh-keygen` step.
Note: It is a best practice to use a password for an SSH key, but it is not
required and you can skip creating a password by pressing enter. Note that
the password you choose here can't be altered or retrieved.
To generate a new SSH key, use the following command:
```bash
ssh-keygen -t rsa -C "$your_email"
......@@ -30,6 +26,12 @@ pair and for a password. When prompted for the location and filename, just
press enter to use the default. If you use a different name, the key will not
be used automatically.
Note: It is a best practice to use a password for an SSH key, but it is not
required and you can skip creating a password by pressing enter.
If you want to change the password of your key later, you can use the following
command: `ssh-keygen -p <keyname>`
Use the command below to show your public key:
**Windows Command Line:**
......
......@@ -219,6 +219,7 @@ Feature: Project Issues
When I click button "Unsubscribe"
Then I should see that I am unsubscribed
@javascript
Scenario: I submit new unassigned issue as guest
Given public project "Community"
When I visit project "Community" page
......
......@@ -73,14 +73,15 @@ Feature: Search
Scenario: I logout and should see project I am looking for
Given project "Shop" is public
And I logout
And I logout directly
And I visit dashboard search page
And I search for "Sho"
Then I should see "Shop" project link
Scenario: I logout and should see issues I am looking for
Given project "Shop" is public
And I logout
And I logout directly
And I visit dashboard search page
And project has issues
And I visit dashboard search page
When I search for "Foo"
......@@ -90,7 +91,7 @@ Feature: Search
Scenario: I logout and should see project code I am looking for
Given project "Shop" is public
And I logout
And I logout directly
When I visit project "Shop" page
And I search for "rspec" on project page
Then I should see code results for project "Shop"
......@@ -49,5 +49,4 @@ class Spinach::Features::NewProject < Spinach::FeatureSteps
step 'I redirected to Google Code import page' do
expect(current_path).to eq new_import_google_code_path
end
end
......@@ -69,7 +69,6 @@ class Spinach::Features::ExploreProjects < Spinach::FeatureSteps
visit namespace_project_issues_path(public_project.namespace, public_project)
end
step 'I should see list of issues for "Community" project' do
expect(page).to have_content "Bug"
expect(page).to have_content public_project.name
......@@ -88,7 +87,6 @@ class Spinach::Features::ExploreProjects < Spinach::FeatureSteps
visit namespace_project_issues_path(internal_project.namespace, internal_project)
end
step 'I should see list of issues for "Internal" project' do
expect(page).to have_content "Internal Bug"
expect(page).to have_content internal_project.name
......@@ -137,7 +135,6 @@ class Spinach::Features::ExploreProjects < Spinach::FeatureSteps
@public_project ||= Project.find_by!(name: 'Community')
end
def internal_merge_request
@internal_merge_request ||= MergeRequest.find_by!(title: 'Feature implemented')
end
......
......@@ -33,5 +33,4 @@ class Spinach::Features::ProjectArchived < Spinach::FeatureSteps
When 'I set project unarchived' do
click_link "Unarchive"
end
end
......@@ -124,14 +124,12 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps
end
step 'project "Shop" has milestone "v2.2"' do
milestone = create(:milestone, title: "v2.2", project: project)
3.times { create(:issue, project: project, milestone: milestone) }
end
step 'project "Shop" has milestone "v3.0"' do
milestone = create(:milestone, title: "v3.0", project: project)
3.times { create(:issue, project: project, milestone: milestone) }
......@@ -147,7 +145,6 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps
end
When 'I select first assignee from "Shop" project' do
first_assignee = project.users.first
select first_assignee.name, from: "assignee_id"
end
......@@ -160,7 +157,6 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps
end
step 'project "Shop" have "Release 0.4" open issue' do
create(:issue,
title: "Release 0.4",
project: project,
......@@ -360,5 +356,4 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps
def filter_issue(text)
fill_in 'issue_search', with: text
end
end
......@@ -66,7 +66,6 @@ class Spinach::Features::ProjectFindFile < Spinach::FeatureSteps
expect(page).not_to have_content(".gitignore")
end
def find_file(text)
fill_in 'file_find', with: text
end
......
......@@ -189,5 +189,4 @@ module SharedIssuable
expect(page).to have_content content
end
end
end
......@@ -52,5 +52,4 @@ class Spinach::Features::SnippetSearch < Spinach::FeatureSteps
step 'I should not see "Personal snippet private" in results' do
expect(page).not_to have_content 'Personal snippet private'
end
end
......@@ -11,7 +11,6 @@ module API
[ ":id/#{awardable_string}/:#{awardable_id_string}/award_emoji",
":id/#{awardable_string}/:#{awardable_id_string}/notes/:note_id/award_emoji"
].each do |endpoint|
# Get a list of project +awardable+ award emoji
#
# Parameters:
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment