Commit c285f350 authored by Rémy Coutable's avatar Rémy Coutable

Merge remote-tracking branch 'upstream/master' into ce-to-ee-2017-07-26

# Conflicts:
#	Gemfile
#	Gemfile.lock
#	app/assets/stylesheets/pages/pipelines.scss
#	app/helpers/system_note_helper.rb
#	app/services/ci/create_pipeline_service.rb
#	app/services/system_note_service.rb
#	doc/api/issues.md
#	doc/articles/index.md
#	doc/integration/README.md
#	doc/user/project/quick_actions.md
#	lib/api/helpers/related_resources_helpers.rb
#	lib/api/triggers.rb
#	lib/api/v3/entities.rb
#	spec/controllers/admin/dashboard_controller_spec.rb
#	spec/features/issues/user_uses_slash_commands_spec.rb
#	spec/requests/api/triggers_spec.rb
#	spec/serializers/pipeline_serializer_spec.rb
#	spec/services/quick_actions/interpret_service_spec.rb
#	spec/support/api/milestones_shared_examples.rb
#	spec/support/stub_configuration.rb
[ci skip]
parents 248ddf26 1a2b92f7
......@@ -115,8 +115,8 @@ scheduling into milestones. Labelling is a task for everyone.
Most issues will have labels for at least one of the following:
- Type: ~"feature proposal", ~bug, ~customer, etc.
- Subject: ~wiki, ~"container registry", ~ldap, ~api, etc.
- Team: ~CI, ~Discussion, ~Edge, ~Frontend, ~Platform, etc.
- Subject: ~wiki, ~"container registry", ~ldap, ~api, ~frontend, etc.
- Team: ~CI, ~Discussion, ~Edge, ~Platform, etc.
- Priority: ~Deliverable, ~Stretch
All labels, their meaning and priority are defined on the
......@@ -279,7 +279,7 @@ For feature proposals for EE, open an issue on the
In order to help track the feature proposals, we have created a
[`feature proposal`][fpl] label. For the time being, users that are not members
of the project cannot add labels. You can instead ask one of the [core team]
members to add the label `feature proposal` to the issue or add the following
members to add the label ~"feature proposal" to the issue or add the following
code snippet right after your description in a new line: `~"feature proposal"`.
Please keep feature proposals as small and simple as possible, complex ones
......
......@@ -65,7 +65,10 @@ gem 'browser', '~> 2.2'
# GitLab fork with several improvements to original library. For full list of changes
# see https://github.com/intridea/omniauth-ldap/compare/master...gitlabhq:master
gem 'gitlab_omniauth-ldap', '~> 2.0.3', require: 'omniauth-ldap'
<<<<<<< HEAD
gem 'net-ldap'
=======
>>>>>>> upstream/master
# Git Wiki
# Required manually in config/initializers/gollum.rb to control load order
......@@ -176,7 +179,7 @@ gem 'rainbow', '~> 2.2'
gem 'settingslogic', '~> 2.0.9'
# Linear-time regex library for untrusted regular expressions
gem 're2', '~> 1.1.0'
gem 're2', '~> 1.1.1'
# Misc
......@@ -367,7 +370,7 @@ group :development, :test do
end
group :test do
gem 'shoulda-matchers', '~> 2.8.0', require: false
gem 'shoulda-matchers', '~> 3.1.2', require: false
gem 'email_spec', '~> 1.6.0'
gem 'json-schema', '~> 2.6.2'
gem 'webmock', '~> 2.3.2'
......
......@@ -500,7 +500,10 @@ GEM
mustermann (~> 1.0.0)
mysql2 (0.4.5)
net-ldap (0.16.0)
<<<<<<< HEAD
net-ntp (2.1.3)
=======
>>>>>>> upstream/master
netrc (0.11.0)
nokogiri (1.6.8.1)
mini_portile2 (~> 2.1.0)
......@@ -689,7 +692,7 @@ GEM
debugger-ruby_core_source (~> 1.3)
rdoc (4.2.2)
json (~> 1.4)
re2 (1.1.0)
re2 (1.1.1)
recaptcha (3.0.0)
json
recursive-open-struct (1.0.0)
......@@ -807,8 +810,8 @@ GEM
sexp_processor (4.9.0)
sham_rack (1.3.6)
rack
shoulda-matchers (2.8.0)
activesupport (>= 3.0.0)
shoulda-matchers (3.1.2)
activesupport (>= 4.0.0)
sidekiq (5.0.4)
concurrent-ruby (~> 1.0)
connection_pool (~> 2.2, >= 2.2.0)
......@@ -1020,7 +1023,10 @@ DEPENDENCIES
google-api-client (~> 0.8.6)
grape (~> 0.19.2)
grape-entity (~> 0.6.0)
<<<<<<< HEAD
gssapi
=======
>>>>>>> upstream/master
grape-route-helpers (~> 2.0.0)
haml_lint (~> 0.21.0)
hamlit (~> 2.6.1)
......@@ -1098,7 +1104,7 @@ DEPENDENCIES
raindrops (~> 0.18)
rblineprof (~> 0.3.6)
rdoc (~> 4.2)
re2 (~> 1.1.0)
re2 (~> 1.1.1)
recaptcha (~> 3.0)
redcarpet (~> 3.4)
redis (~> 3.2)
......@@ -1127,7 +1133,7 @@ DEPENDENCIES
sentry-raven (~> 2.5.3)
settingslogic (~> 2.0.9)
sham_rack (~> 1.3.6)
shoulda-matchers (~> 2.8.0)
shoulda-matchers (~> 3.1.2)
sidekiq (~> 5.0)
sidekiq-cron (~> 0.6.0)
sidekiq-limit_fetch (~> 3.4)
......
......@@ -175,7 +175,7 @@ import Cookies from 'js-cookie';
getConflictsCountText() {
const count = this.getConflictsCount();
const text = count ? 'conflicts' : 'conflict';
const text = count > 1 ? 'conflicts' : 'conflict';
return `${count} ${text}`;
},
......
......@@ -108,7 +108,8 @@ export default {
</div>
<mr-widget-memory-usage
v-if="deployment.metrics_url"
:metricsUrl="deployment.metrics_url"
:metrics-url="deployment.metrics_url"
:metrics-monitoring-url="deployment.metrics_monitoring_url"
/>
</div>
</div>
......
......@@ -7,7 +7,14 @@ import MRWidgetService from '../services/mr_widget_service';
export default {
name: 'MemoryUsage',
props: {
metricsUrl: { type: String, required: true },
metricsUrl: {
type: String,
required: true,
},
metricsMonitoringUrl: {
type: String,
required: true,
},
},
data() {
return {
......@@ -124,7 +131,7 @@ export default {
<p
v-if="shouldShowMemoryGraph"
class="usage-info js-usage-info">
Memory usage <b>{{memoryChangeType}}</b> from {{memoryFrom}}MB to {{memoryTo}}MB
<a :href="metricsMonitoringUrl">Memory</a> usage <b>{{memoryChangeType}}</b> from {{memoryFrom}}MB to {{memoryTo}}MB
</p>
<p
v-if="shouldShowLoadFailure"
......
......@@ -163,8 +163,18 @@
td.blame-commit {
padding: 5px 10px;
min-width: 400px;
max-width: 400px;
background: $gray-light;
border-left: 3px solid;
.commit-row-title {
display: flex;
}
.item-title {
flex: 1;
margin-right: 0.5em;
}
}
@for $i from 0 through 5 {
......
......@@ -21,6 +21,11 @@ header.navbar-gitlab-new {
padding-right: 0;
color: currentColor;
img {
height: 28px;
margin-right: 10px;
}
> a {
display: flex;
align-items: center;
......
......@@ -626,8 +626,12 @@
}
// Dropdown button in mini pipeline graph
<<<<<<< HEAD
button.mini-pipeline-graph-dropdown-toggle,
a.linked-pipeline-mini-item {
=======
button.mini-pipeline-graph-dropdown-toggle {
>>>>>>> upstream/master
border-radius: 100px;
background-color: $white-light;
border-width: 1px;
......
class Admin::DashboardController < Admin::ApplicationController
def index
@projects = Project.with_route.limit(10)
@projects = Project.without_deleted.with_route.limit(10)
@users = User.limit(10)
@groups = Group.with_route.limit(10)
@license = License.current
......
......@@ -227,11 +227,17 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
metrics_project_environment_deployment_path(environment.project, environment, deployment)
end
metrics_monitoring_url =
if can?(current_user, :read_environment, environment)
environment_metrics_path(environment)
end
{
id: environment.id,
name: environment.name,
url: project_environment_path(project, environment),
metrics_url: metrics_url,
metrics_monitoring_url: metrics_monitoring_url,
stop_url: stop_url,
external_url: environment.external_url,
external_url_formatted: environment.formatted_external_url,
......
......@@ -19,11 +19,15 @@ module SystemNoteHelper
'discussion' => 'icon_comment_o',
'moved' => 'icon_arrow_circle_o_right',
'outdated' => 'icon_edit',
<<<<<<< HEAD
'duplicate' => 'icon_clone',
'approved' => 'icon_check',
'unapproved' => 'icon_fa_close',
'relate' => 'icon_anchor',
'unrelate' => 'icon_anchor_broken'
=======
'duplicate' => 'icon_clone'
>>>>>>> upstream/master
}.freeze
def icon_for_system_note(note)
......
......@@ -33,7 +33,7 @@ module Ci
has_many :merge_requests, foreign_key: "head_pipeline_id"
has_many :pending_builds, -> { pending }, foreign_key: :commit_id, class_name: 'Ci::Build'
has_many :retryable_builds, -> { latest.failed_or_canceled }, foreign_key: :commit_id, class_name: 'Ci::Build'
has_many :retryable_builds, -> { latest.failed_or_canceled.includes(:project) }, foreign_key: :commit_id, class_name: 'Ci::Build'
has_many :cancelable_statuses, -> { cancelable }, foreign_key: :commit_id, class_name: 'CommitStatus'
has_many :manual_actions, -> { latest.manual_actions.includes(:project) }, foreign_key: :commit_id, class_name: 'Ci::Build'
has_many :artifacts, -> { latest.with_artifacts_not_expired.includes(:project) }, foreign_key: :commit_id, class_name: 'Ci::Build'
......
......@@ -40,10 +40,6 @@ module Ci
update_attribute(:active, false)
end
def runnable_by_owner?
Ability.allowed?(owner, :create_pipeline, project)
end
def set_next_run_at
self.next_run_at = Gitlab::Ci::CronParser.new(cron, cron_timezone).next_time_from(Time.now)
end
......
......@@ -31,8 +31,8 @@ module ProtectedRef
end
end
def protected_ref_accessible_to?(ref, user, action:)
access_levels_for_ref(ref, action: action).any? do |access_level|
def protected_ref_accessible_to?(ref, user, action:, protected_refs: nil)
access_levels_for_ref(ref, action: action, protected_refs: protected_refs).any? do |access_level|
access_level.check_access(user)
end
end
......@@ -43,8 +43,9 @@ module ProtectedRef
end
end
def access_levels_for_ref(ref, action:)
self.matching(ref).map(&:"#{action}_access_levels").flatten
def access_levels_for_ref(ref, action:, protected_refs: nil)
self.matching(ref, protected_refs: protected_refs)
.map(&:"#{action}_access_levels").flatten
end
def matching(ref_name, protected_refs: nil)
......
......@@ -3,10 +3,8 @@ class JiraService < IssueTrackerService
validates :url, url: true, presence: true, if: :activated?
validates :api_url, url: true, allow_blank: true
validates :project_key, presence: true, if: :activated?
prop_accessor :username, :password, :url, :api_url, :project_key,
:jira_issue_transition_id, :title, :description
prop_accessor :username, :password, :url, :api_url, :jira_issue_transition_id, :title, :description
before_update :reset_password
......@@ -54,10 +52,6 @@ class JiraService < IssueTrackerService
@client ||= JIRA::Client.new(options)
end
def jira_project
@jira_project ||= jira_request { client.Project.find(project_key) }
end
def help
"You need to configure JIRA before enabling this service. For more details
read the
......@@ -88,18 +82,12 @@ class JiraService < IssueTrackerService
[
{ type: 'text', name: 'url', title: 'Web URL', placeholder: 'https://jira.example.com', required: true },
{ type: 'text', name: 'api_url', title: 'JIRA API URL', placeholder: 'If different from Web URL' },
{ type: 'text', name: 'project_key', placeholder: 'Project Key', required: true },
{ type: 'text', name: 'username', placeholder: '', required: true },
{ type: 'password', name: 'password', placeholder: '', required: true },
{ type: 'text', name: 'jira_issue_transition_id', placeholder: '' }
{ type: 'text', name: 'jira_issue_transition_id', title: 'Transition ID', placeholder: '' }
]
end
# URLs to redirect from Gitlab issues pages to jira issue tracker
def project_url
"#{url}/issues/?jql=project=#{project_key}"
end
def issues_url
"#{url}/browse/:id"
end
......@@ -184,7 +172,7 @@ class JiraService < IssueTrackerService
def test_settings
return unless client_url.present?
# Test settings by getting the project
jira_request { jira_project.present? }
jira_request { client.ServerInfo.all.attrs }
end
private
......
......@@ -478,9 +478,18 @@ class Repository
end
cache_method :root_ref
# Gitaly migration: https://gitlab.com/gitlab-org/gitaly/issues/314
def exists?
return false unless path_with_namespace
Gitlab::GitalyClient.migrate(:repository_exists) do |enabled|
if enabled
raw_repository.exists?
else
refs_directory_exists?
end
end
end
cache_method :exists?
delegate :empty?, to: :raw_repository
......@@ -1175,8 +1184,6 @@ class Repository
end
def refs_directory_exists?
return false unless path_with_namespace
File.exist?(File.join(path_to_repo, 'refs'))
end
......
module Ci
class BuildPolicy < CommitStatusPolicy
condition(:protected_action) do
next false unless @subject.action?
condition(:protected_ref) do
access = ::Gitlab::UserAccess.new(@user, project: @subject.project)
if @subject.tag?
!access.can_create_tag?(@subject.ref)
else
!access.can_merge_to_branch?(@subject.ref)
!access.can_update_branch?(@subject.ref)
end
end
rule { protected_action }.prevent :update_build
rule { protected_ref }.prevent :update_build
end
end
module Ci
class PipelinePolicy < BasePolicy
delegate { @subject.project }
condition(:protected_ref) do
access = ::Gitlab::UserAccess.new(@user, project: @subject.project)
if @subject.tag?
!access.can_create_tag?(@subject.ref)
else
!access.can_update_branch?(@subject.ref)
end
end
rule { protected_ref }.prevent :update_pipeline
end
end
......@@ -44,7 +44,7 @@ class GlobalPolicy < BasePolicy
prevent :log_in
end
rule { ~restricted_public_level }.policy do
rule { admin | ~restricted_public_level }.policy do
enable :read_users_list
end
end
......@@ -16,7 +16,8 @@ class BuildDetailsEntity < JobEntity
end
expose :path do |build|
project_merge_request_path(project, build.merge_request)
project_merge_request_path(build.merge_request.project,
build.merge_request)
end
end
......
......@@ -9,7 +9,7 @@ class DeployKeyEntity < Grape::Entity
expose :created_at
expose :updated_at
expose :projects, using: ProjectEntity do |deploy_key|
deploy_key.projects.select { |project| options[:user].can?(:read_project, project) }
deploy_key.projects.without_deleted.select { |project| options[:user].can?(:read_project, project) }
end
expose :can_edit
......
......@@ -15,16 +15,49 @@ module Ci
pipeline_schedule: schedule
)
result = validate(current_user || trigger_request.trigger.owner,
ignore_skip_ci: ignore_skip_ci,
save_on_errors: save_on_errors)
return result if result
Ci::Pipeline.transaction do
update_merge_requests_head_pipeline if pipeline.save
Ci::CreatePipelineStagesService
.new(project, current_user)
.execute(pipeline)
end
cancel_pending_pipelines if project.auto_cancel_pending_pipelines?
pipeline_created_counter.increment(source: source)
pipeline.tap(&:process!)
end
private
def validate(triggering_user, ignore_skip_ci:, save_on_errors:)
unless project.builds_enabled?
return error('Pipeline is disabled')
end
<<<<<<< HEAD
unless project.mirror_trigger_builds?
return error('Pipeline is disabled for mirror updates') if mirror_update
end
unless trigger_request || can?(current_user, :create_pipeline, project)
return error('Insufficient permissions to create a new pipeline')
=======
unless allowed_to_trigger_pipeline?(triggering_user)
if can?(triggering_user, :create_pipeline, project)
return error("Insufficient permissions for protected ref '#{ref}'")
else
return error('Insufficient permissions to create a new pipeline')
end
>>>>>>> upstream/master
end
unless branch? || tag?
......@@ -50,7 +83,9 @@ module Ci
unless pipeline.has_stage_seeds?
return error('No stages / jobs for this pipeline.')
end
end
<<<<<<< HEAD
_create_pipeline(source, &block)
end
......@@ -65,13 +100,27 @@ module Ci
Ci::CreatePipelineStagesService
.new(project, current_user)
.execute(pipeline)
=======
def allowed_to_trigger_pipeline?(triggering_user)
if triggering_user
allowed_to_create?(triggering_user)
else # legacy triggers don't have a corresponding user
!project.protected_for?(ref)
>>>>>>> upstream/master
end
end
cancel_pending_pipelines if project.auto_cancel_pending_pipelines?
pipeline_created_counter.increment(source: source)
def allowed_to_create?(triggering_user)
access = Gitlab::UserAccess.new(triggering_user, project: project)
pipeline.tap(&:process!)
can?(triggering_user, :create_pipeline, project) &&
if branch?
access.can_update_branch?(ref)
elsif tag?
access.can_create_tag?(ref)
else
true # Allow it for now and we'll reject when we check ref existence
end
end
def update_merge_requests_head_pipeline
......@@ -123,15 +172,21 @@ module Ci
end
def branch?
return @is_branch if defined?(@is_branch)
@is_branch =
project.repository.ref_exists?(Gitlab::Git::BRANCH_REF_PREFIX + ref)
end
def tag?
return @is_tag if defined?(@is_tag)
@is_tag =
project.repository.ref_exists?(Gitlab::Git::TAG_REF_PREFIX + ref)
end
def ref
Gitlab::Git.ref_name(origin_ref)
@ref ||= Gitlab::Git.ref_name(origin_ref)
end
def valid_sha?
......
module Ci
class CreateTriggerRequestService
def execute(project, trigger, ref, variables = nil)
module CreateTriggerRequestService
Result = Struct.new(:trigger_request, :pipeline)
def self.execute(project, trigger, ref, variables = nil)
trigger_request = trigger.trigger_requests.create(variables: variables)
pipeline = Ci::CreatePipelineService.new(project, trigger.owner, ref: ref)
.execute(:trigger, ignore_skip_ci: true, trigger_request: trigger_request)
trigger_request if pipeline.persisted?
Result.new(trigger_request, pipeline)
end
end
end
......@@ -552,6 +552,7 @@ module SystemNoteService
create_note(NoteSummary.new(noteable, project, author, body, action: 'moved'))
end
<<<<<<< HEAD
#
# noteable - Noteable object
# noteable_ref - Referenced noteable object
......@@ -606,6 +607,8 @@ module SystemNoteService
create_note(NoteSummary.new(noteable, noteable.project, user, body, action: 'unapproved'))
end
=======
>>>>>>> upstream/master
# Called when a Noteable has been marked as a duplicate of another Issue
#
# noteable - Noteable object
......
......@@ -21,8 +21,8 @@
.commit
= author_avatar(commit, size: 36)
.commit-row-title
%strong
= link_to_gfm truncate(commit.title, length: 35), project_commit_path(@project, commit.id), class: "cdark"
%span.item-title.str-truncated-100
= link_to_gfm commit.title, project_commit_path(@project, commit.id), class: "cdark", title: commit.title
.pull-right
= link_to commit.short_id, project_commit_path(@project, commit), class: "commit-sha"
&nbsp;
......
- if @projects.any?
.project-item-select-holder
= project_select_tag :project_path, class: "project-item-select", data: { include_groups: local_assigns[:include_groups], order_by: 'last_activity_at' }, with_feature_enabled: local_assigns[:with_feature_enabled]
%a.btn.btn-new.new-project-item-select-button{ data: { relative_path: local_assigns[:path] } }
= project_select_tag :project_path, class: "project-item-select", data: { include_groups: local_assigns[:include_groups], order_by: 'last_activity_at', relative_path: local_assigns[:path] }, with_feature_enabled: local_assigns[:with_feature_enabled]
%a.btn.btn-new.new-project-item-select-button
= local_assigns[:label]
= icon('caret-down')
......@@ -6,15 +6,12 @@ class PipelineScheduleWorker
Ci::PipelineSchedule.active.where("next_run_at < ?", Time.now)
.preload(:owner, :project).find_each do |schedule|
begin
unless schedule.runnable_by_owner?
schedule.deactivate!
next
end
Ci::CreatePipelineService.new(schedule.project,
pipeline = Ci::CreatePipelineService.new(schedule.project,
schedule.owner,
ref: schedule.ref)
.execute(:schedule, save_on_errors: false, schedule: schedule)
schedule.deactivate! unless pipeline.persisted?
rescue => e
Rails.logger.error "#{schedule.id}: Failed to create a scheduled pipeline: #{e.message}"
ensure
......
---
title: Fix vertical alignment in firefox and safari for pipeline mini graph
merge_request:
author:
---
title: Disallow running the pipeline if ref is protected and user cannot merge the
branch or create the tag
merge_request: 11910
author:
---
title: Remove project_key from the Jira configuration
merge_request: 12050
author:
---
title: Added link to the MR widget that directs to the monitoring dashboard
merge_request:
author:
---
title: Use only CSS to truncate commit message in blame
merge_request: 12900
author: Takuya Noguchi
---
title: Add link to doc/api/ci/lint.md
merge_request: 12914
author: Takuya Noguchi
---
title: Pending delete projects should not show in deploy keys.
merge_request: 13088
author:
---
title: Fixes 500 error caused by pending delete projects in admin dashboard
merge_request: 13067
author:
---
title: Allow admin to read_users_list even if it's restricted
merge_request: 13066
author:
---
title: Add instrumentation to MarkupHelper#link_to_gfm
merge_request: 13069
author:
---
title: Free up some top level words, reject top level groups named like files in the
public folder
merge_request: 12932
author:
---
title: Fix job merge request link to a forked source project
merge_request: 12965
author:
---
title: Fix sizing of custom header logo in new navigation
merge_request:
author:
......@@ -136,6 +136,9 @@ def instrument_classes(instrumentation)
# This is a Rails scope so we have to instrument it manually.
instrumentation.instrument_method(Project, :visible_to_user)
# Needed for https://gitlab.com/gitlab-org/gitlab-ce/issues/34509
instrumentation.instrument_method(MarkupHelper, :link_to_gfm)
# Needed for https://gitlab.com/gitlab-org/gitlab-ce/issues/30224#note_32306159
instrumentation.instrument_instance_method(MergeRequestDiff, :load_commits)
end
......
......@@ -11,15 +11,11 @@ self-hosted, free to use. Every feature available in GitLab CE is also available
self-hosted, fully featured solution of GitLab, available under distinct [subscriptions](https://about.gitlab.com/products/): **GitLab Enterprise Edition Starter (EES)** and **GitLab Enterprise Edition Premium (EEP)**.
- **GitLab.com**: SaaS GitLab solution, with [free and paid subscriptions](https://about.gitlab.com/gitlab-com/). GitLab.com is hosted by GitLab, Inc., and administrated by GitLab (users don't have access to admin settings).
**GitLab EE** contains all features available in **GitLab CE**,
> **GitLab EE** contains all features available in **GitLab CE**,
plus premium features available in each version: **Enterprise Edition Starter**
(**EES**) and **Enterprise Edition Premium** (**EEP**). Everything available in
**EES** is also available in **EEP**.
**Note:** _We are unifying the documentation for CE and EE. To check if certain feature is
available in CE or EE, look for a note right below the page title containing the GitLab
version which introduced that feature._
----
Shortcuts to GitLab's most visited docs:
......@@ -40,6 +36,7 @@ Shortcuts to GitLab's most visited docs:
### User account
- [User documentation](user/index.md)
- [Authentication](topics/authentication/index.md): Account security with two-factor authentication, setup your ssh keys and deploy keys for secure access to your projects.
- [Profile settings](profile/README.md): Manage your profile settings, two factor authentication and more.
- [User permissions](user/permissions.md): Learn what each role in a project (external/guest/reporter/developer/master/owner) can do.
......
......@@ -465,23 +465,42 @@ on how to achieve that.
## Disable Container Registry but use GitLab as an auth endpoint
You can disable the embedded Container Registry to use an external one, but
still use GitLab as an auth endpoint.
**Omnibus GitLab**
You can use GitLab as an auth endpoint and use a non-bundled Container Registry.
1. Open `/etc/gitlab/gitlab.rb` and set necessary configurations:
```ruby
registry['enable'] = false
gitlab_rails['registry_enabled'] = true
gitlab_rails['registry_host'] = "registry.gitlab.example.com"
gitlab_rails['registry_port'] = "5005"
gitlab_rails['registry_api_url'] = "http://localhost:5000"
gitlab_rails['registry_key_path'] = "/var/opt/gitlab/gitlab-rails/certificate.key"
gitlab_rails['registry_path'] = "/var/opt/gitlab/gitlab-rails/shared/registry"
gitlab_rails['registry_issuer'] = "omnibus-gitlab-issuer"
```
1. A certificate keypair is required for GitLab and the Container Registry to
communicate securely. By default omnibus-gitlab will generate one keypair,
which is saved to `/var/opt/gitlab/gitlab-rails/etc/gitlab-registry.key`.
When using an non-bundled Container Registry, you will need to supply a
custom certificate key. To do that, add the following to
`/etc/gitlab/gitlab.rb`
```ruby
gitlab_rails['registry_key_path'] = "/custom/path/to/registry-key.key"
# registry['internal_key'] should contain the contents of the custom key
# file. Line breaks in the key file should be marked using `\n` character
# Example:
registry['internal_key'] = "---BEGIN RSA PRIVATE KEY---\nMIIEpQIBAA\n"
```
**Note:** The file specified at `registry_key_path` gets populated with the
content specified by `internal_key`, each time reconfigure is executed. If
no file is specified, omnibus-gitlab will default it to
`/var/opt/gitlab/gitlab-rails/etc/gitlab-registry.key` and will populate
it.
1. Save the file and [reconfigure GitLab][] for the changes to take effect.
**Installations from source**
......
......@@ -100,9 +100,12 @@ You can use the [alpha version of the document](alpha_database.md) to try it out
Enter new password:
Enter it again:
```
1. Exit from editing `template1` prompt by typing `\q` and Enter.
1. Enable the `pg_trgm` extension within the `gitlabhq_production` database:
1. Enable the `pg_trgm` extension:
```
gitlab-psql -d gitlabhq_production
CREATE EXTENSION pg_trgm;
# Output:
......
......@@ -47,3 +47,5 @@ Example responses:
"error": "content is missing"
}
```
[ce-5953]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/5953
......@@ -360,7 +360,16 @@ Example response:
"due_date": null,
"web_url": "http://example.com/example/example/issues/1",
"confidential": false,
<<<<<<< HEAD
"weight": null
=======
"_links": {
"self": "http://example.com/api/v4/projects/1/issues/2",
"notes": "http://example.com/api/v4/projects/1/issues/2/notes",
"award_emoji": "http://example.com/api/v4/projects/1/issues/2/award_emoji",
"project": "http://example.com/api/v4/projects/1"
}
>>>>>>> upstream/master
}
```
......@@ -424,7 +433,16 @@ Example response:
"due_date": null,
"web_url": "http://example.com/example/example/issues/14",
"confidential": false,
<<<<<<< HEAD
"weight": null
=======
"_links": {
"self": "http://example.com/api/v4/projects/1/issues/2",
"notes": "http://example.com/api/v4/projects/1/issues/2/notes",
"award_emoji": "http://example.com/api/v4/projects/1/issues/2/award_emoji",
"project": "http://example.com/api/v4/projects/1"
}
>>>>>>> upstream/master
}
```
......@@ -489,7 +507,16 @@ Example response:
"due_date": "2016-07-22",
"web_url": "http://example.com/example/example/issues/15",
"confidential": false,
<<<<<<< HEAD
"weight": null
=======
"_links": {
"self": "http://example.com/api/v4/projects/1/issues/2",
"notes": "http://example.com/api/v4/projects/1/issues/2/notes",
"award_emoji": "http://example.com/api/v4/projects/1/issues/2/award_emoji",
"project": "http://example.com/api/v4/projects/1"
}
>>>>>>> upstream/master
}
```
......@@ -576,7 +603,16 @@ Example response:
"due_date": null,
"web_url": "http://example.com/example/example/issues/11",
"confidential": false,
<<<<<<< HEAD
"weight": null
=======
"_links": {
"self": "http://example.com/api/v4/projects/1/issues/2",
"notes": "http://example.com/api/v4/projects/1/issues/2/notes",
"award_emoji": "http://example.com/api/v4/projects/1/issues/2/award_emoji",
"project": "http://example.com/api/v4/projects/1"
}
>>>>>>> upstream/master
}
```
......@@ -642,7 +678,16 @@ Example response:
"due_date": null,
"web_url": "http://example.com/example/example/issues/11",
"confidential": false,
<<<<<<< HEAD
"weight": null
=======
"_links": {
"self": "http://example.com/api/v4/projects/1/issues/2",
"notes": "http://example.com/api/v4/projects/1/issues/2/notes",
"award_emoji": "http://example.com/api/v4/projects/1/issues/2/award_emoji",
"project": "http://example.com/api/v4/projects/1"
}
>>>>>>> upstream/master
}
```
......
......@@ -100,7 +100,16 @@ Parameters:
"repository_size": 1038090,
"lfs_objects_size": 0,
"job_artifacts_size": 0
}
},
"_links": {
"self": "http://example.com/api/v4/projects",
"issues": "http://example.com/api/v4/projects/1/issues",
"merge_requests": "http://example.com/api/v4/projects/1/merge_requests",
"repo_branches": "http://example.com/api/v4/projects/1/repository_branches",
"labels": "http://example.com/api/v4/projects/1/labels",
"events": "http://example.com/api/v4/projects/1/events",
"members": "http://example.com/api/v4/projects/1/members"
},
},
{
"id": 6,
......@@ -170,6 +179,15 @@ Parameters:
"repository_size": 2066080,
"lfs_objects_size": 0,
"job_artifacts_size": 0
},
"_links": {
"self": "http://example.com/api/v4/projects",
"issues": "http://example.com/api/v4/projects/1/issues",
"merge_requests": "http://example.com/api/v4/projects/1/merge_requests",
"repo_branches": "http://example.com/api/v4/projects/1/repository_branches",
"labels": "http://example.com/api/v4/projects/1/labels",
"events": "http://example.com/api/v4/projects/1/events",
"members": "http://example.com/api/v4/projects/1/members"
}
}
]
......@@ -259,6 +277,15 @@ Parameters:
"repository_size": 1038090,
"lfs_objects_size": 0,
"job_artifacts_size": 0
},
"_links": {
"self": "http://example.com/api/v4/projects",
"issues": "http://example.com/api/v4/projects/1/issues",
"merge_requests": "http://example.com/api/v4/projects/1/merge_requests",
"repo_branches": "http://example.com/api/v4/projects/1/repository_branches",
"labels": "http://example.com/api/v4/projects/1/labels",
"events": "http://example.com/api/v4/projects/1/events",
"members": "http://example.com/api/v4/projects/1/members"
}
},
{
......@@ -328,6 +355,15 @@ Parameters:
"repository_size": 2066080,
"lfs_objects_size": 0,
"job_artifacts_size": 0
},
"_links": {
"self": "http://example.com/api/v4/projects",
"issues": "http://example.com/api/v4/projects/1/issues",
"merge_requests": "http://example.com/api/v4/projects/1/merge_requests",
"repo_branches": "http://example.com/api/v4/projects/1/repository_branches",
"labels": "http://example.com/api/v4/projects/1/labels",
"events": "http://example.com/api/v4/projects/1/events",
"members": "http://example.com/api/v4/projects/1/members"
}
}
]
......@@ -431,6 +467,15 @@ Parameters:
"repository_size": 1038090,
"lfs_objects_size": 0,
"job_artifacts_size": 0
},
"_links": {
"self": "http://example.com/api/v4/projects",
"issues": "http://example.com/api/v4/projects/1/issues",
"merge_requests": "http://example.com/api/v4/projects/1/merge_requests",
"repo_branches": "http://example.com/api/v4/projects/1/repository_branches",
"labels": "http://example.com/api/v4/projects/1/labels",
"events": "http://example.com/api/v4/projects/1/events",
"members": "http://example.com/api/v4/projects/1/members"
}
}
```
......@@ -669,7 +714,16 @@ Example response:
"shared_with_groups": [],
"only_allow_merge_if_pipeline_succeeds": false,
"only_allow_merge_if_all_discussions_are_resolved": false,
"request_access_enabled": false
"request_access_enabled": false,
"_links": {
"self": "http://example.com/api/v4/projects",
"issues": "http://example.com/api/v4/projects/1/issues",
"merge_requests": "http://example.com/api/v4/projects/1/merge_requests",
"repo_branches": "http://example.com/api/v4/projects/1/repository_branches",
"labels": "http://example.com/api/v4/projects/1/labels",
"events": "http://example.com/api/v4/projects/1/events",
"members": "http://example.com/api/v4/projects/1/members"
}
}
```
......@@ -735,7 +789,16 @@ Example response:
"shared_with_groups": [],
"only_allow_merge_if_pipeline_succeeds": false,
"only_allow_merge_if_all_discussions_are_resolved": false,
"request_access_enabled": false
"request_access_enabled": false,
"_links": {
"self": "http://example.com/api/v4/projects",
"issues": "http://example.com/api/v4/projects/1/issues",
"merge_requests": "http://example.com/api/v4/projects/1/merge_requests",
"repo_branches": "http://example.com/api/v4/projects/1/repository_branches",
"labels": "http://example.com/api/v4/projects/1/labels",
"events": "http://example.com/api/v4/projects/1/events",
"members": "http://example.com/api/v4/projects/1/members"
}
}
```
......@@ -819,7 +882,16 @@ Example response:
"shared_with_groups": [],
"only_allow_merge_if_pipeline_succeeds": false,
"only_allow_merge_if_all_discussions_are_resolved": false,
"request_access_enabled": false
"request_access_enabled": false,
"_links": {
"self": "http://example.com/api/v4/projects",
"issues": "http://example.com/api/v4/projects/1/issues",
"merge_requests": "http://example.com/api/v4/projects/1/merge_requests",
"repo_branches": "http://example.com/api/v4/projects/1/repository_branches",
"labels": "http://example.com/api/v4/projects/1/labels",
"events": "http://example.com/api/v4/projects/1/events",
"members": "http://example.com/api/v4/projects/1/members"
}
}
```
......@@ -903,7 +975,16 @@ Example response:
"shared_with_groups": [],
"only_allow_merge_if_pipeline_succeeds": false,
"only_allow_merge_if_all_discussions_are_resolved": false,
"request_access_enabled": false
"request_access_enabled": false,
"_links": {
"self": "http://example.com/api/v4/projects",
"issues": "http://example.com/api/v4/projects/1/issues",
"merge_requests": "http://example.com/api/v4/projects/1/merge_requests",
"repo_branches": "http://example.com/api/v4/projects/1/repository_branches",
"labels": "http://example.com/api/v4/projects/1/labels",
"events": "http://example.com/api/v4/projects/1/events",
"members": "http://example.com/api/v4/projects/1/members"
}
}
```
......
......@@ -2,9 +2,11 @@
Since GitLab 9.0, API V4 is the preferred version to be used.
API V3 will be removed in GitLab 9.5, to be released on August 22, 2017. In the
meantime, we advise you to make any necessary changes to applications that use
V3. The V3 API documentation is still [available](https://gitlab.com/gitlab-org/gitlab-ce/blob/8-16-stable/doc/api/README.md).
API V3 will be unsupported from GitLab 9.5, to be released on August
22, 2017. It will be removed in GitLab 9.5 or later. In the meantime, we advise
you to make any necessary changes to applications that use V3. The V3 API
documentation is still
[available](https://gitlab.com/gitlab-org/gitlab-ce/blob/8-16-stable/doc/api/README.md).
Below are the changes made between V3 and V4.
......
......@@ -11,7 +11,11 @@ They are written by members of the GitLab Team and by
- **LDAP**
- [How to configure LDAP with GitLab CE](how_to_configure_ldap_gitlab_ce/index.md)
<<<<<<< HEAD
- [How to configure LDAP with GitLab EE](how_to_configure_ldap_gitlab_ee/index.md)
=======
- [How to configure LDAP with GitLab EE](https://docs.gitlab.com/ee/articles/how_to_configure_ldap_gitlab_ee/)
>>>>>>> upstream/master
## Git
......@@ -24,3 +28,23 @@ They are written by members of the GitLab Team and by
- [Part 2: Quick start guide - Setting up GitLab Pages](../user/project/pages/getting_started_part_two.md)
- [Part 3: Setting Up Custom Domains - DNS Records and SSL/TLS Certificates](../user/project/pages/getting_started_part_three.md)
- [Part 4: Creating and tweaking `.gitlab-ci.yml` for GitLab Pages](../user/project/pages/getting_started_part_four.md)
- [Building a new GitLab Docs site with Nanoc, GitLab CI, and GitLab Pages](https://about.gitlab.com/2016/12/07/building-a-new-gitlab-docs-site-with-nanoc-gitlab-ci-and-gitlab-pages/)
- [GitLab CI: Deployment & Environments](https://about.gitlab.com/2016/08/26/ci-deployment-and-environments/)
## Sofware development
- [In 13 minutes from Kubernetes to a complete application development tool](https://about.gitlab.com/2016/11/14/idea-to-production/)
- [Making CI Easier with GitLab](https://about.gitlab.com/2017/07/13/making-ci-easier-with-gitlab/)
- [Fast and Natural Continuous Integration with GitLab CI](https://about.gitlab.com/2017/05/22/fast-and-natural-continuous-integration-with-gitlab-ci/)
- [GitLab Workflow, an Overview](https://about.gitlab.com/2016/10/25/gitlab-workflow-an-overview/)
- [Continuous Integration, Delivery, and Deployment with GitLab](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/)
## Build, test, and deploy with GitLab CI/CD
**Build, test, and deploy** the software you develop with **[GitLab CI/CD](../ci/README.md)**
- [Continuous Delivery of a Spring Boot application with GitLab CI and Kubernetes](https://about.gitlab.com/2016/12/14/continuous-delivery-of-a-spring-boot-application-with-gitlab-ci-and-kubernetes/)
- [Automated Debian Package Build with GitLab CI](https://about.gitlab.com/2016/10/12/automated-debian-package-build-with-gitlab-ci/)
- [Building an Elixir Release into a Docker image using GitLab CI](https://about.gitlab.com/2016/08/11/building-an-elixir-release-into-docker-image-using-gitlab-ci-part-1/)
- [Setting up GitLab CI for Android projects](https://about.gitlab.com/2016/11/30/setting-up-gitlab-ci-for-android-projects/)
- [How to use GitLab CI and MacStadium to build your macOS or iOS projects](https://about.gitlab.com/2017/05/15/how-to-use-macstadium-and-gitlab-ci-to-build-your-macos-or-ios-projects/)
......@@ -447,6 +447,7 @@ A forEach will cause side effects, it will be mutating the array being iterated.
1. `name`
1. `props`
1. `mixins`
1. `directives`
1. `data`
1. `components`
1. `computedProps`
......
......@@ -5,21 +5,31 @@ trackers and external authentication.
See the documentation below for details on how to configure these services.
- [JIRA](../user/project/integrations/jira.md) Integrate with the JIRA issue tracker
- [Akismet](akismet.md) Configure Akismet to stop spam
- [Auth0 OmniAuth](auth0.md) Enable the Auth0 OmniAuth provider
- [Bitbucket](bitbucket.md) Import projects from Bitbucket.org and login to your GitLab instance with your
Bitbucket.org account
- [CAS](cas.md) Configure GitLab to sign in using CAS
- [External issue tracker](external-issue-tracker.md) Redmine, JIRA, etc.
- [Gmail actions buttons](gmail_action_buttons_for_gitlab.md) Adds GitLab actions to messages
- [JIRA](../user/project/integrations/jira.md) Integrate with the JIRA issue tracker
- [Koding](../administration/integration/koding.md) Configure Koding to use IDE integration
- [LDAP](ldap.md) Set up sign in via LDAP
<<<<<<< HEAD
- [Jenkins](jenkins.md) Integrate with the Jenkins CI
- [OmniAuth](omniauth.md) Sign in via Twitter, GitHub, GitLab.com, Google, Bitbucket, Facebook, Shibboleth, SAML, Crowd, Azure and Authentiq ID
- [SAML](saml.md) Configure GitLab as a SAML 2.0 Service Provider
- [CAS](cas.md) Configure GitLab to sign in using CAS
- [Kerberos](kerberos.md) Integrate with Kerberos
=======
>>>>>>> upstream/master
- [OAuth2 provider](oauth_provider.md) OAuth2 application creation
- [OmniAuth](omniauth.md) Sign in via Twitter, GitHub, GitLab.com, Google, Bitbucket, Facebook, Shibboleth, SAML, Crowd, Azure and Authentiq ID
- [OpenID Connect](openid_connect_provider.md) Use GitLab as an identity provider
- [Gmail actions buttons](gmail_action_buttons_for_gitlab.md) Adds GitLab actions to messages
- [reCAPTCHA](recaptcha.md) Configure GitLab to use Google reCAPTCHA for new users
- [Akismet](akismet.md) Configure Akismet to stop spam
- [Koding](../administration/integration/koding.md) Configure Koding to use IDE integration
- [PlantUML](../administration/integration/plantuml.md) Configure PlantUML to use diagrams in AsciiDoc documents.
- [reCAPTCHA](recaptcha.md) Configure GitLab to use Google reCAPTCHA for new users
- [SAML](saml.md) Configure GitLab as a SAML 2.0 Service Provider
- [Trello](trello_power_up.md) Integrate Trello with GitLab
> GitLab Enterprise Edition contains [advanced Jenkins support][jenkins].
......
# User documentation
Welcome to GitLab! We're glad to have you here!
As a GitLab user you'll have access to all the features
your [subscription](https://about.gitlab.com/products/)
includes, except [GitLab administrator](../README.md#administrator-documentation)
settings, unless you have admin privileges to install, configure,
and upgrade your GitLab instance.
For GitLab.com, admin privileges are restricted to the GitLab team.
If you run your own GitLab instance and are looking for the administration settings,
please refer to the [administration](../README.md#administrator-documentation)
documentation.
## Overview
GitLab is a fully integrated software development platform that enables you
and your team to work cohesively, faster, transparently, and effectively,
since the discussion of a new idea until taking that idea to production all
all the way through, from within the same platform.
Please check this page for an overview on [GitLab's features](https://about.gitlab.com/features/).
## Use cases
GitLab is a git-based platforms that integrates a great number of essential tools for software development and deployment, and project management:
- Code hosting in repositories with version control
- Track proposals for new implementations, bug reports, and feedback with a
fully featured [Issue Tracker](project/issues/index.md#issue-tracker)
- Organize and prioritize with [Issue Boards](project/issues/index.md#issue-boards)
- Code review in [Merge Requests](project/merge_requests/index.md) with live-preview changes per
branch with [Review Apps](../ci/review_apps/index.md)
- Build, test and deploy with built-in [Continuous Integration](../ci/README.md)
- Deploy your personal and professional static websites with [GitLab Pages](project/pages/index.md)
- Integrate with Docker with [GitLab Container Registry](project/container_registry.md)
- Track the development lifecycle with [GitLab Cycle Analytics](project/cycle_analytics.md)
With GitLab Enterprise Edition, you can also:
- Provide support with [Service Desk](https://docs.gitlab.com/ee/user/project/service_desk.html)
- Improve collaboration with
[Merge Request Approvals](https://docs.gitlab.com/ee/user/project/merge_requests/index.html#merge-request-approvals),
[Multiple Assignees for Issues](https://docs.gitlab.com/ee/user/project/issues/multiple_assignees_for_issues.html),
and [Multiple Issue Boards](https://docs.gitlab.com/ee/user/project/issue_board.html#multiple-issue-boards)
- Create formal relashionships between issues with [Related Issues](https://docs.gitlab.com/ee/user/project/issues/related_issues.html)
- Use [Burndown Charts](https://docs.gitlab.com/ee/user/project/milestones/burndown_charts.html) to track progress during a sprint or while working on a new version of their software.
- Leverage [Elasticsearch](https://docs.gitlab.com/ee/integration/elasticsearch.html) with [Advanced Global Search](https://docs.gitlab.com/ee/user/search/advanced_global_search.html) and [Advanced Syntax Search](https://docs.gitlab.com/ee/user/search/advanced_search_syntax.html) for faster, more advanced code search across your entire GitLab instance
- [Authenticate users with Kerberos](https://docs.gitlab.com/ee/integration/kerberos.html)
- [Mirror a repository](https://docs.gitlab.com/ee/workflow/repository_mirroring.html) from elsewhere on your local server.
- [Export issues as CSV](https://docs.gitlab.com/ee/user/project/issues/csv_export.html)
- View your entire CI/CD pipeline involving more than one project with [Multiple-Project Pipeline Graphs](https://docs.gitlab.com/ee/ci/multi_project_pipeline_graphs.html)
- [Lock files](https://docs.gitlab.com/ee/user/project/file_lock.html) to prevent conflicts
- View of the current health and status of each CI environment running on Kubernetes with [Deploy Boards](https://docs.gitlab.com/ee/user/project/deploy_boards.html)
- Leverage your continuous delivery method with [Canary Deployments](https://docs.gitlab.com/ee/user/project/canary_deployments.html)
You can also [integrate](project/integrations/project_services.md) GitLab with numerous third-party applications, such as Mattermost, Microsoft Teams, HipChat, Trello, Slack, Bamboo CI, JIRA, and a lot more.
### Articles
For a complete workflow use case please check [GitLab Workflow, an Overview](https://about.gitlab.com/2016/10/25/gitlab-workflow-an-overview/#gitlab-workflow-use-case-scenario).
For more use cases please check our [Technical Articles](../articles/index.md).
## Projects
In GitLab, you can create projects for numerous reasons, such as, host
your code, use it as an issue tracker, collaborate on code, and continuously
build, test, and deploy your app with built-in GitLab CI/CD. Or, you can do
it all at once, from one single project.
### Issues
Explore the best of GitLab [Issues](project/issues/index.md).
### Merge Requests
Collanorate on code, gather reviews, live preview changes per branch, and
request approvals with [Merge Requests](project/merge_requests/index.md).
### Milestones
Work on multiple issues and merge requests towards the same target date
with [Milestones](project/milestones/index.md).
### GitLab Pages
Publish your static site directly from GitLab with [GitLab Pages](project/pages/index.md). You
can [build, test, and deploy any Static Site Generator](https://about.gitlab.com/2016/06/17/ssg-overview-gitlab-pages-part-3-examples-ci/) with Pages.
### Container Registry
Build and deploy Docker images with [GitLab Container Registry](project/container_registry.md).
## GitLab CI/CD
Use built-in [GitLab CI/CD](../ci/README.md) to test, build, and deploy your applications
directly from GitLab. No third-party integrations needed.
### Auto Deploy
Deploy your application out-of-the-box with [GitLab Auto Deploy](../ci/autodeploy/index.md).
### Review Apps
Live-preview the changes introduced by a merge request with [Review Apps](../ci/review_apps/index.md).
## Groups
With GitLab [Groups](group/index.md) you can assemble related projects together
and grant members access to several projects at once.
### Subgroups
Groups can also be nested in [subgroups](group/subgroups/index.md).
## Account
There is a lot you can customize and configure
to enjoy the best of GitLab.
Manage your user settings to change your personal info,
personal access tokens, authorized applications, integrations, etc.
### Authentication
Read through the [authentication](../topics/authentication/index.md) methods available in GitLab.
### Permissions
Learn the different set of [permissions](permissions.md) for user type (guest, reporter, developer, master, owner).
## Integrations
[Integrate GitLab](../integration/README.md) with your preferred tool,
such as Trello, JIRA, etc.
## Git and GitLab
Learn what is [Git](../topics/git/index.md) and its best practices.
## Discussions
In GitLab, you can comment and mention collaborators in issues,
merge requests, code snippets, and commits.
When performing inline reviews to implementations
to your codebase through merge requests you can
gather feedback through [resolvable discussions](discussions/index.md#resolvable-discussions).
## Todos
Never forget to reply to your collaborators. [GitLab Todos](../workflow/todos.md)
are a tool for working faster and more effectively with your team,
by listing all user or group mentions, as well as issues and merge
requests you're assigned to.
## Snippets
[Snippets](snippets.md) are code blocks that you want to store in GitLab, from which
you have quick access to. You can also gather feedback on them through
[discussions](#discussions).
## Webhooks
Configure [webhooks](project/integrations/webhooks.html) to listen for
specific events like pushes, issues or merge requests. GitLab will send a
POST request with data to the webhook URL.
## API
Automate GitLab via [API](../api/README.html).
......@@ -98,11 +98,11 @@ in the table below.
| Field | Description |
| ----- | ----------- |
| `Web URL` | The base URL to the JIRA instance web interface which is being linked to this GitLab project. E.g., `https://jira.example.com`. |
| `JIRA API URL` | The base URL to the JIRA instance API. E.g., `https://jira-api.example.com`. This is optional. If not entered, the Web URL value be used. |
| `JIRA API URL` | The base URL to the JIRA instance API. Web URL value will be used if not set. E.g., `https://jira-api.example.com`. |
| `Project key` | Put a JIRA project key (in uppercase), e.g. `MARS` in this field. This is only for testing the configuration settings. JIRA integration in GitLab works with _all_ JIRA projects in your JIRA instance. This field will be removed in a future release. |
| `Username` | The user name created in [configuring JIRA step](#configuring-jira). |
| `Password` |The password of the user created in [configuring JIRA step](#configuring-jira). |
| `JIRA issue transition` | This is the ID of a transition that moves issues to a closed state. You can find this number under JIRA workflow administration ([see screenshot](img/jira_workflow_screenshot.png)). **Closing JIRA issues via commits or Merge Requests won't work if you don't set the ID correctly.** |
| `Transition ID` | This is the ID of a transition that moves issues to a closed state. You can find this number under JIRA workflow administration ([see screenshot](img/jira_workflow_screenshot.png)). **Closing JIRA issues via commits or Merge Requests won't work if you don't set the ID correctly.** |
After saving the configuration, your GitLab project will be able to interact
with all JIRA projects in your JIRA instance.
......
......@@ -71,9 +71,10 @@ The next time a pipeline is scheduled, your credentials will be used.
>**Note:**
When the owner of the schedule doesn't have the ability to create pipelines
anymore, due to e.g., being blocked or removed from the project, the schedule
is deactivated. Another user can take ownership and activate it, so the
schedule can be run again.
anymore, due to e.g., being blocked or removed from the project, or lacking
the permission to run on protected branches or tags. When this happened, the
schedule is deactivated. Another user can take ownership and activate it, so
the schedule can be run again.
## Advanced admin configuration
......
......@@ -41,6 +41,9 @@ do.
| `/clear_weight` | Clears the issue weight |
| `/board_move ~column` | Move issue to column on the board |
| `/duplicate #issue` | Closes this issue and marks it as a duplicate of another issue |
<<<<<<< HEAD
Note: In GitLab EES every issue can have more than one assignee, so commands `/assign`, `/unassign` and `/reassign`
support multiple assignees.
=======
>>>>>>> upstream/master
......@@ -175,7 +175,6 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps
fill_in 'JIRA API URL', with: 'http://jira.example/api'
fill_in 'Username', with: 'gitlab'
fill_in 'Password', with: 'gitlab'
fill_in 'Project Key', with: 'GITLAB'
click_button 'Save'
end
......
......@@ -13,7 +13,11 @@ module API
def expose_url(path)
url_options = Rails.application.routes.default_url_options
<<<<<<< HEAD
host, protocol, port = url_options.slice(:host, :protocol, :port).values
=======
protocol, host, port = url_options.slice(:protocol, :host, :port).values
>>>>>>> upstream/master
URI::HTTP.build(scheme: protocol, host: host, port: port, path: path).to_s
end
......
......@@ -312,12 +312,6 @@ module API
type: String,
desc: 'The base URL to the JIRA instance API. Web URL value will be used if not set. E.g., https://jira-api.example.com'
},
{
required: true,
name: :project_key,
type: String,
desc: 'The short identifier for your JIRA project, all uppercase, e.g., PROJ'
},
{
required: false,
name: :username,
......
......@@ -21,6 +21,7 @@ module API
render_api_error!('variables needs to be a map of key-valued strings', 400)
end
<<<<<<< HEAD
project = find_project(params[:id])
not_found! unless project
......@@ -31,6 +32,16 @@ module API
render_api_error!(result[:message], result[:http_status])
else
present result[:pipeline], with: Entities::Pipeline
=======
# create request and trigger builds
result = Ci::CreateTriggerRequestService.execute(project, trigger, params[:ref].to_s, variables)
pipeline = result.pipeline
if pipeline.persisted?
present pipeline, with: Entities::Pipeline
else
render_validation_error!(pipeline)
>>>>>>> upstream/master
end
end
......
......@@ -294,7 +294,10 @@ module API
expose :upvotes, :downvotes
expose :due_date
expose :confidential
<<<<<<< HEAD
expose :weight, if: ->(issue, _) { issue.supports_weight? }
=======
>>>>>>> upstream/master
expose :web_url do |issue, options|
Gitlab::UrlBuilder.build(issue)
......
......@@ -28,12 +28,13 @@ module API
end
# create request and trigger builds
trigger_request = Ci::CreateTriggerRequestService.new.execute(project, trigger, params[:ref].to_s, variables)
if trigger_request
present trigger_request, with: ::API::V3::Entities::TriggerRequest
result = Ci::CreateTriggerRequestService.execute(project, trigger, params[:ref].to_s, variables)
pipeline = result.pipeline
if pipeline.persisted?
present result.trigger_request, with: ::API::V3::Entities::TriggerRequest
else
errors = 'No builds created'
render_api_error!(errors, 400)
render_validation_error!(pipeline)
end
end
......
......@@ -24,12 +24,13 @@ module Ci
end
# create request and trigger builds
trigger_request = Ci::CreateTriggerRequestService.new.execute(project, trigger, params[:ref], variables)
if trigger_request
present trigger_request, with: Entities::TriggerRequest
result = Ci::CreateTriggerRequestService.execute(project, trigger, params[:ref], variables)
pipeline = result.pipeline
if pipeline.persisted?
present result.trigger_request, with: Entities::TriggerRequest
else
errors = 'No builds created'
render_api_error!(errors, 400)
render_validation_error!(pipeline)
end
end
end
......
......@@ -45,6 +45,8 @@ module Gitlab
:bare?,
to: :rugged
delegate :exists?, to: :gitaly_repository_client
# Default branch in the repository
def root_ref
@root_ref ||= gitaly_migrate(:root_ref) do |is_enabled|
......@@ -208,10 +210,6 @@ module Gitlab
!empty?
end
def repo_exists?
!!rugged
end
# Discovers the default branch based on the repository's available branches
#
# - If no branches are present, returns nil
......@@ -815,6 +813,10 @@ module Gitlab
@gitaly_commit_client ||= Gitlab::GitalyClient::CommitService.new(self)
end
def gitaly_repository_client
@gitaly_repository_client ||= Gitlab::GitalyClient::RepositoryService.new(self)
end
private
# Gitaly note: JV: Trying to get rid of the 'filter' option so we can implement this with 'git'.
......
module Gitlab
module GitalyClient
class RepositoryService
def initialize(repository)
@repository = repository
@gitaly_repo = repository.gitaly_repository
end
def exists?
request = Gitaly::RepositoryExistsRequest.new(repository: @gitaly_repo)
GitalyClient.call(@repository.storage, :repository_service, :exists, request).exists
end
end
end
end
......@@ -14,42 +14,42 @@ module Gitlab
TOP_LEVEL_ROUTES = %w[
-
.well-known
404.html
422.html
500.html
502.html
503.html
abuse_reports
admin
all
api
apple-touch-icon-precomposed.png
apple-touch-icon.png
assets
autocomplete
ci
dashboard
deploy.html
explore
favicon.ico
files
groups
health_check
help
hooks
import
invites
issues
jwt
koding
member
merge_requests
new
notes
notification_settings
oauth
profile
projects
public
repository
robots.txt
s
search
sent_notifications
services
slash-command-logo.png
snippets
teams
u
unicorn_test
unsubscribes
......
......@@ -37,8 +37,8 @@ module Gitlab
request_cache def can_create_tag?(ref)
return false unless can_access_git?
if ProtectedTag.protected?(project, ref)
project.protected_tags.protected_ref_accessible_to?(ref, user, action: :create)
if protected?(ProtectedTag, project, ref)
protected_tag_accessible_to?(ref, action: :create)
else
user.can?(:push_code, project)
end
......@@ -47,20 +47,24 @@ module Gitlab
request_cache def can_delete_branch?(ref)
return false unless can_access_git?
if ProtectedBranch.protected?(project, ref)
if protected?(ProtectedBranch, project, ref)
user.can?(:delete_protected_branch, project)
else
user.can?(:push_code, project)
end
end
def can_update_branch?(ref)
can_push_to_branch?(ref) || can_merge_to_branch?(ref)
end
request_cache def can_push_to_branch?(ref)
return false unless can_access_git?
if ProtectedBranch.protected?(project, ref)
if protected?(ProtectedBranch, project, ref)
return true if project.empty_repo? && project.user_can_push_to_empty_repo?(user)
project.protected_branches.protected_ref_accessible_to?(ref, user, action: :push)
protected_branch_accessible_to?(ref, action: :push)
else
user.can?(:push_code, project)
end
......@@ -69,8 +73,8 @@ module Gitlab
request_cache def can_merge_to_branch?(ref)
return false unless can_access_git?
if ProtectedBranch.protected?(project, ref)
project.protected_branches.protected_ref_accessible_to?(ref, user, action: :merge)
if protected?(ProtectedBranch, project, ref)
protected_branch_accessible_to?(ref, action: :merge)
else
user.can?(:push_code, project)
end
......@@ -87,5 +91,23 @@ module Gitlab
def can_access_git?
user && user.can?(:access_git)
end
def protected_branch_accessible_to?(ref, action:)
ProtectedBranch.protected_ref_accessible_to?(
ref, user,
action: action,
protected_refs: project.protected_branches)
end
def protected_tag_accessible_to?(ref, action:)
ProtectedTag.protected_ref_accessible_to?(
ref, user,
action: action,
protected_refs: project.protected_tags)
end
request_cache def protected?(kind, project, ref)
kind.protected?(project, ref)
end
end
end
# Андрей Витюк <andruwa13@gmail.com>, 2017. #zanata
# Huang Tao <htve@outlook.com>, 2017. #zanata
# Андрей Витюк <andruwa13@gmail.com>, 2017. #zanata
msgid ""
msgstr ""
"Project-Id-Version: gitlab 1.0.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-06-28 13:32+0200\n"
"POT-Creation-Date: 2017-07-05 08:50-0500\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"PO-Revision-Date: 2017-07-12 09:05-0400\n"
"Last-Translator: Андрей Витюк <andruwa13@gmail.com>\n"
"Language-Team: Ukrainian (https://translate.zanata.org/project/view/GitLab)\n"
"PO-Revision-Date: 2017-07-25 03:27-0400\n"
"Last-Translator: Андрей Витюк <andruwa13@gmail.com>\n"
"Language: uk\n"
"X-Generator: Zanata 3.9.6\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
......@@ -57,7 +57,7 @@ msgid "Add Changelog"
msgstr "Додати список змін (Changelog)"
msgid "Add Contribution guide"
msgstr "Додати керівництво для контрибуторів"
msgstr "Додати керівництво для контриб’юторів"
msgid "Add License"
msgstr "Додати ліцензію"
......@@ -209,7 +209,9 @@ msgstr[1] "Комміта"
msgstr[2] "Коммітів"
msgid "Commit duration in minutes for last 30 commits"
msgstr "Комміт тривалість у хвилинах за останні 30 коммітів"
msgstr ""
"Тривалість коммітів протягом декількох хвилин на протязі 30 останніх "
"коммітів"
msgid "Commit message"
msgstr "Комміт повідомлення"
......@@ -236,10 +238,10 @@ msgid "Compare"
msgstr "Порівняти"
msgid "Contribution guide"
msgstr "Керівництво контрибуторів"
msgstr "Керівництво контриб’юторів"
msgid "Contributors"
msgstr "Контрибутори"
msgstr "Контриб’ютори"
msgid "Copy URL to clipboard"
msgstr "Скопіювати URL в буфер обміну"
......@@ -352,16 +354,16 @@ msgid "Download"
msgstr "Завантажити"
msgid "Download tar"
msgstr "Завантажити в форматі tar"
msgstr "Завантажити tar"
msgid "Download tar.bz2"
msgstr "Завантажити в форматі tar.bz2"
msgstr "Завантажити tar.bz2"
msgid "Download tar.gz"
msgstr "Завантажити в форматі tar.gz"
msgstr "Завантажити tar.gz"
msgid "Download zip"
msgstr "Завантажити в форматі zip"
msgstr "Завантажити zip"
msgid "DownloadArtifacts|Download"
msgstr "Завантажити"
......@@ -397,7 +399,7 @@ msgid "Failed to remove the pipeline schedule"
msgstr "Не вдалося видалити розклад Конвеєра"
msgid "Files"
msgstr "Файли"
msgstr "Файлів"
msgid "Filter by commit message"
msgstr "Фільтрувати повідомлення коммітів"
......@@ -436,7 +438,7 @@ msgid "GoToYourFork|Fork"
msgstr "Форк"
msgid "Home"
msgstr "Початок"
msgstr "Головна"
msgid "Housekeeping successfully started"
msgstr "Очищення успішно розпочато"
......@@ -451,13 +453,13 @@ msgid "Introducing Cycle Analytics"
msgstr "Представляємо аналітику циклу"
msgid "Jobs for last month"
msgstr "Завдання за останній місяць"
msgstr "Кількість завдань за останній місяць"
msgid "Jobs for last week"
msgstr "Завдання за останній тиждень"
msgstr "Кількість завдань за останній тиждень"
msgid "Jobs for last year"
msgstr "Завдання за останній рік"
msgstr "Кількість завдань за останній рік"
msgid "LFSStatus|Disabled"
msgstr "Вимкнено"
......@@ -508,7 +510,7 @@ msgid "New Issue"
msgid_plural "New Issues"
msgstr[0] "Нова проблема"
msgstr[1] "Нові проблеми"
msgstr[2] "Новах проблем"
msgstr[2] "Нових проблем"
msgid "New Pipeline Schedule"
msgstr "Новий розклад Конвеєра"
......@@ -654,6 +656,12 @@ msgstr "Всі"
msgid "PipelineSchedules|Inactive"
msgstr "Неактивні"
msgid "PipelineSchedules|Input variable key"
msgstr "Введіть ім'я змінної"
msgid "PipelineSchedules|Input variable value"
msgstr "Вхідні значення змінних"
msgid "PipelineSchedules|Next Run"
msgstr "Наступний запуск"
......@@ -663,12 +671,18 @@ msgstr "Немає"
msgid "PipelineSchedules|Provide a short description for this pipeline"
msgstr "Задайте короткий опис для цього Конвеєру"
msgid "PipelineSchedules|Remove variable row"
msgstr "Видалити змінні"
msgid "PipelineSchedules|Take ownership"
msgstr "Стати власником"
msgid "PipelineSchedules|Target"
msgstr "Ціль"
msgid "PipelineSchedules|Variables"
msgstr "Змінні"
msgid "PipelineSheduleIntervalPattern|Custom"
msgstr "Власні"
......@@ -745,7 +759,7 @@ msgid "ProjectLifecycle|Stage"
msgstr "Етап"
msgid "ProjectNetworkGraph|Graph"
msgstr "Графік"
msgstr "Історія"
msgid "Read more"
msgstr "Докладніше"
......@@ -840,7 +854,7 @@ msgid "Source code"
msgstr "Код"
msgid "StarProject|Star"
msgstr "Старт"
msgstr "Підписатися"
msgid "Start a %{new_merge_request} with these changes"
msgstr "Почати %{new_merge_request} з цих змін"
......@@ -976,19 +990,19 @@ msgid "Timeago|%s minutes remaining"
msgstr "%s хвилини залишитися"
msgid "Timeago|%s months ago"
msgstr "%s місяців тому"
msgstr "%s місяці(в) тому"
msgid "Timeago|%s months remaining"
msgstr "%s місяці, що залишилися"
msgstr "%s місяці(в), що залишилися"
msgid "Timeago|%s seconds remaining"
msgstr "%s секунд, що залишаються"
msgid "Timeago|%s weeks ago"
msgstr "%s тижнів тому"
msgstr "%s тижні(в) тому"
msgid "Timeago|%s weeks remaining"
msgstr "%s тижнів залишилися"
msgstr "%s тижні(в) залишилися"
msgid "Timeago|%s years ago"
msgstr "%s років тому"
......@@ -1018,7 +1032,7 @@ msgid "Timeago|Past due"
msgstr "Прострочені"
msgid "Timeago|a day ago"
msgstr "годин тому"
msgstr "День тому"
msgid "Timeago|a month ago"
msgstr "місяць тому"
......@@ -1042,28 +1056,28 @@ msgid "Timeago|about an hour ago"
msgstr "Близько години тому"
msgid "Timeago|in %s days"
msgstr "через %s днїв"
msgstr "через %s дні(в)"
msgid "Timeago|in %s hours"
msgstr "через %s години"
msgstr "через %s годин(и)"
msgid "Timeago|in %s minutes"
msgstr "через %s хвилини"
msgstr "через %s хвилин(и)"
msgid "Timeago|in %s months"
msgstr "через %s місяців"
msgstr "через %s місяці(в)"
msgid "Timeago|in %s seconds"
msgstr "через %s секунд"
msgstr "через %s секунд(и)"
msgid "Timeago|in %s weeks"
msgstr "через %s тижні"
msgstr "через %s тижні(в)"
msgid "Timeago|in %s years"
msgstr "через %s років"
msgstr "через %s роки(ів)"
msgid "Timeago|in 1 day"
msgstr "через день"
msgstr "через 1 день"
msgid "Timeago|in 1 hour"
msgstr "через годину"
......@@ -1081,22 +1095,22 @@ msgid "Timeago|in 1 year"
msgstr "через рік"
msgid "Timeago|less than a minute ago"
msgstr "менш хвилини тому"
msgstr "менше хвилини тому"
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] "Година"
msgstr[1] "Годині"
msgstr[2] "Годин"
msgstr[0] "година"
msgstr[1] "години"
msgstr[2] "годин"
msgid "Time|min"
msgid_plural "Time|mins"
msgstr[0] "хвилина"
msgstr[1] "хвилині"
msgstr[1] "хвилини"
msgstr[2] "хвилин"
msgid "Time|s"
msgstr "секунда"
msgstr "секунд(а)"
msgid "Total Time"
msgstr "Загальний час"
......@@ -1105,7 +1119,7 @@ msgid "Total test time for all commits/merges"
msgstr "Загальний час, щоб перевірити всі фіксації/злиття"
msgid "Unstar"
msgstr "Зняти позначку"
msgstr "Відписатись"
msgid "Upload New File"
msgstr "Завантажити новий файл"
......@@ -1117,7 +1131,7 @@ msgid "UploadLink|click to upload"
msgstr "Натисніть, щоб завантажити"
msgid "Use your global notification setting"
msgstr "Використовуються глобальний налаштування повідомлень"
msgstr "Використовуються глобальні налаштування повідомлень"
msgid "View open merge request"
msgstr "Перегляд відкритих запитів на злиття"
......@@ -1140,6 +1154,15 @@ msgstr "Ми не маємо достатньо даних для показу
msgid "Withdraw Access Request"
msgstr "Скасувати запит доступу"
msgid ""
"You are going to remove %{group_name}.\n"
"Removed groups CANNOT be restored!\n"
"Are you ABSOLUTELY sure?"
msgstr ""
"Ви хочете видалити %{group_name}.\n"
"Видалені групи НЕ МОЖНА буду відновити!\n"
"Ви АБСОЛЮТНО впевнені?"
msgid ""
"You are going to remove %{project_name_with_namespace}.\n"
"Removed project CANNOT be restored!\n"
......
......@@ -2,6 +2,7 @@ require 'spec_helper'
describe Admin::DashboardController do
describe '#index' do
<<<<<<< HEAD
it "allows an admin user to access the page" do
sign_in(create(:user, :admin))
get :index
......@@ -21,6 +22,22 @@ describe Admin::DashboardController do
get :index
expect(response).to have_http_status(404)
=======
context 'with pending_delete projects' do
render_views
it 'does not retrieve projects that are pending deletion' do
sign_in(create(:admin))
project = create(:project)
pending_delete_project = create(:project, pending_delete: true)
get :index
expect(response.body).to match(project.name)
expect(response.body).not_to match(pending_delete_project.name)
end
>>>>>>> upstream/master
end
end
end
......@@ -827,7 +827,7 @@ describe Projects::IssuesController do
delete :destroy, namespace_id: project.namespace, project_id: project, id: issue.iid
expect(response).to have_http_status(302)
expect(controller).to set_flash[:notice].to(/The issue was successfully deleted\./).now
expect(controller).to set_flash[:notice].to(/The issue was successfully deleted\./)
end
it 'delegates the update of the todos count cache to TodoService' do
......
......@@ -7,6 +7,10 @@ describe Projects::JobsController do
let(:pipeline) { create(:ci_pipeline, project: project) }
let(:user) { create(:user) }
before do
stub_not_protect_default_branch
end
describe 'GET index' do
context 'when scope is pending' do
before do
......
......@@ -440,7 +440,7 @@ describe Projects::MergeRequestsController do
delete :destroy, namespace_id: project.namespace, project_id: project, id: merge_request.iid
expect(response).to have_http_status(302)
expect(controller).to set_flash[:notice].to(/The merge request was successfully deleted\./).now
expect(controller).to set_flash[:notice].to(/The merge request was successfully deleted\./)
end
it 'delegates the update of the todos count cache to TodoService' do
......
......@@ -8,6 +8,7 @@ describe Projects::PipelinesController do
let(:feature) { ProjectFeature::DISABLED }
before do
stub_not_protect_default_branch
project.add_developer(user)
project.project_feature.update(
builds_access_level: feature)
......
......@@ -23,7 +23,7 @@ describe SentNotificationsController, type: :controller do
end
it 'sets the flash message' do
expect(controller).to set_flash[:notice].to(/unsubscribed/).now
expect(controller).to set_flash[:notice].to(/unsubscribed/)
end
it 'redirects to the login page' do
......@@ -83,7 +83,7 @@ describe SentNotificationsController, type: :controller do
end
it 'sets the flash message' do
expect(controller).to set_flash[:notice].to(/unsubscribed/).now
expect(controller).to set_flash[:notice].to(/unsubscribed/)
end
it 'redirects to the issue page' do
......@@ -109,7 +109,7 @@ describe SentNotificationsController, type: :controller do
end
it 'sets the flash message' do
expect(controller).to set_flash[:notice].to(/unsubscribed/).now
expect(controller).to set_flash[:notice].to(/unsubscribed/)
end
it 'redirects to the merge request page' do
......
......@@ -78,5 +78,23 @@ RSpec.describe 'Dashboard Issues', feature: true do
expect(page).not_to have_content(project_with_issues_disabled.name_with_namespace)
end
end
it 'shows the new issue page', js: true do
Gitlab::Application.routes.default_url_options = {
host: Capybara.current_session.server.host,
port: Capybara.current_session.server.port,
protocol: 'http'
}
find('.new-project-item-select-button').trigger('click')
wait_for_requests
find('.select2-results li').click
expect(page).to have_current_path("/#{project.path_with_namespace}/issues/new")
page.within('#content-body') do
expect(page).to have_selector('.issue-form')
end
end
end
end
......@@ -119,6 +119,7 @@ feature 'Issues > User uses quick actions', feature: true, js: true do
end
end
<<<<<<< HEAD
describe 'adding a weight from a note' do
let(:issue) { create(:issue, project: project) }
......@@ -195,6 +196,8 @@ feature 'Issues > User uses quick actions', feature: true, js: true do
end
end
=======
>>>>>>> upstream/master
describe 'mark issue as duplicate' do
let(:issue) { create(:issue, project: project) }
let(:original_issue) { create(:issue, project: project) }
......
......@@ -6,17 +6,12 @@ feature 'Setup Jira service', :feature, :js do
let(:service) { project.create_jira_service }
let(:url) { 'http://jira.example.com' }
def stub_project_url
WebMock.stub_request(:get, 'http://jira.example.com/rest/api/2/project/GitLabProject')
.with(basic_auth: %w(username password))
end
let(:test_url) { 'http://jira.example.com/rest/api/2/serverInfo' }
def fill_form(active = true)
check 'Active' if active
fill_in 'service_url', with: url
fill_in 'service_project_key', with: 'GitLabProject'
fill_in 'service_username', with: 'username'
fill_in 'service_password', with: 'password'
fill_in 'service_jira_issue_transition_id', with: '25'
......@@ -31,11 +26,10 @@ feature 'Setup Jira service', :feature, :js do
describe 'user sets and activates Jira Service' do
context 'when Jira connection test succeeds' do
before do
stub_project_url
end
it 'activates the JIRA service' do
server_info = { key: 'value' }.to_json
WebMock.stub_request(:get, test_url).with(basic_auth: %w(username password)).to_return(body: server_info)
click_link('JIRA')
fill_form
click_button('Test settings and save changes')
......@@ -47,10 +41,6 @@ feature 'Setup Jira service', :feature, :js do
end
context 'when Jira connection test fails' do
before do
stub_project_url.to_return(status: 401)
end
it 'shows errors when some required fields are not filled in' do
click_link('JIRA')
......@@ -64,6 +54,9 @@ feature 'Setup Jira service', :feature, :js do
end
it 'activates the JIRA service' do
WebMock.stub_request(:get, test_url).with(basic_auth: %w(username password))
.to_raise(JIRA::HTTPError.new(double(message: 'message')))
click_link('JIRA')
fill_form
click_button('Test settings and save changes')
......
......@@ -10,6 +10,7 @@ const deploymentMockData = [
url: '/root/acets-review-apps/environments/15',
stop_url: '/root/acets-review-apps/environments/15/stop',
metrics_url: '/root/acets-review-apps/environments/15/deployments/1/metrics',
metrics_monitoring_url: '/root/acets-review-apps/environments/15/metrics',
external_url: 'http://diplo.',
external_url_formatted: 'diplo.',
deployed_at: '2017-03-22T22:44:42.258Z',
......
......@@ -3,6 +3,7 @@ import memoryUsageComponent from '~/vue_merge_request_widget/components/mr_widge
import MRWidgetService from '~/vue_merge_request_widget/services/mr_widget_service';
const url = '/root/acets-review-apps/environments/15/deployments/1/metrics';
const monitoringUrl = '/root/acets-review-apps/environments/15/metrics';
const metricsMockData = {
success: true,
......@@ -39,6 +40,7 @@ const createComponent = () => {
el: document.createElement('div'),
propsData: {
metricsUrl: url,
metricsMonitoringUrl: monitoringUrl,
memoryMetrics: [],
deploymentTime: 0,
hasMetrics: false,
......
......@@ -48,7 +48,9 @@ describe Gitlab::Ci::Status::Build::Cancelable do
describe '#has_action?' do
context 'when user is allowed to update build' do
before do
build.project.team << [user, :developer]
stub_not_protect_default_branch
build.project.add_developer(user)
end
it { is_expected.to have_action }
......
......@@ -7,7 +7,9 @@ describe Gitlab::Ci::Status::Build::Factory do
let(:factory) { described_class.new(build, user) }
before do
project.team << [user, :developer]
stub_not_protect_default_branch
project.add_developer(user)
end
context 'when build is successful' do
......@@ -225,19 +227,19 @@ describe Gitlab::Ci::Status::Build::Factory do
end
context 'when user has ability to play action' do
before do
project.add_developer(user)
create(:protected_branch, :developers_can_merge,
name: build.ref, project: project)
end
it 'fabricates status that has action' do
expect(status).to have_action
end
end
context 'when user does not have ability to play action' do
before do
allow(build.project).to receive(:empty_repo?).and_return(false)
create(:protected_branch, :no_one_can_push,
name: build.ref, project: build.project)
end
it 'fabricates status that has no action' do
expect(status).not_to have_action
end
......@@ -262,6 +264,13 @@ describe Gitlab::Ci::Status::Build::Factory do
end
context 'when user is not allowed to execute manual action' do
before do
allow(build.project).to receive(:empty_repo?).and_return(false)
create(:protected_branch, :no_one_can_push,
name: build.ref, project: build.project)
end
it 'fabricates status with correct details' do
expect(status.text).to eq 'manual'
expect(status.group).to eq 'manual'
......
......@@ -48,7 +48,9 @@ describe Gitlab::Ci::Status::Build::Retryable do
describe '#has_action?' do
context 'when user is allowed to update build' do
before do
build.project.team << [user, :developer]
stub_not_protect_default_branch
build.project.add_developer(user)
end
it { is_expected.to have_action }
......
......@@ -20,7 +20,9 @@ describe Gitlab::Ci::Status::Build::Stop do
describe '#has_action?' do
context 'when user is allowed to update build' do
before do
build.project.team << [user, :developer]
stub_not_protect_default_branch
build.project.add_developer(user)
end
it { is_expected.to have_action }
......
require 'spec_helper'
describe Gitlab::GitalyClient::RepositoryService do
set(:project) { create(:empty_project) }
let(:storage_name) { project.repository_storage }
let(:relative_path) { project.path_with_namespace + '.git' }
let(:client) { described_class.new(project.repository) }
describe '#exists?' do
it 'sends an exists message' do
expect_any_instance_of(Gitaly::RepositoryService::Stub)
.to receive(:exists)
.with(gitaly_request_with_path(storage_name, relative_path), kind_of(Hash))
.and_call_original
client.exists?
end
end
end
......@@ -36,9 +36,12 @@ describe Gitlab::PathRegex, lib: true do
described_class::PROJECT_WILDCARD_ROUTES.include?(path.split('/').first)
end
def failure_message(missing_words, constant_name, migration_helper)
def failure_message(constant_name, migration_helper, missing_words: [], additional_words: [])
missing_words = Array(missing_words)
<<-MSG
additional_words = Array(additional_words)
message = ""
if missing_words.any?
message += <<-MISSING
Found new routes that could cause conflicts with existing namespaced routes
for groups or projects.
......@@ -51,7 +54,18 @@ describe Gitlab::PathRegex, lib: true do
Make sure to make a note of the renamed records in the release blog post.
MSG
MISSING
end
if additional_words.any?
message += <<-ADDITIONAL
Why are <#{additional_words.join(', ')}> in `#{constant_name}`?
If they are really required, update these specs to reflect that.
ADDITIONAL
end
message
end
let(:all_routes) do
......@@ -68,9 +82,23 @@ describe Gitlab::PathRegex, lib: true do
let(:routes_not_starting_in_wildcard) { routes_without_format.select { |p| p !~ %r{^/[:*]} } }
let(:top_level_words) do
routes_not_starting_in_wildcard.map do |route|
words = routes_not_starting_in_wildcard.map do |route|
route.split('/')[1]
end.compact.uniq
words + ee_top_level_words + files_in_public + Array(API::API.prefix.to_s)
end
let(:ee_top_level_words) do
['unsubscribes']
end
let(:files_in_public) do
git = Gitlab.config.git.bin_path
`cd #{Rails.root} && #{git} ls-files public`
.split("\n")
.map { |entry| entry.gsub('public/', '') }
.uniq
end
# All routes that start with a namespaced path, that have 1 or more
......@@ -115,18 +143,29 @@ describe Gitlab::PathRegex, lib: true do
let(:paths_after_group_id) do
group_routes.map do |route|
route.gsub(STARTING_WITH_GROUP, '').split('/').first
end.uniq
end.uniq + ee_paths_after_group_id
end
let(:ee_paths_after_group_id) do
%w(analytics
ldap
ldap_group_links
notification_setting
audit_events
pipeline_quota hooks)
end
describe 'TOP_LEVEL_ROUTES' do
it 'includes all the top level namespaces' do
failure_block = lambda do
missing_words = top_level_words - described_class::TOP_LEVEL_ROUTES
failure_message(missing_words, 'TOP_LEVEL_ROUTES', 'rename_root_paths')
additional_words = described_class::TOP_LEVEL_ROUTES - top_level_words
failure_message('TOP_LEVEL_ROUTES', 'rename_root_paths',
missing_words: missing_words, additional_words: additional_words)
end
expect(described_class::TOP_LEVEL_ROUTES)
.to include(*top_level_words), failure_block
.to contain_exactly(*top_level_words), failure_block
end
end
......@@ -134,11 +173,13 @@ describe Gitlab::PathRegex, lib: true do
it "don't contain a second wildcard" do
failure_block = lambda do
missing_words = paths_after_group_id - described_class::GROUP_ROUTES
failure_message(missing_words, 'GROUP_ROUTES', 'rename_child_paths')
additional_words = described_class::GROUP_ROUTES - paths_after_group_id
failure_message('GROUP_ROUTES', 'rename_child_paths',
missing_words: missing_words, additional_words: additional_words)
end
expect(described_class::GROUP_ROUTES)
.to include(*paths_after_group_id), failure_block
.to contain_exactly(*paths_after_group_id), failure_block
end
end
......@@ -147,7 +188,7 @@ describe Gitlab::PathRegex, lib: true do
aggregate_failures do
all_wildcard_paths.each do |path|
expect(wildcards_include?(path))
.to be(true), failure_message(path, 'PROJECT_WILDCARD_ROUTES', 'rename_wildcard_paths')
.to be(true), failure_message('PROJECT_WILDCARD_ROUTES', 'rename_wildcard_paths', missing_words: path)
end
end
end
......
......@@ -738,6 +738,8 @@ describe Ci::Pipeline, models: true do
context 'on failure and build retry' do
before do
stub_not_protect_default_branch
build.drop
project.add_developer(user)
......@@ -1003,6 +1005,8 @@ describe Ci::Pipeline, models: true do
let(:latest_status) { pipeline.statuses.latest.pluck(:status) }
before do
stub_not_protect_default_branch
project.add_developer(user)
end
......
......@@ -13,12 +13,6 @@ describe List do
it { is_expected.to validate_presence_of(:position) }
it { is_expected.to validate_numericality_of(:position).only_integer.is_greater_than_or_equal_to(0) }
it 'validates uniqueness of label scoped to board_id' do
create(:list)
expect(subject).to validate_uniqueness_of(:label_id).scoped_to(:board_id)
end
context 'when list_type is set to closed' do
subject { described_class.new(list_type: :closed) }
......
......@@ -11,7 +11,14 @@ RSpec.describe NotificationSetting, type: :model do
it { is_expected.to validate_presence_of(:user) }
it { is_expected.to validate_presence_of(:level) }
it { is_expected.to validate_uniqueness_of(:user_id).scoped_to([:source_id, :source_type]).with_message(/already exists in source/) }
describe 'user_id' do
before do
subject.user = create(:user)
end
it { is_expected.to validate_uniqueness_of(:user_id).scoped_to([:source_type, :source_id]).with_message(/already exists in source/) }
end
context "events" do
let(:user) { create(:user) }
......
......@@ -11,7 +11,7 @@ describe PagesDomain, models: true do
context 'is unique' do
let(:domain) { 'my.domain.com' }
it { is_expected.to validate_uniqueness_of(:domain) }
it { is_expected.to validate_uniqueness_of(:domain).case_insensitive }
end
{
......
......@@ -15,7 +15,6 @@ describe JiraService, models: true do
end
it { is_expected.to validate_presence_of(:url) }
it { is_expected.to validate_presence_of(:project_key) }
it_behaves_like 'issue tracker service URL attribute', :url
end
......@@ -34,7 +33,6 @@ describe JiraService, models: true do
active: true,
username: 'username',
password: 'test',
project_key: 'TEST',
jira_issue_transition_id: 24,
url: 'http://jira.test.com'
)
......@@ -88,7 +86,6 @@ describe JiraService, models: true do
url: 'http://jira.example.com',
username: 'gitlab_jira_username',
password: 'gitlab_jira_password',
project_key: 'GitLabProject',
jira_issue_transition_id: "custom-id"
)
......@@ -196,15 +193,14 @@ describe JiraService, models: true do
project: create(:project),
url: 'http://jira.example.com',
username: 'jira_username',
password: 'jira_password',
project_key: 'GitLabProject'
password: 'jira_password'
)
end
def test_settings(api_url)
project_url = "http://#{api_url}/rest/api/2/project/GitLabProject"
test_url = "http://#{api_url}/rest/api/2/serverInfo"
WebMock.stub_request(:get, project_url).with(basic_auth: %w(jira_username jira_password))
WebMock.stub_request(:get, test_url).with(basic_auth: %w(jira_username jira_password)).to_return(body: { url: 'http://url' }.to_json )
jira_service.test_settings
end
......
......@@ -11,7 +11,7 @@ describe RedirectRoute, models: true do
describe 'validations' do
it { is_expected.to validate_presence_of(:source) }
it { is_expected.to validate_presence_of(:path) }
it { is_expected.to validate_uniqueness_of(:path) }
it { is_expected.to validate_uniqueness_of(:path).case_insensitive }
end
describe '.matching_path_and_descendants' do
......
......@@ -956,21 +956,25 @@ describe Repository, models: true do
end
end
describe '#exists?' do
shared_examples 'repo exists check' do
it 'returns true when a repository exists' do
expect(repository.exists?).to eq(true)
end
it 'returns false when a repository does not exist' do
allow(repository).to receive(:refs_directory_exists?).and_return(false)
it 'returns false if no full path can be constructed' do
allow(repository).to receive(:path_with_namespace).and_return(nil)
expect(repository.exists?).to eq(false)
end
end
it 'returns false when there is no namespace' do
allow(repository).to receive(:path_with_namespace).and_return(nil)
describe '#exists?' do
context 'when repository_exists is disabled' do
it_behaves_like 'repo exists check'
end
expect(repository.exists?).to eq(false)
context 'when repository_exists is enabled', skip_gitaly_mock: true do
it_behaves_like 'repo exists check'
end
end
......
......@@ -15,7 +15,7 @@ describe Route, models: true do
it { is_expected.to validate_presence_of(:source) }
it { is_expected.to validate_presence_of(:path) }
it { is_expected.to validate_uniqueness_of(:path) }
it { is_expected.to validate_uniqueness_of(:path).case_insensitive }
end
describe 'callbacks' do
......
......@@ -123,7 +123,9 @@ describe User, models: true do
end
it 'validates uniqueness' do
expect(subject).to validate_uniqueness_of(:username).case_insensitive
user = build(:user)
expect(user).to validate_uniqueness_of(:username).case_insensitive
end
end
......
......@@ -96,17 +96,18 @@ describe Ci::BuildPolicy, :models do
end
end
describe 'rules for manual actions' do
describe 'rules for protected ref' do
let(:project) { create(:project) }
let(:build) { create(:ci_build, ref: 'some-ref', pipeline: pipeline) }
before do
project.add_developer(user)
end
shared_examples 'protected ref' do
context 'when build is a manual action' do
let(:build) do
create(:ci_build, :manual, ref: 'some-ref', pipeline: pipeline)
context 'when no one can push or merge to the branch' do
before do
create(:protected_branch, :no_one_can_push,
name: build.ref, project: project)
end
it 'does not include ability to update build' do
......@@ -114,46 +115,34 @@ describe Ci::BuildPolicy, :models do
end
end
context 'when build is not a manual action' do
let(:build) do
create(:ci_build, ref: 'some-ref', pipeline: pipeline)
context 'when developers can push to the branch' do
before do
create(:protected_branch, :developers_can_merge,
name: build.ref, project: project)
end
it 'includes ability to update build' do
expect(policy).to be_allowed :update_build
end
end
end
context 'when build is against a protected branch' do
before do
create(:protected_branch, :no_one_can_push,
name: 'some-ref', project: project)
end
it_behaves_like 'protected ref'
end
context 'when build is against a protected tag' do
context 'when no one can create the tag' do
before do
create(:protected_tag, :no_one_can_create,
name: 'some-ref', project: project)
name: build.ref, project: project)
build.update(tag: true)
end
it_behaves_like 'protected ref'
it 'does not include ability to update build' do
expect(policy).to be_disallowed :update_build
end
end
context 'when build is against a protected tag but it is not a tag' do
context 'when no one can create the tag but it is not a tag' do
before do
create(:protected_tag, :no_one_can_create,
name: 'some-ref', project: project)
end
context 'when build is a manual action' do
let(:build) do
create(:ci_build, :manual, ref: 'some-ref', pipeline: pipeline)
name: build.ref, project: project)
end
it 'includes ability to update build' do
......@@ -161,24 +150,5 @@ describe Ci::BuildPolicy, :models do
end
end
end
context 'when branch build is assigned to is not protected' do
context 'when build is a manual action' do
let(:build) { create(:ci_build, :manual, pipeline: pipeline) }
it 'includes ability to update build' do
expect(policy).to be_allowed :update_build
end
end
context 'when build is not a manual action' do
let(:build) { create(:ci_build, pipeline: pipeline) }
it 'includes ability to update build' do
expect(policy).to be_allowed :update_build
end
end
end
end
end
end
require 'spec_helper'
describe Ci::PipelinePolicy, :models do
let(:user) { create(:user) }
let(:pipeline) { create(:ci_empty_pipeline, project: project) }
let(:policy) do
described_class.new(user, pipeline)
end
describe 'rules' do
describe 'rules for protected ref' do
let(:project) { create(:project) }
before do
project.add_developer(user)
end
context 'when no one can push or merge to the branch' do
before do
create(:protected_branch, :no_one_can_push,
name: pipeline.ref, project: project)
end
it 'does not include ability to update pipeline' do
expect(policy).to be_disallowed :update_pipeline
end
end
context 'when developers can push to the branch' do
before do
create(:protected_branch, :developers_can_merge,
name: pipeline.ref, project: project)
end
it 'includes ability to update pipeline' do
expect(policy).to be_allowed :update_pipeline
end
end
context 'when no one can create the tag' do
before do
create(:protected_tag, :no_one_can_create,
name: pipeline.ref, project: project)
pipeline.update(tag: true)
end
it 'does not include ability to update pipeline' do
expect(policy).to be_disallowed :update_pipeline
end
end
context 'when no one can create the tag but it is not a tag' do
before do
create(:protected_tag, :no_one_can_create,
name: pipeline.ref, project: project)
end
it 'includes ability to update pipeline' do
expect(policy).to be_allowed :update_pipeline
end
end
end
end
end
......@@ -30,5 +30,25 @@ describe GlobalPolicy, models: true do
it { is_expected.to be_allowed(:read_users_list) }
end
end
context "for an admin" do
let(:current_user) { create(:admin) }
context "when the public level is restricted" do
before do
stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::PUBLIC])
end
it { is_expected.to be_allowed(:read_users_list) }
end
context "when the public level is not restricted" do
before do
stub_application_setting(restricted_visibility_levels: [])
end
it { is_expected.to be_allowed(:read_users_list) }
end
end
end
end
This diff is collapsed.
......@@ -55,7 +55,12 @@ describe API::Triggers do
post api("/projects/#{project.id}/trigger/pipeline"), options.merge(ref: 'other-branch')
expect(response).to have_http_status(400)
<<<<<<< HEAD
expect(json_response['message']).to eq('base' => ["Reference not found"])
=======
expect(json_response['message']['base'])
.to contain_exactly('Reference not found')
>>>>>>> upstream/master
end
context 'Validates variables' do
......
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