Commit 103c7d1c authored by GitLab Bot's avatar GitLab Bot

Merge remote-tracking branch 'upstream/master' into ce-to-ee-2018-06-19

# Conflicts:
#	app/models/project.rb

[ci skip]
parents 5151cb82 9092e96a
...@@ -27,25 +27,26 @@ _This notice should stay as the first item in the CONTRIBUTING.md file._ ...@@ -27,25 +27,26 @@ _This notice should stay as the first item in the CONTRIBUTING.md file._
- [Helping others](#helping-others) - [Helping others](#helping-others)
- [I want to contribute!](#i-want-to-contribute) - [I want to contribute!](#i-want-to-contribute)
- [Workflow labels](#workflow-labels) - [Workflow labels](#workflow-labels)
- [Type labels (~"feature proposal", ~bug, ~customer, etc.)](#type-labels-feature-proposal-bug-customer-etc) - [Type labels](#type-labels)
- [Subject labels (~wiki, ~"container registry", ~ldap, ~api, etc.)](#subject-labels-wiki-container-registry-ldap-api-etc) - [Subject labels](#subject-labels)
- [Team labels (~"CI/CD", ~Discussion, ~Quality, ~Platform, etc.)](#team-labels-cicd-discussion-quality-platform-etc) - [Team labels](#team-labels)
- [Milestone labels (~Deliverable, ~Stretch, ~"Next Patch Release")](#milestone-labels-deliverable-stretch-next-patch-release) - [Milestone labels](#milestone-labels)
- [Priority labels (~P1, ~P2, ~P3 , ~P4)](#bug-priority-labels-p1-p2-p3-p4) - [Bug Priority labels](#bug-priority-labels)
- [Severity labels (~S1, ~S2, ~S3 , ~S4)](#bug-severity-labels-s1-s2-s3-s4) - [Bug Severity labels](#bug-severity-labels)
- [Label for community contributors (~"Accepting Merge Requests")](#label-for-community-contributors-accepting-merge-requests) - [Severity impact guidance](#severity-impact-guidance)
- [Implement design & UI elements](#implement-design--ui-elements) - [Label for community contributors](#label-for-community-contributors)
- [Implement design & UI elements](#implement-design-ui-elements)
- [Issue tracker](#issue-tracker) - [Issue tracker](#issue-tracker)
- [Issue triaging](#issue-triaging) - [Issue triaging](#issue-triaging)
- [Feature proposals](#feature-proposals) - [Feature proposals](#feature-proposals)
- [Issue tracker guidelines](#issue-tracker-guidelines) - [Issue tracker guidelines](#issue-tracker-guidelines)
- [Issue weight](#issue-weight) - [Issue weight](#issue-weight)
- [Regression issues](#regression-issues) - [Regression issues](#regression-issues)
- [Technical and UX debt](#technical-and-ux-debt) - [Technical and UX debt](#technical-and-ux-debt)
- [Stewardship](#stewardship) - [Stewardship](#stewardship)
- [Merge requests](#merge-requests) - [Merge requests](#merge-requests)
- [Merge request guidelines](#merge-request-guidelines) - [Merge request guidelines](#merge-request-guidelines)
- [Contribution acceptance criteria](#contribution-acceptance-criteria) - [Contribution acceptance criteria](#contribution-acceptance-criteria)
- [Definition of done](#definition-of-done) - [Definition of done](#definition-of-done)
- [Style guides](#style-guides) - [Style guides](#style-guides)
- [Code of conduct](#code-of-conduct) - [Code of conduct](#code-of-conduct)
...@@ -146,7 +147,7 @@ labels, you can _always_ add the team and type, and often also the subject. ...@@ -146,7 +147,7 @@ labels, you can _always_ add the team and type, and often also the subject.
[milestones-page]: https://gitlab.com/gitlab-org/gitlab-ce/milestones [milestones-page]: https://gitlab.com/gitlab-org/gitlab-ce/milestones
[labels-page]: https://gitlab.com/gitlab-org/gitlab-ce/labels [labels-page]: https://gitlab.com/gitlab-org/gitlab-ce/labels
### Type labels (~"feature proposal", ~bug, ~customer, etc.) ### Type labels
Type labels are very important. They define what kind of issue this is. Every Type labels are very important. They define what kind of issue this is. Every
issue should have one or more. issue should have one or more.
...@@ -162,28 +163,41 @@ already reserved for subject labels). ...@@ -162,28 +163,41 @@ already reserved for subject labels).
The descriptions on the [labels page][labels-page] explain what falls under each type label. The descriptions on the [labels page][labels-page] explain what falls under each type label.
### Subject labels (~wiki, ~"container registry", ~ldap, ~api, etc.) ### Subject labels
Subject labels are labels that define what area or feature of GitLab this issue Subject labels are labels that define what area or feature of GitLab this issue
hits. They are not always necessary, but very convenient. hits. They are not always necessary, but very convenient.
Examples of subject labels are ~wiki, ~ldap, ~api,
~issues, ~"merge requests", ~labels, and ~"container registry".
If you are an expert in a particular area, it makes it easier to find issues to If you are an expert in a particular area, it makes it easier to find issues to
work on. You can also subscribe to those labels to receive an email each time an work on. You can also subscribe to those labels to receive an email each time an
issue is labeled with a subject label corresponding to your expertise. issue is labeled with a subject label corresponding to your expertise.
Examples of subject labels are ~wiki, ~"container registry", ~ldap, ~api,
~issues, ~"merge requests", ~labels, and ~"container registry".
Subject labels are always all-lowercase. Subject labels are always all-lowercase.
### Team labels (~"CI/CD", ~Discussion, ~Quality, ~Platform, etc.) ### Team labels
Team labels specify what team is responsible for this issue. Team labels specify what team is responsible for this issue.
Assigning a team label makes sure issues get the attention of the appropriate Assigning a team label makes sure issues get the attention of the appropriate
people. people.
The current team labels are ~Distribution, ~"CI/CD", ~Discussion, ~Documentation, ~Quality, The current team labels are:
~Geo, ~Gitaly, ~Monitoring, ~Platform, ~Release, ~"Security Products", ~"Configuration", and ~"UX".
- ~Configuration
- ~"CI/CD"
- ~Discussion
- ~Distribution
- ~Documentation
- ~Geo
- ~Gitaly
- ~Monitoring
- ~Platform
- ~Quality
- ~Release
- ~"Security Products"
- ~UX
The descriptions on the [labels page][labels-page] explain what falls under the The descriptions on the [labels page][labels-page] explain what falls under the
responsibility of each team. responsibility of each team.
...@@ -194,7 +208,7 @@ indicate if an issue needs backend work, frontend work, or both. ...@@ -194,7 +208,7 @@ indicate if an issue needs backend work, frontend work, or both.
Team labels are always capitalized so that they show up as the first label for Team labels are always capitalized so that they show up as the first label for
any issue. any issue.
### Milestone labels (~Deliverable, ~Stretch, ~"Next Patch Release") ### Milestone labels
Milestone labels help us clearly communicate expectations of the work for the Milestone labels help us clearly communicate expectations of the work for the
release. There are three levels of Milestone labels: release. There are three levels of Milestone labels:
...@@ -212,9 +226,9 @@ Each issue scheduled for the current milestone should be labeled ~Deliverable ...@@ -212,9 +226,9 @@ Each issue scheduled for the current milestone should be labeled ~Deliverable
or ~"Stretch". Any open issue for a previous milestone should be labeled or ~"Stretch". Any open issue for a previous milestone should be labeled
~"Next Patch Release", or otherwise rescheduled to a different milestone. ~"Next Patch Release", or otherwise rescheduled to a different milestone.
### Bug Priority labels (~P1, ~P2, ~P3, ~P4) ### Bug Priority labels
Bug Priority labels help us define the time a ~bug fix should be completed. Priority determines how quickly the defect turnaround time must be. Bug Priority labels help us define the time a ~bug fix should be completed. Priority determines how quickly the defect turnaround time must be.
If there are multiple defects, the priority decides which defect has to be fixed immediately versus later. If there are multiple defects, the priority decides which defect has to be fixed immediately versus later.
This label documents the planned timeline & urgency which is used to measure against our actual SLA on delivering ~bug fixes. This label documents the planned timeline & urgency which is used to measure against our actual SLA on delivering ~bug fixes.
...@@ -225,7 +239,7 @@ This label documents the planned timeline & urgency which is used to measure aga ...@@ -225,7 +239,7 @@ This label documents the planned timeline & urgency which is used to measure aga
| ~P3 | Medium Priority | Within the next 3 releases (approx one quarter) | | | ~P3 | Medium Priority | Within the next 3 releases (approx one quarter) | |
| ~P4 | Low Priority | Anything outside the next 3 releases (approx beyond one quarter) | The issue is prominent but does not impact user workflow and a workaround is documented | | ~P4 | Low Priority | Anything outside the next 3 releases (approx beyond one quarter) | The issue is prominent but does not impact user workflow and a workaround is documented |
### Bug Severity labels (~S1, ~S2, ~S3, ~S4) ### Bug Severity labels
Severity labels help us clearly communicate the impact of a ~bug on users. Severity labels help us clearly communicate the impact of a ~bug on users.
...@@ -241,11 +255,11 @@ Severity labels help us clearly communicate the impact of a ~bug on users. ...@@ -241,11 +255,11 @@ Severity labels help us clearly communicate the impact of a ~bug on users.
| Label | Security Impact | Availability / Performance Impact | | Label | Security Impact | Availability / Performance Impact |
|-------|---------------------------------------------------------------------|--------------------------------------------------------------| |-------|---------------------------------------------------------------------|--------------------------------------------------------------|
| ~S1 | >50% users impacted (possible company extinction level event) | | | ~S1 | >50% users impacted (possible company extinction level event) | |
| ~S2 | Many users or multiple paid customers impacted (but not apocalyptic)| The issue is (almost) guaranteed to occur in the near future | | ~S2 | Many users or multiple paid customers impacted (but not apocalyptic)| The issue is (almost) guaranteed to occur in the near future |
| ~S3 | A few users or a single paid customer impacted | The issue is likely to occur in the near future | | ~S3 | A few users or a single paid customer impacted | The issue is likely to occur in the near future |
| ~S4 | No paid users/customer impacted, or expected impact within 30 days | The issue _may_ occur but it's not likely | | ~S4 | No paid users/customer impacted, or expected impact within 30 days | The issue _may_ occur but it's not likely |
### Label for community contributors (~"Accepting Merge Requests") ### Label for community contributors
Issues that are beneficial to our users, 'nice to haves', that we currently do Issues that are beneficial to our users, 'nice to haves', that we currently do
not have the capacity for or want to give the priority to, are labeled as not have the capacity for or want to give the priority to, are labeled as
...@@ -301,14 +315,14 @@ For guidance on UX implementation at GitLab, please refer to our [Design System] ...@@ -301,14 +315,14 @@ For guidance on UX implementation at GitLab, please refer to our [Design System]
The UX team uses labels to manage their workflow. The UX team uses labels to manage their workflow.
The ~"UX" label on an issue is a signal to the UX team that it will need UX attention. The ~"UX" label on an issue is a signal to the UX team that it will need UX attention.
To better understand the priority by which UX tackles issues, see the [UX section](https://about.gitlab.com/handbook/engineering/ux) of the handbook. To better understand the priority by which UX tackles issues, see the [UX section](https://about.gitlab.com/handbook/engineering/ux) of the handbook.
Once an issue has been worked on and is ready for development, a UXer removes the ~"UX" label and applies the ~"UX ready" label to that issue. Once an issue has been worked on and is ready for development, a UXer removes the ~"UX" label and applies the ~"UX ready" label to that issue.
The UX team has a special type label called ~"design artifact". This label indicates that the final output The UX team has a special type label called ~"design artifact". This label indicates that the final output
for an issue is a UX solution/design. The solution will be developed by frontend and/or backend in a subsequent milestone. for an issue is a UX solution/design. The solution will be developed by frontend and/or backend in a subsequent milestone.
Any issue labeled ~"design artifact" should not also be labeled ~"frontend" or ~"backend" since no development is Any issue labeled ~"design artifact" should not also be labeled ~"frontend" or ~"backend" since no development is
needed until the solution has been decided. needed until the solution has been decided.
~"design artifact" issues are like any other issue and should contain a milestone label, ~"Deliverable" or ~"Stretch", when scheduled in the current milestone. ~"design artifact" issues are like any other issue and should contain a milestone label, ~"Deliverable" or ~"Stretch", when scheduled in the current milestone.
......
...@@ -173,7 +173,7 @@ ...@@ -173,7 +173,7 @@
</a> </a>
<clipboard-button <clipboard-button
:title="__('Copy commit SHA to clipboard')" :title="__('Copy commit SHA to clipboard')"
:text="mr.shortMergeCommitSha" :text="mr.mergeCommitSha"
css-class="btn-default btn-transparent btn-clipboard js-mr-merged-copy-sha" css-class="btn-default btn-transparent btn-clipboard js-mr-merged-copy-sha"
/> />
</p> </p>
......
...@@ -26,6 +26,7 @@ export default class MergeRequestStore { ...@@ -26,6 +26,7 @@ export default class MergeRequestStore {
this.mergeStatus = data.merge_status; this.mergeStatus = data.merge_status;
this.commitMessage = data.merge_commit_message; this.commitMessage = data.merge_commit_message;
this.shortMergeCommitSha = data.short_merge_commit_sha; this.shortMergeCommitSha = data.short_merge_commit_sha;
this.mergeCommitSha = data.merge_commit_sha;
this.commitMessageWithDescription = data.merge_commit_message_with_description; this.commitMessageWithDescription = data.merge_commit_message_with_description;
this.commitsCount = data.commits_count; this.commitsCount = data.commits_count;
this.divergedCommitsCount = data.diverged_commits_count; this.divergedCommitsCount = data.diverged_commits_count;
......
...@@ -173,7 +173,10 @@ table { ...@@ -173,7 +173,10 @@ table {
display: none; display: none;
} }
.badge { // Add to .label so that old system notes that are saved to the db
// will still receive the correct styling
.badge,
.label {
padding: 4px 5px; padding: 4px 5px;
font-size: 12px; font-size: 12px;
font-style: normal; font-style: normal;
......
...@@ -23,7 +23,8 @@ ...@@ -23,7 +23,8 @@
position: relative; position: relative;
line-height: 35px; line-height: 35px;
display: flex; display: flex;
flex-grow: 1; flex: 1 1;
min-width: 0;
@include media-breakpoint-up(sm) { @include media-breakpoint-up(sm) {
padding-left: 0; padding-left: 0;
......
...@@ -710,6 +710,8 @@ ...@@ -710,6 +710,8 @@
font-size: 14px; font-size: 14px;
line-height: 24px; line-height: 24px;
align-self: center; align-self: center;
overflow: hidden;
text-overflow: ellipsis;
} }
.js-issuable-selector-wrap { .js-issuable-selector-wrap {
......
...@@ -127,13 +127,6 @@ ...@@ -127,13 +127,6 @@
color: $gl-danger; color: $gl-danger;
} }
.service-settings {
input[type="radio"],
input[type="checkbox"] {
margin-top: 10px;
}
}
.integration-settings-form { .integration-settings-form {
.card.card-body, .card.card-body,
.info-well { .info-well {
......
module UploadsActions module UploadsActions
extend ActiveSupport::Concern
include Gitlab::Utils::StrongMemoize include Gitlab::Utils::StrongMemoize
include SendFileUpload include SendFileUpload
UPLOAD_MOUNTS = %w(avatar attachment file logo header_logo favicon).freeze UPLOAD_MOUNTS = %w(avatar attachment file logo header_logo favicon).freeze
included do
prepend_before_action :set_html_format, only: :show
end
def create def create
link_to_file = UploadService.new(model, params[:file], uploader_class).execute link_to_file = UploadService.new(model, params[:file], uploader_class).execute
...@@ -41,6 +47,13 @@ module UploadsActions ...@@ -41,6 +47,13 @@ module UploadsActions
private private
# Explicitly set the format.
# Otherwise rails 5 will set it from a file extension.
# See https://github.com/rails/rails/commit/84e8accd6fb83031e4c27e44925d7596655285f7#diff-2b8f2fbb113b55ca8e16001c393da8f1
def set_html_format
request.format = :html
end
def uploader_class def uploader_class
raise NotImplementedError raise NotImplementedError
end end
......
...@@ -31,7 +31,10 @@ class Projects::BranchesController < Projects::ApplicationController ...@@ -31,7 +31,10 @@ class Projects::BranchesController < Projects::ApplicationController
end end
end end
render # https://gitlab.com/gitlab-org/gitlab-ce/issues/48097
Gitlab::GitalyClient.allow_n_plus_1_calls do
render
end
end end
format.json do format.json do
branches = BranchesFinder.new(@repository, params).execute branches = BranchesFinder.new(@repository, params).execute
......
...@@ -159,7 +159,7 @@ module IssuablesHelper ...@@ -159,7 +159,7 @@ module IssuablesHelper
output = "" output = ""
output << "Opened #{time_ago_with_tooltip(issuable.created_at)} by ".html_safe output << "Opened #{time_ago_with_tooltip(issuable.created_at)} by ".html_safe
output << content_tag(:strong) do output << content_tag(:strong) do
author_output = link_to_member(project, issuable.author, size: 24, mobile_classes: "d-none d-sm-inline-block", tooltip: true) author_output = link_to_member(project, issuable.author, size: 24, mobile_classes: "d-none d-sm-inline", tooltip: true)
author_output << link_to_member(project, issuable.author, size: 24, by_username: true, avatar: false, mobile_classes: "d-block d-sm-none") author_output << link_to_member(project, issuable.author, size: 24, by_username: true, avatar: false, mobile_classes: "d-block d-sm-none")
end end
......
...@@ -26,9 +26,12 @@ class Project < ActiveRecord::Base ...@@ -26,9 +26,12 @@ class Project < ActiveRecord::Base
include WithUploads include WithUploads
include BatchDestroyDependentAssociations include BatchDestroyDependentAssociations
extend Gitlab::Cache::RequestCache extend Gitlab::Cache::RequestCache
<<<<<<< HEAD
# EE specific modules # EE specific modules
prepend EE::Project prepend EE::Project
=======
>>>>>>> upstream/master
extend Gitlab::ConfigHelper extend Gitlab::ConfigHelper
......
...@@ -155,6 +155,7 @@ class ChatNotificationService < Service ...@@ -155,6 +155,7 @@ class ChatNotificationService < Service
end end
def notify_for_ref?(data) def notify_for_ref?(data)
return true if data[:object_kind] == 'tag_push'
return true if data.dig(:object_attributes, :tag) return true if data.dig(:object_attributes, :tag)
return true unless notify_only_default_branch? return true unless notify_only_default_branch?
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
%colgroup %colgroup
%col %col
%col %col
%col.d-none.d-sm-block %col
%col{ width: "120" } %col{ width: "120" }
%thead %thead
%tr %tr
......
...@@ -8,28 +8,12 @@ class RepositoryForkWorker ...@@ -8,28 +8,12 @@ class RepositoryForkWorker
target_project_id = args.shift target_project_id = args.shift
target_project = Project.find(target_project_id) target_project = Project.find(target_project_id)
# By v10.8, we should've drained the queue of all jobs using the old arguments. source_project = target_project.forked_from_project
# We can remove the else clause if we're no longer logging the message in that clause. unless source_project
# See https://gitlab.com/gitlab-org/gitaly/issues/1110 return target_project.mark_import_as_failed('Source project cannot be found.')
if args.empty?
source_project = target_project.forked_from_project
unless source_project
return target_project.mark_import_as_failed('Source project cannot be found.')
end
fork_repository(target_project, source_project.repository_storage, source_project.disk_path)
else
Rails.logger.info("Project #{target_project.id} is being forked using old-style arguments.")
source_repository_storage_path, source_disk_path = *args
source_repository_storage_name = Gitlab::GitalyClient::StorageSettings.allow_disk_access do
Gitlab.config.repositories.storages.find do |_, info|
info.legacy_disk_path == source_repository_storage_path
end&.first || raise("no shard found for path '#{source_repository_storage_path}'")
end
fork_repository(target_project, source_repository_storage_name, source_disk_path)
end end
fork_repository(target_project, source_project.repository_storage, source_project.disk_path)
end end
private private
......
---
title: Fix chat service tag notifications not sending when only default branch enabled
merge_request: 19864
author:
type: fixed
---
title: Fix CSS for buttons not to be hidden on issues/MR title
merge_request: 19176
author: Takuya Noguchi
type: fixed
---
title: Uses long sha version of the merged commit in MR widget copy to clipboard button
merge_request: 19955
author:
type: other
title: Fixed pagination of groups API
merge_request: 19665
author: Marko, Peter
type: added
---
title: Added id sorting option to GET groups and subgroups API
merge_request: 19665
author: Marko, Peter
type: added
---
title: Rails5 fix format in uploads actions
merge_request: 19907
author: Jasper Maes
type: fixed
---
title: Eliminate N+1 queries in LFS file locks checks during a push
merge_request:
author:
type: performance
...@@ -107,7 +107,7 @@ Global Admins GitLab.org/GitLab INT/Global Groups/Global Admins ...@@ -107,7 +107,7 @@ Global Admins GitLab.org/GitLab INT/Global Groups/Global Admins
## GitLab LDAP configuration ## GitLab LDAP configuration
The initial configuration of LDAP in GitLab requires changes to the `gitlab.rb` configuration file. Below is an example of a complete configuration using an Active Directory. The initial configuration of LDAP in GitLab requires changes to the `gitlab.rb` configuration file (`/etc/gitlab/gitlab.rb`). Below is an example of a complete configuration using an Active Directory.
The two Active Directory specific values are `active_directory: true` and `uid: 'sAMAccountName'`. `sAMAccountName` is an attribute returned by Active Directory used for GitLab usernames. See the example output from `ldapsearch` for a full list of attributes a "person" object (user) has in **AD** - [`ldapsearch` example](#using-ldapsearch-unix) The two Active Directory specific values are `active_directory: true` and `uid: 'sAMAccountName'`. `sAMAccountName` is an attribute returned by Active Directory used for GitLab usernames. See the example output from `ldapsearch` for a full list of attributes a "person" object (user) has in **AD** - [`ldapsearch` example](#using-ldapsearch-unix)
......
...@@ -12,7 +12,7 @@ Parameters: ...@@ -12,7 +12,7 @@ Parameters:
| `skip_groups` | array of integers | no | Skip the group IDs passed | | `skip_groups` | array of integers | no | Skip the group IDs passed |
| `all_available` | boolean | no | Show all the groups you have access to (defaults to `false` for authenticated users, `true` for admin) | | `all_available` | boolean | no | Show all the groups you have access to (defaults to `false` for authenticated users, `true` for admin) |
| `search` | string | no | Return the list of authorized groups matching the search criteria | | `search` | string | no | Return the list of authorized groups matching the search criteria |
| `order_by` | string | no | Order groups by `name` or `path`. Default is `name` | | `order_by` | string | no | Order groups by `name`, `path` or `id`. Default is `name` |
| `sort` | string | no | Order groups in `asc` or `desc` order. Default is `asc` | | `sort` | string | no | Order groups in `asc` or `desc` order. Default is `asc` |
| `statistics` | boolean | no | Include group statistics (admins only) | | `statistics` | boolean | no | Include group statistics (admins only) |
| `with_custom_attributes` | boolean | no | Include [custom attributes](custom_attributes.md) in response (admins only) | | `with_custom_attributes` | boolean | no | Include [custom attributes](custom_attributes.md) in response (admins only) |
...@@ -96,7 +96,7 @@ Parameters: ...@@ -96,7 +96,7 @@ Parameters:
| `skip_groups` | array of integers | no | Skip the group IDs passed | | `skip_groups` | array of integers | no | Skip the group IDs passed |
| `all_available` | boolean | no | Show all the groups you have access to (defaults to `false` for authenticated users, `true` for admin) | | `all_available` | boolean | no | Show all the groups you have access to (defaults to `false` for authenticated users, `true` for admin) |
| `search` | string | no | Return the list of authorized groups matching the search criteria | | `search` | string | no | Return the list of authorized groups matching the search criteria |
| `order_by` | string | no | Order groups by `name` or `path`. Default is `name` | | `order_by` | string | no | Order groups by `name`, `path` or `id`. Default is `name` |
| `sort` | string | no | Order groups in `asc` or `desc` order. Default is `asc` | | `sort` | string | no | Order groups in `asc` or `desc` order. Default is `asc` |
| `statistics` | boolean | no | Include group statistics (admins only) | | `statistics` | boolean | no | Include group statistics (admins only) |
| `with_custom_attributes` | boolean | no | Include [custom attributes](custom_attributes.md) in response (admins only) | | `with_custom_attributes` | boolean | no | Include [custom attributes](custom_attributes.md) in response (admins only) |
......
...@@ -88,18 +88,18 @@ The example below simply moves all files from the root of the project to the ...@@ -88,18 +88,18 @@ The example below simply moves all files from the root of the project to the
`public/` directory. The `.public` workaround is so `cp` doesn't also copy `public/` directory. The `.public` workaround is so `cp` doesn't also copy
`public/` to itself in an infinite loop: `public/` to itself in an infinite loop:
``` ```yaml
pages: pages:
stage: deploy stage: deploy
script: script:
- mkdir .public - mkdir .public
- cp -r * .public - cp -r * .public
- mv .public public - mv .public public
artifacts: artifacts:
paths: paths:
- public - public
only: only:
- master - master
``` ```
Read more on [GitLab Pages user documentation](../../user/project/pages/index.md). Read more on [GitLab Pages user documentation](../../user/project/pages/index.md).
...@@ -131,15 +131,15 @@ if you set it per-job: ...@@ -131,15 +131,15 @@ if you set it per-job:
```yaml ```yaml
before_script: before_script:
- global before script - global before script
job: job:
before_script: before_script:
- execute this instead of global before script - execute this instead of global before script
script: script:
- my command - my command
after_script: after_script:
- execute this after my script - execute this after my script
``` ```
## `stages` ## `stages`
...@@ -409,18 +409,18 @@ fails, it will not stop the next stage from running, since it's marked with ...@@ -409,18 +409,18 @@ fails, it will not stop the next stage from running, since it's marked with
job1: job1:
stage: test stage: test
script: script:
- execute_script_that_will_fail - execute_script_that_will_fail
allow_failure: true allow_failure: true
job2: job2:
stage: test stage: test
script: script:
- execute_script_that_will_succeed - execute_script_that_will_succeed
job3: job3:
stage: deploy stage: deploy
script: script:
- deploy_to_staging - deploy_to_staging
``` ```
## `when` ## `when`
...@@ -442,38 +442,38 @@ For example: ...@@ -442,38 +442,38 @@ For example:
```yaml ```yaml
stages: stages:
- build - build
- cleanup_build - cleanup_build
- test - test
- deploy - deploy
- cleanup - cleanup
build_job: build_job:
stage: build stage: build
script: script:
- make build - make build
cleanup_build_job: cleanup_build_job:
stage: cleanup_build stage: cleanup_build
script: script:
- cleanup build when failed - cleanup build when failed
when: on_failure when: on_failure
test_job: test_job:
stage: test stage: test
script: script:
- make test - make test
deploy_job: deploy_job:
stage: deploy stage: deploy
script: script:
- make deploy - make deploy
when: manual when: manual
cleanup_job: cleanup_job:
stage: cleanup stage: cleanup
script: script:
- cleanup after jobs - cleanup after jobs
when: always when: always
``` ```
...@@ -734,8 +734,8 @@ rspec: ...@@ -734,8 +734,8 @@ rspec:
script: test script: test
cache: cache:
paths: paths:
- binaries/*.apk - binaries/*.apk
- .config - .config
``` ```
Locally defined cache overrides globally defined options. The following `rspec` Locally defined cache overrides globally defined options. The following `rspec`
...@@ -744,14 +744,14 @@ job will cache only `binaries/`: ...@@ -744,14 +744,14 @@ job will cache only `binaries/`:
```yaml ```yaml
cache: cache:
paths: paths:
- my/files - my/files
rspec: rspec:
script: test script: test
cache: cache:
key: rspec key: rspec
paths: paths:
- binaries/ - binaries/
``` ```
Note that since cache is shared between jobs, if you're using different Note that since cache is shared between jobs, if you're using different
...@@ -786,7 +786,7 @@ For example, to enable per-branch caching: ...@@ -786,7 +786,7 @@ For example, to enable per-branch caching:
cache: cache:
key: "$CI_COMMIT_REF_SLUG" key: "$CI_COMMIT_REF_SLUG"
paths: paths:
- binaries/ - binaries/
``` ```
If you use **Windows Batch** to run your shell scripts you need to replace If you use **Windows Batch** to run your shell scripts you need to replace
...@@ -796,7 +796,7 @@ If you use **Windows Batch** to run your shell scripts you need to replace ...@@ -796,7 +796,7 @@ If you use **Windows Batch** to run your shell scripts you need to replace
cache: cache:
key: "%CI_COMMIT_REF_SLUG%" key: "%CI_COMMIT_REF_SLUG%"
paths: paths:
- binaries/ - binaries/
``` ```
### `cache:untracked` ### `cache:untracked`
...@@ -819,7 +819,7 @@ rspec: ...@@ -819,7 +819,7 @@ rspec:
cache: cache:
untracked: true untracked: true
paths: paths:
- binaries/ - binaries/
``` ```
### `cache:policy` ### `cache:policy`
...@@ -897,8 +897,8 @@ Send all files in `binaries` and `.config`: ...@@ -897,8 +897,8 @@ Send all files in `binaries` and `.config`:
```yaml ```yaml
artifacts: artifacts:
paths: paths:
- binaries/ - binaries/
- .config - .config
``` ```
To disable artifact passing, define the job with empty [dependencies](#dependencies): To disable artifact passing, define the job with empty [dependencies](#dependencies):
...@@ -927,7 +927,7 @@ release-job: ...@@ -927,7 +927,7 @@ release-job:
- mvn package -U - mvn package -U
artifacts: artifacts:
paths: paths:
- target/*.war - target/*.war
only: only:
- tags - tags
``` ```
...@@ -949,7 +949,7 @@ job: ...@@ -949,7 +949,7 @@ job:
artifacts: artifacts:
name: "$CI_JOB_NAME" name: "$CI_JOB_NAME"
paths: paths:
- binaries/ - binaries/
``` ```
To create an archive with a name of the current branch or tag including only To create an archive with a name of the current branch or tag including only
...@@ -960,7 +960,7 @@ job: ...@@ -960,7 +960,7 @@ job:
artifacts: artifacts:
name: "$CI_COMMIT_REF_NAME" name: "$CI_COMMIT_REF_NAME"
paths: paths:
- binaries/ - binaries/
``` ```
To create an archive with a name of the current job and the current branch or To create an archive with a name of the current job and the current branch or
...@@ -971,7 +971,7 @@ job: ...@@ -971,7 +971,7 @@ job:
artifacts: artifacts:
name: "$CI_JOB_NAME-$CI_COMMIT_REF_NAME" name: "$CI_JOB_NAME-$CI_COMMIT_REF_NAME"
paths: paths:
- binaries/ - binaries/
``` ```
To create an archive with a name of the current [stage](#stages) and branch name: To create an archive with a name of the current [stage](#stages) and branch name:
...@@ -981,7 +981,7 @@ job: ...@@ -981,7 +981,7 @@ job:
artifacts: artifacts:
name: "$CI_JOB_STAGE-$CI_COMMIT_REF_NAME" name: "$CI_JOB_STAGE-$CI_COMMIT_REF_NAME"
paths: paths:
- binaries/ - binaries/
``` ```
--- ---
...@@ -994,7 +994,7 @@ job: ...@@ -994,7 +994,7 @@ job:
artifacts: artifacts:
name: "%CI_JOB_STAGE%-%CI_COMMIT_REF_NAME%" name: "%CI_JOB_STAGE%-%CI_COMMIT_REF_NAME%"
paths: paths:
- binaries/ - binaries/
``` ```
If you use **Windows PowerShell** to run your shell scripts you need to replace If you use **Windows PowerShell** to run your shell scripts you need to replace
...@@ -1005,7 +1005,7 @@ job: ...@@ -1005,7 +1005,7 @@ job:
artifacts: artifacts:
name: "$env:CI_JOB_STAGE-$env:CI_COMMIT_REF_NAME" name: "$env:CI_JOB_STAGE-$env:CI_COMMIT_REF_NAME"
paths: paths:
- binaries/ - binaries/
``` ```
### `artifacts:untracked` ### `artifacts:untracked`
...@@ -1030,7 +1030,7 @@ Send all Git untracked files and files in `binaries`: ...@@ -1030,7 +1030,7 @@ Send all Git untracked files and files in `binaries`:
artifacts: artifacts:
untracked: true untracked: true
paths: paths:
- binaries/ - binaries/
``` ```
### `artifacts:when` ### `artifacts:when`
...@@ -1120,26 +1120,26 @@ build:osx: ...@@ -1120,26 +1120,26 @@ build:osx:
script: make build:osx script: make build:osx
artifacts: artifacts:
paths: paths:
- binaries/ - binaries/
build:linux: build:linux:
stage: build stage: build
script: make build:linux script: make build:linux
artifacts: artifacts:
paths: paths:
- binaries/ - binaries/
test:osx: test:osx:
stage: test stage: test
script: make test:osx script: make test:osx
dependencies: dependencies:
- build:osx - build:osx
test:linux: test:linux:
stage: test stage: test
script: make test:linux script: make test:linux
dependencies: dependencies:
- build:linux - build:linux
deploy: deploy:
stage: deploy stage: deploy
......
...@@ -168,7 +168,7 @@ want their accounts to be upgraded to full internal accounts. ...@@ -168,7 +168,7 @@ want their accounts to be upgraded to full internal accounts.
>**Note:** >**Note:**
The following information only applies for installations from source. The following information only applies for installations from source.
GitLab uses [Omniauth](http://www.omniauth.org/) for authentication and already ships GitLab uses [Omniauth](https://github.com/omniauth/omniauth) for authentication and already ships
with a few providers pre-installed (e.g. LDAP, GitHub, Twitter). But sometimes that with a few providers pre-installed (e.g. LDAP, GitHub, Twitter). But sometimes that
is not enough and you need to integrate with other authentication solutions. For is not enough and you need to integrate with other authentication solutions. For
these cases you can use the Omniauth provider. these cases you can use the Omniauth provider.
......
...@@ -172,4 +172,12 @@ prevent any conflicting changes. ...@@ -172,4 +172,12 @@ prevent any conflicting changes.
You can access your repos via [repository API](../../../api/repositories.md). You can access your repos via [repository API](../../../api/repositories.md).
## Clone in Apple Xcode
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/45820) in GitLab 11.0
Projects that contain a `.xcodeproj` or `.xcworkspace` directory can now be cloned
in Xcode using the new **Open in Xcode** button, located next to the Git URL
used for cloning your project. The button is only shown on macOS.
[jupyter]: https://jupyter.org [jupyter]: https://jupyter.org
...@@ -41,7 +41,7 @@ module API ...@@ -41,7 +41,7 @@ module API
optional :all_available, type: Boolean, desc: 'Show all group that you have access to' optional :all_available, type: Boolean, desc: 'Show all group that you have access to'
optional :search, type: String, desc: 'Search for a specific group' optional :search, type: String, desc: 'Search for a specific group'
optional :owned, type: Boolean, default: false, desc: 'Limit by owned by authenticated user' optional :owned, type: Boolean, default: false, desc: 'Limit by owned by authenticated user'
optional :order_by, type: String, values: %w[name path], default: 'name', desc: 'Order by name or path' optional :order_by, type: String, values: %w[name path id], default: 'name', desc: 'Order by name, path or id'
optional :sort, type: String, values: %w[asc desc], default: 'asc', desc: 'Sort by asc (ascending) or desc (descending)' optional :sort, type: String, values: %w[asc desc], default: 'asc', desc: 'Sort by asc (ascending) or desc (descending)'
use :pagination use :pagination
end end
...@@ -57,7 +57,9 @@ module API ...@@ -57,7 +57,9 @@ module API
groups = groups.preload(:ldap_group_links) groups = groups.preload(:ldap_group_links)
groups = groups.search(params[:search]) if params[:search].present? groups = groups.search(params[:search]) if params[:search].present?
groups = groups.where.not(id: params[:skip_groups]) if params[:skip_groups].present? groups = groups.where.not(id: params[:skip_groups]) if params[:skip_groups].present?
groups = groups.reorder(params[:order_by] => params[:sort]) order_options = { params[:order_by] => params[:sort] }
order_options["id"] ||= "asc"
groups = groups.reorder(order_options)
groups groups
end end
......
...@@ -7,18 +7,10 @@ module Gitlab ...@@ -7,18 +7,10 @@ module Gitlab
# Created or deleted branch # Created or deleted branch
return false if Gitlab::Git.blank_ref?(oldrev) || Gitlab::Git.blank_ref?(newrev) return false if Gitlab::Git.blank_ref?(oldrev) || Gitlab::Git.blank_ref?(newrev)
GitalyClient.migrate(:force_push) do |is_enabled| !project
if is_enabled .repository
!project .gitaly_commit_client
.repository .ancestor?(oldrev, newrev)
.gitaly_commit_client
.ancestor?(oldrev, newrev)
else
Gitlab::Git::RevList.new(
project.repository.raw, oldrev: oldrev, newrev: newrev
).missed_ref.present?
end
end
end end
end end
end end
......
...@@ -472,13 +472,21 @@ module Gitlab ...@@ -472,13 +472,21 @@ module Gitlab
end end
def count_commits(options) def count_commits(options)
count_commits_options = process_count_commits_options(options) options = process_count_commits_options(options.dup)
gitaly_migrate(:count_commits, status: Gitlab::GitalyClient::MigrationStatus::OPT_OUT) do |is_enabled| wrapped_gitaly_errors do
if is_enabled if options[:left_right]
count_commits_by_gitaly(count_commits_options) from = options[:from]
to = options[:to]
right_count = gitaly_commit_client
.commit_count("#{from}..#{to}", options)
left_count = gitaly_commit_client
.commit_count("#{to}..#{from}", options)
[left_count, right_count]
else else
count_commits_by_shelling_out(count_commits_options) gitaly_commit_client.commit_count(options[:ref], options)
end end
end end
end end
...@@ -676,15 +684,9 @@ module Gitlab ...@@ -676,15 +684,9 @@ module Gitlab
end end
# Return total commits count accessible from passed ref # Return total commits count accessible from passed ref
#
# Gitaly migration: https://gitlab.com/gitlab-org/gitaly/issues/330
def commit_count(ref) def commit_count(ref)
gitaly_migrate(:commit_count, status: Gitlab::GitalyClient::MigrationStatus::OPT_OUT) do |is_enabled| wrapped_gitaly_errors do
if is_enabled gitaly_commit_client.commit_count(ref)
gitaly_commit_client.commit_count(ref)
else
rugged_commit_count(ref)
end
end end
end end
...@@ -988,21 +990,7 @@ module Gitlab ...@@ -988,21 +990,7 @@ module Gitlab
def info_attributes def info_attributes
return @info_attributes if @info_attributes return @info_attributes if @info_attributes
content = content = gitaly_repository_client.info_attributes
gitaly_migrate(:get_info_attributes, status: Gitlab::GitalyClient::MigrationStatus::OPT_OUT) do |is_enabled|
if is_enabled
gitaly_repository_client.info_attributes
else
attributes_path = File.join(File.expand_path(path), 'info', 'attributes')
if File.exist?(attributes_path)
File.read(attributes_path)
else
""
end
end
end
@info_attributes = AttributesParser.new(content) @info_attributes = AttributesParser.new(content)
end end
...@@ -1058,18 +1046,8 @@ module Gitlab ...@@ -1058,18 +1046,8 @@ module Gitlab
end end
def license_short_name def license_short_name
gitaly_migrate(:license_short_name, wrapped_gitaly_errors do
status: Gitlab::GitalyClient::MigrationStatus::OPT_OUT) do |is_enabled| gitaly_repository_client.license_short_name
if is_enabled
gitaly_repository_client.license_short_name
else
begin
# The licensee gem creates a Rugged object from the path:
# https://github.com/benbalter/licensee/blob/v8.7.0/lib/licensee/projects/git_project.rb
Licensee.license(path).try(:key)
rescue Rugged::Error
end
end
end end
end end
...@@ -1256,12 +1234,8 @@ module Gitlab ...@@ -1256,12 +1234,8 @@ module Gitlab
end end
def rebase_in_progress?(rebase_id) def rebase_in_progress?(rebase_id)
gitaly_migrate(:rebase_in_progress) do |is_enabled| wrapped_gitaly_errors do
if is_enabled gitaly_repository_client.rebase_in_progress?(rebase_id)
gitaly_repository_client.rebase_in_progress?(rebase_id)
else
fresh_worktree?(worktree_path(REBASE_WORKTREE_PREFIX, rebase_id))
end
end end
end end
...@@ -1277,12 +1251,8 @@ module Gitlab ...@@ -1277,12 +1251,8 @@ module Gitlab
end end
def squash_in_progress?(squash_id) def squash_in_progress?(squash_id)
gitaly_migrate(:squash_in_progress, status: Gitlab::GitalyClient::MigrationStatus::OPT_OUT) do |is_enabled| wrapped_gitaly_errors do
if is_enabled gitaly_repository_client.squash_in_progress?(squash_id)
gitaly_repository_client.squash_in_progress?(squash_id)
else
fresh_worktree?(worktree_path(SQUASH_WORKTREE_PREFIX, squash_id))
end
end end
end end
...@@ -1528,10 +1498,6 @@ module Gitlab ...@@ -1528,10 +1498,6 @@ module Gitlab
run_git!(args, lazy_block: block) run_git!(args, lazy_block: block)
end end
def missed_ref(oldrev, newrev)
run_git!(['rev-list', '--max-count=1', oldrev, "^#{newrev}"])
end
def with_worktree(worktree_path, branch, sparse_checkout_files: nil, env:) def with_worktree(worktree_path, branch, sparse_checkout_files: nil, env:)
base_args = %w(worktree add --detach) base_args = %w(worktree add --detach)
...@@ -1635,21 +1601,6 @@ module Gitlab ...@@ -1635,21 +1601,6 @@ module Gitlab
end end
end end
# This function is duplicated in Gitaly-Go, don't change it!
# https://gitlab.com/gitlab-org/gitaly/merge_requests/698
def fresh_worktree?(path)
File.exist?(path) && !clean_stuck_worktree(path)
end
# This function is duplicated in Gitaly-Go, don't change it!
# https://gitlab.com/gitlab-org/gitaly/merge_requests/698
def clean_stuck_worktree(path)
return false unless File.mtime(path) < 15.minutes.ago
FileUtils.rm_rf(path)
true
end
# Adding a worktree means checking out the repository. For large repos, # Adding a worktree means checking out the repository. For large repos,
# this can be very expensive, so set up sparse checkout for the worktree # this can be very expensive, so set up sparse checkout for the worktree
# to only check out the files we're interested in. # to only check out the files we're interested in.
...@@ -1916,71 +1867,6 @@ module Gitlab ...@@ -1916,71 +1867,6 @@ module Gitlab
gitaly_repository_client.repository_size gitaly_repository_client.repository_size
end end
def count_commits_by_gitaly(options)
if options[:left_right]
from = options[:from]
to = options[:to]
right_count = gitaly_commit_client
.commit_count("#{from}..#{to}", options)
left_count = gitaly_commit_client
.commit_count("#{to}..#{from}", options)
[left_count, right_count]
else
gitaly_commit_client.commit_count(options[:ref], options)
end
end
def count_commits_by_shelling_out(options)
cmd = count_commits_shelling_command(options)
raw_output, _status = run_git(cmd)
process_count_commits_raw_output(raw_output, options)
end
def count_commits_shelling_command(options)
cmd = %w[rev-list]
cmd << "--after=#{options[:after].iso8601}" if options[:after]
cmd << "--before=#{options[:before].iso8601}" if options[:before]
cmd << "--max-count=#{options[:max_count]}" if options[:max_count]
cmd << "--left-right" if options[:left_right]
cmd << '--count'
cmd << if options[:all]
'--all'
elsif options[:ref]
options[:ref]
else
raise ArgumentError, "Please specify a valid ref or set the 'all' attribute to true"
end
cmd += %W[-- #{options[:path]}] if options[:path].present?
cmd
end
def process_count_commits_raw_output(raw_output, options)
if options[:left_right]
result = raw_output.scan(/\d+/).map(&:to_i)
if result.sum != options[:max_count]
result
else # Reaching max count, right is not accurate
right_option =
process_count_commits_options(options
.except(:left_right, :from, :to)
.merge(ref: options[:to]))
right = count_commits_by_shelling_out(right_option)
[result.first, right] # left should be accurate in the first call
end
else
raw_output.to_i
end
end
def gitaly_ls_files(ref) def gitaly_ls_files(ref)
gitaly_commit_client.ls_files(ref) gitaly_commit_client.ls_files(ref)
end end
...@@ -2415,16 +2301,6 @@ module Gitlab ...@@ -2415,16 +2301,6 @@ module Gitlab
nil nil
end end
def rugged_commit_count(ref)
walker = Rugged::Walker.new(rugged)
walker.sorting(Rugged::SORT_TOPO | Rugged::SORT_REVERSE)
oid = rugged.rev_parse_oid(ref)
walker.push(oid)
walker.count
rescue Rugged::ReferenceError
0
end
def rev_list_param(spec) def rev_list_param(spec)
spec == :all ? ['--all'] : spec spec == :all ? ['--all'] : spec
end end
......
# Gitaly note: JV: will probably be migrated indirectly by migrating the call sites.
module Gitlab module Gitlab
module Git module Git
class RevList class RevList
...@@ -45,13 +43,6 @@ module Gitlab ...@@ -45,13 +43,6 @@ module Gitlab
&lazy_block) &lazy_block)
end end
# This methods returns an array of missed references
#
# Should become obsolete after https://gitlab.com/gitlab-org/gitaly/issues/348.
def missed_ref
repository.missed_ref(oldrev, newrev).split("\n")
end
private private
def execute(args) def execute(args)
......
# Gitaly note: JV: two sets of straightforward RPC's. 1 Hard RPC: fork_repository. # Gitaly note: SSH key operations are not part of Gitaly so will never be migrated.
# SSH key operations are not part of Gitaly so will never be migrated.
require 'securerandom' require 'securerandom'
...@@ -153,8 +152,6 @@ module Gitlab ...@@ -153,8 +152,6 @@ module Gitlab
# #
# Ex. # Ex.
# mv_repository("/path/to/storage", "gitlab/gitlab-ci", "randx/gitlab-ci-new") # mv_repository("/path/to/storage", "gitlab/gitlab-ci", "randx/gitlab-ci-new")
#
# Gitaly migration: https://gitlab.com/gitlab-org/gitaly/issues/873
def mv_repository(storage, path, new_path) def mv_repository(storage, path, new_path)
return false if path.empty? || new_path.empty? return false if path.empty? || new_path.empty?
...@@ -169,19 +166,11 @@ module Gitlab ...@@ -169,19 +166,11 @@ module Gitlab
# #
# Ex. # Ex.
# fork_repository("nfs-file06", "gitlab/gitlab-ci", "nfs-file07", "new-namespace/gitlab-ci") # fork_repository("nfs-file06", "gitlab/gitlab-ci", "nfs-file07", "new-namespace/gitlab-ci")
#
# Gitaly migration: https://gitlab.com/gitlab-org/gitaly/issues/817
def fork_repository(forked_from_storage, forked_from_disk_path, forked_to_storage, forked_to_disk_path) def fork_repository(forked_from_storage, forked_from_disk_path, forked_to_storage, forked_to_disk_path)
forked_from_relative_path = "#{forked_from_disk_path}.git" forked_from_relative_path = "#{forked_from_disk_path}.git"
fork_args = [forked_to_storage, "#{forked_to_disk_path}.git"] fork_args = [forked_to_storage, "#{forked_to_disk_path}.git"]
gitaly_migrate(:fork_repository, status: Gitlab::GitalyClient::MigrationStatus::OPT_OUT) do |is_enabled| GitalyGitlabProjects.new(forked_from_storage, forked_from_relative_path).fork_repository(*fork_args)
if is_enabled
GitalyGitlabProjects.new(forked_from_storage, forked_from_relative_path).fork_repository(*fork_args)
else
gitlab_projects(forked_from_storage, forked_from_relative_path).fork_repository(*fork_args)
end
end
end end
# Removes a repository from file system, using rm_diretory which is an alias # Removes a repository from file system, using rm_diretory which is an alias
...@@ -193,8 +182,6 @@ module Gitlab ...@@ -193,8 +182,6 @@ module Gitlab
# #
# Ex. # Ex.
# remove_repository("/path/to/storage", "gitlab/gitlab-ci") # remove_repository("/path/to/storage", "gitlab/gitlab-ci")
#
# Gitaly migration: https://gitlab.com/gitlab-org/gitaly/issues/873
def remove_repository(storage, name) def remove_repository(storage, name)
return false if name.empty? return false if name.empty?
......
...@@ -39,7 +39,8 @@ describe('MRWidgetMerged', () => { ...@@ -39,7 +39,8 @@ describe('MRWidgetMerged', () => {
readableClosedAt: '', readableClosedAt: '',
}, },
updatedAt: 'mergedUpdatedAt', updatedAt: 'mergedUpdatedAt',
shortMergeCommitSha: 'asdf1234', shortMergeCommitSha: '958c0475',
mergeCommitSha: '958c047516e182dfc52317f721f696e8a1ee85ed',
mergeCommitPath: 'http://localhost:3000/root/nautilus/commit/f7ce827c314c9340b075657fd61c789fb01cf74d', mergeCommitPath: 'http://localhost:3000/root/nautilus/commit/f7ce827c314c9340b075657fd61c789fb01cf74d',
sourceBranch: 'bar', sourceBranch: 'bar',
targetBranch, targetBranch,
...@@ -153,7 +154,7 @@ describe('MRWidgetMerged', () => { ...@@ -153,7 +154,7 @@ describe('MRWidgetMerged', () => {
it('shows button to copy commit SHA to clipboard', () => { it('shows button to copy commit SHA to clipboard', () => {
expect(selectors.copyMergeShaButton).toExist(); expect(selectors.copyMergeShaButton).toExist();
expect(selectors.copyMergeShaButton.getAttribute('data-clipboard-text')).toBe(vm.mr.shortMergeCommitSha); expect(selectors.copyMergeShaButton.getAttribute('data-clipboard-text')).toBe(vm.mr.mergeCommitSha);
}); });
it('shows merge commit SHA link', () => { it('shows merge commit SHA link', () => {
......
...@@ -99,7 +99,7 @@ describe Gitlab::Auth::UserAuthFinders do ...@@ -99,7 +99,7 @@ describe Gitlab::Auth::UserAuthFinders do
context 'when the request format is empty' do context 'when the request format is empty' do
it 'the method call does not modify the original value' do it 'the method call does not modify the original value' do
env['action_dispatch.request.formats'] = nil env.delete('action_dispatch.request.formats')
find_user_from_feed_token find_user_from_feed_token
......
require 'spec_helper' require 'spec_helper'
describe Gitlab::Checks::ForcePush do describe Gitlab::Checks::ForcePush do
let(:project) { create(:project, :repository) } set(:project) { create(:project, :repository) }
let(:repository) { project.repository.raw }
context "exit code checking", :skip_gitaly_mock do describe '.force_push?' do
it "does not raise a runtime error if the `popen` call to git returns a zero exit code" do it 'returns false if the repo is empty' do
allow(repository).to receive(:popen).and_return(['normal output', 0]) allow(project).to receive(:empty_repo?).and_return(true)
expect { described_class.force_push?(project, 'oldrev', 'newrev') }.not_to raise_error expect(described_class.force_push?(project, 'HEAD', 'HEAD~')).to be(false)
end end
it "raises a GitError error if the `popen` call to git returns a non-zero exit code" do it 'checks if old rev is an anchestor' do
allow(repository).to receive(:popen).and_return(['error', 1]) expect(described_class.force_push?(project, 'HEAD', 'HEAD~')).to be(true)
expect { described_class.force_push?(project, 'oldrev', 'newrev') }
.to raise_error(Gitlab::Git::Repository::GitError)
end end
end end
end end
...@@ -1114,7 +1114,7 @@ describe Gitlab::Git::Repository, seed_helper: true do ...@@ -1114,7 +1114,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
end end
describe '#count_commits' do describe '#count_commits' do
shared_examples 'extended commit counting' do describe 'extended commit counting' do
context 'with after timestamp' do context 'with after timestamp' do
it 'returns the number of commits after timestamp' do it 'returns the number of commits after timestamp' do
options = { ref: 'master', after: Time.iso8601('2013-03-03T20:15:01+00:00') } options = { ref: 'master', after: Time.iso8601('2013-03-03T20:15:01+00:00') }
...@@ -1199,14 +1199,6 @@ describe Gitlab::Git::Repository, seed_helper: true do ...@@ -1199,14 +1199,6 @@ describe Gitlab::Git::Repository, seed_helper: true do
end end
end end
end end
context 'when Gitaly count_commits feature is enabled' do
it_behaves_like 'extended commit counting'
end
context 'when Gitaly count_commits feature is disabled', :disable_gitaly do
it_behaves_like 'extended commit counting'
end
end end
describe '#autocrlf' do describe '#autocrlf' do
...@@ -1688,70 +1680,52 @@ describe Gitlab::Git::Repository, seed_helper: true do ...@@ -1688,70 +1680,52 @@ describe Gitlab::Git::Repository, seed_helper: true do
end end
describe '#languages' do describe '#languages' do
shared_examples 'languages' do it 'returns exactly the expected results' do
it 'returns exactly the expected results' do languages = repository.languages('4b4918a572fa86f9771e5ba40fbd48e1eb03e2c6')
languages = repository.languages('4b4918a572fa86f9771e5ba40fbd48e1eb03e2c6') expected_languages = [
expected_languages = [ { value: 66.63, label: "Ruby", color: "#701516", highlight: "#701516" },
{ value: 66.63, label: "Ruby", color: "#701516", highlight: "#701516" }, { value: 22.96, label: "JavaScript", color: "#f1e05a", highlight: "#f1e05a" },
{ value: 22.96, label: "JavaScript", color: "#f1e05a", highlight: "#f1e05a" }, { value: 7.9, label: "HTML", color: "#e34c26", highlight: "#e34c26" },
{ value: 7.9, label: "HTML", color: "#e34c26", highlight: "#e34c26" }, { value: 2.51, label: "CoffeeScript", color: "#244776", highlight: "#244776" }
{ value: 2.51, label: "CoffeeScript", color: "#244776", highlight: "#244776" } ]
]
expect(languages.size).to eq(expected_languages.size) expect(languages.size).to eq(expected_languages.size)
expected_languages.size.times do |i| expected_languages.size.times do |i|
a = expected_languages[i] a = expected_languages[i]
b = languages[i] b = languages[i]
expect(a.keys.sort).to eq(b.keys.sort) expect(a.keys.sort).to eq(b.keys.sort)
expect(a[:value]).to be_within(0.1).of(b[:value]) expect(a[:value]).to be_within(0.1).of(b[:value])
non_float_keys = a.keys - [:value] non_float_keys = a.keys - [:value]
expect(a.values_at(*non_float_keys)).to eq(b.values_at(*non_float_keys)) expect(a.values_at(*non_float_keys)).to eq(b.values_at(*non_float_keys))
end
end
it "uses the repository's HEAD when no ref is passed" do
lang = repository.languages.first
expect(lang[:label]).to eq('Ruby')
end end
end end
it_behaves_like 'languages' it "uses the repository's HEAD when no ref is passed" do
lang = repository.languages.first
context 'with rugged', :skip_gitaly_mock do expect(lang[:label]).to eq('Ruby')
it_behaves_like 'languages'
end end
end end
describe '#license_short_name' do describe '#license_short_name' do
shared_examples 'acquiring the Licensee license key' do subject { repository.license_short_name }
subject { repository.license_short_name }
context 'when no license file can be found' do
let(:project) { create(:project, :repository) }
let(:repository) { project.repository.raw_repository }
before do context 'when no license file can be found' do
project.repository.delete_file(project.owner, 'LICENSE', message: 'remove license', branch_name: 'master') let(:project) { create(:project, :repository) }
end let(:repository) { project.repository.raw_repository }
it { is_expected.to be_nil }
end
context 'when an mit license is found' do before do
it { is_expected.to eq('mit') } project.repository.delete_file(project.owner, 'LICENSE', message: 'remove license', branch_name: 'master')
end end
end
context 'when gitaly is enabled' do it { is_expected.to be_nil }
it_behaves_like 'acquiring the Licensee license key'
end end
context 'when gitaly is disabled', :disable_gitaly do context 'when an mit license is found' do
it_behaves_like 'acquiring the Licensee license key' it { is_expected.to eq('mit') }
end end
end end
......
...@@ -93,14 +93,4 @@ describe Gitlab::Git::RevList do ...@@ -93,14 +93,4 @@ describe Gitlab::Git::RevList do
expect { |b| rev_list.all_objects(&b) }.to yield_with_args(%w[sha1 sha2]) expect { |b| rev_list.all_objects(&b) }.to yield_with_args(%w[sha1 sha2])
end end
end end
context "#missed_ref" do
let(:rev_list) { described_class.new(repository, oldrev: 'oldrev', newrev: 'newrev') }
it 'calls out to `popen`' do
stub_popen_rev_list('--max-count=1', 'oldrev', '^newrev', with_lazy_block: false, output: "sha1\nsha2")
expect(rev_list.missed_ref).to eq(%w[sha1 sha2])
end
end
end end
...@@ -498,34 +498,18 @@ describe Gitlab::Shell do ...@@ -498,34 +498,18 @@ describe Gitlab::Shell do
) )
end end
context 'with gitaly' do it 'returns true when the command succeeds' do
it 'returns true when the command succeeds' do expect_any_instance_of(Gitlab::GitalyClient::RepositoryService).to receive(:fork_repository)
expect_any_instance_of(Gitlab::GitalyClient::RepositoryService).to receive(:fork_repository) .with(repository.raw_repository) { :gitaly_response_object }
.with(repository.raw_repository) { :gitaly_response_object }
is_expected.to be_truthy
end
it 'return false when the command fails' do
expect_any_instance_of(Gitlab::GitalyClient::RepositoryService).to receive(:fork_repository)
.with(repository.raw_repository) { raise GRPC::BadStatus, 'bla' }
is_expected.to be_falsy is_expected.to be_truthy
end
end end
context 'without gitaly', :disable_gitaly do it 'return false when the command fails' do
it 'returns true when the command succeeds' do expect_any_instance_of(Gitlab::GitalyClient::RepositoryService).to receive(:fork_repository)
expect(gitlab_projects).to receive(:fork_repository).with('nfs-file05', 'fork/path.git') { true } .with(repository.raw_repository) { raise GRPC::BadStatus, 'bla' }
is_expected.to be_truthy
end
it 'return false when the command fails' do
expect(gitlab_projects).to receive(:fork_repository).with('nfs-file05', 'fork/path.git') { false }
is_expected.to be_falsy is_expected.to be_falsy
end
end end
end end
...@@ -665,7 +649,7 @@ describe Gitlab::Shell do ...@@ -665,7 +649,7 @@ describe Gitlab::Shell do
subject do subject do
gitlab_shell.fetch_remote(repository.raw_repository, remote_name, gitlab_shell.fetch_remote(repository.raw_repository, remote_name,
forced: true, no_tags: true, ssh_auth: ssh_auth) forced: true, no_tags: true, ssh_auth: ssh_auth)
end end
it 'passes the correct params to the gitaly service' do it 'passes the correct params to the gitaly service' do
......
...@@ -152,10 +152,15 @@ describe API::Groups do ...@@ -152,10 +152,15 @@ describe API::Groups do
context "when using sorting" do context "when using sorting" do
let(:group3) { create(:group, name: "a#{group1.name}", path: "z#{group1.path}") } let(:group3) { create(:group, name: "a#{group1.name}", path: "z#{group1.path}") }
let(:group4) { create(:group, name: "same-name", path: "y#{group1.path}") }
let(:group5) { create(:group, name: "same-name") }
let(:response_groups) { json_response.map { |group| group['name'] } } let(:response_groups) { json_response.map { |group| group['name'] } }
let(:response_groups_ids) { json_response.map { |group| group['id'] } }
before do before do
group3.add_owner(user1) group3.add_owner(user1)
group4.add_owner(user1)
group5.add_owner(user1)
end end
it "sorts by name ascending by default" do it "sorts by name ascending by default" do
...@@ -164,7 +169,7 @@ describe API::Groups do ...@@ -164,7 +169,7 @@ describe API::Groups do
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers expect(response).to include_pagination_headers
expect(json_response).to be_an Array expect(json_response).to be_an Array
expect(response_groups).to eq([group3.name, group1.name]) expect(response_groups).to eq(Group.visible_to_user(user1).order(:name).pluck(:name))
end end
it "sorts in descending order when passed" do it "sorts in descending order when passed" do
...@@ -173,16 +178,52 @@ describe API::Groups do ...@@ -173,16 +178,52 @@ describe API::Groups do
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers expect(response).to include_pagination_headers
expect(json_response).to be_an Array expect(json_response).to be_an Array
expect(response_groups).to eq([group1.name, group3.name]) expect(response_groups).to eq(Group.visible_to_user(user1).order(name: :desc).pluck(:name))
end end
it "sorts by the order_by param" do it "sorts by path in order_by param" do
get api("/groups", user1), order_by: "path" get api("/groups", user1), order_by: "path"
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers expect(response).to include_pagination_headers
expect(json_response).to be_an Array expect(json_response).to be_an Array
expect(response_groups).to eq([group1.name, group3.name]) expect(response_groups).to eq(Group.visible_to_user(user1).order(:path).pluck(:name))
end
it "sorts by id in the order_by param" do
get api("/groups", user1), order_by: "id"
expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(response_groups).to eq(Group.visible_to_user(user1).order(:id).pluck(:name))
end
it "sorts also by descending id with pagination fix" do
get api("/groups", user1), order_by: "id", sort: "desc"
expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(response_groups).to eq(Group.visible_to_user(user1).order(id: :desc).pluck(:name))
end
it "sorts identical keys by id for good pagination" do
get api("/groups", user1), search: "same-name", order_by: "name"
expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(response_groups_ids).to eq(Group.select { |group| group['name'] == 'same-name' }.map { |group| group['id'] }.sort)
end
it "sorts descending identical keys by id for good pagination" do
get api("/groups", user1), search: "same-name", order_by: "name", sort: "desc"
expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(response_groups_ids).to eq(Group.select { |group| group['name'] == 'same-name' }.map { |group| group['id'] }.sort)
end end
end end
......
...@@ -13,7 +13,7 @@ module Spec ...@@ -13,7 +13,7 @@ module Spec
module Features module Features
module NotesHelpers module NotesHelpers
def add_note(text) def add_note(text)
Sidekiq::Testing.fake! do perform_enqueued_jobs do
page.within(".js-main-target-form") do page.within(".js-main-target-form") do
fill_in("note[note]", with: text) fill_in("note[note]", with: text)
find(".js-comment-submit-button").click find(".js-comment-submit-button").click
......
...@@ -245,6 +245,70 @@ RSpec.shared_examples 'slack or mattermost notifications' do ...@@ -245,6 +245,70 @@ RSpec.shared_examples 'slack or mattermost notifications' do
end end
end end
describe 'Push events' do
let(:user) { create(:user) }
let(:project) { create(:project, :repository, creator: user) }
before do
allow(chat_service).to receive_messages(
project: project,
service_hook: true,
webhook: webhook_url
)
WebMock.stub_request(:post, webhook_url)
end
context 'only notify for the default branch' do
context 'when enabled' do
before do
chat_service.notify_only_default_branch = true
end
it 'does not notify push events if they are not for the default branch' do
ref = "#{Gitlab::Git::BRANCH_REF_PREFIX}test"
push_sample_data = Gitlab::DataBuilder::Push.build(project, user, nil, nil, ref, [])
chat_service.execute(push_sample_data)
expect(WebMock).not_to have_requested(:post, webhook_url)
end
it 'notifies about push events for the default branch' do
push_sample_data = Gitlab::DataBuilder::Push.build_sample(project, user)
chat_service.execute(push_sample_data)
expect(WebMock).to have_requested(:post, webhook_url).once
end
it 'still notifies about pushed tags' do
ref = "#{Gitlab::Git::TAG_REF_PREFIX}test"
push_sample_data = Gitlab::DataBuilder::Push.build(project, user, nil, nil, ref, [])
chat_service.execute(push_sample_data)
expect(WebMock).to have_requested(:post, webhook_url).once
end
end
context 'when disabled' do
before do
chat_service.notify_only_default_branch = false
end
it 'notifies about all push events' do
ref = "#{Gitlab::Git::BRANCH_REF_PREFIX}test"
push_sample_data = Gitlab::DataBuilder::Push.build(project, user, nil, nil, ref, [])
chat_service.execute(push_sample_data)
expect(WebMock).to have_requested(:post, webhook_url).once
end
end
end
end
describe "Note events" do describe "Note events" do
let(:user) { create(:user) } let(:user) { create(:user) }
let(:project) { create(:project, :repository, creator: user) } let(:project) { create(:project, :repository, creator: user) }
...@@ -394,23 +458,6 @@ RSpec.shared_examples 'slack or mattermost notifications' do ...@@ -394,23 +458,6 @@ RSpec.shared_examples 'slack or mattermost notifications' do
expect(result).to be_falsy expect(result).to be_falsy
end end
it 'does not notify push events if they are not for the default branch' do
ref = "#{Gitlab::Git::BRANCH_REF_PREFIX}test"
push_sample_data = Gitlab::DataBuilder::Push.build(project, user, nil, nil, ref, [])
chat_service.execute(push_sample_data)
expect(WebMock).not_to have_requested(:post, webhook_url)
end
it 'notifies about push events for the default branch' do
push_sample_data = Gitlab::DataBuilder::Push.build_sample(project, user)
chat_service.execute(push_sample_data)
expect(WebMock).to have_requested(:post, webhook_url).once
end
end end
context 'when disabled' do context 'when disabled' do
......
...@@ -92,16 +92,6 @@ describe RepositoryForkWorker do ...@@ -92,16 +92,6 @@ describe RepositoryForkWorker do
end end
it_behaves_like 'RepositoryForkWorker performing' it_behaves_like 'RepositoryForkWorker performing'
it 'logs a message about forking with old-style arguments' do
allow(subject).to receive(:gitlab_shell).and_return(shell)
expect(shell).to receive(:fork_repository) { true }
allow(Rails.logger).to receive(:info).with(anything) # To compensate for other logs
expect(Rails.logger).to receive(:info).with("Project #{fork_project.id} is being forked using old-style arguments.")
perform!
end
end end
end end
end end
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