Commit ee82a41f authored by GitLab Bot's avatar GitLab Bot

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

# Conflicts:
#	Gemfile.lock
#	app/services/projects/disable_deploy_key_service.rb
#	app/views/dashboard/merge_requests.html.haml
#	app/views/devise/shared/_tabs_ldap.html.haml
#	doc/install/requirements.md
#	package.json
#	spec/controllers/projects/deploy_keys_controller_spec.rb

[ci skip]
parents 9f04b5a1 af1ed0e2
......@@ -917,6 +917,39 @@ qa:selectors:
- bundle install
- bundle exec bin/qa Test::Sanity::Selectors
.qa-frontend-node: &qa-frontend-node
stage: test
variables:
NODE_OPTIONS: --max_old_space_size=3584
cache:
key: "$CI_JOB_NAME"
paths:
- .yarn-cache/
dependencies: []
before_script: []
script:
- date
- yarn install --frozen-lockfile --cache-folder .yarn-cache
- date
- yarn run webpack-prod
qa-frontend-node:6:
<<: *qa-frontend-node
image: node:6-alpine
qa-frontend-node:8:
<<: *qa-frontend-node
image: node:8-alpine
qa-frontend-node:10:
<<: *qa-frontend-node
image: node:10-alpine
qa-frontend-node:latest:
<<: *qa-frontend-node
image: node:alpine
allow_failure: true
coverage:
# Don't include dedicated-no-docs-no-db-pull-cache-job here since we need to
# download artifacts from all the rspec jobs instead of from setup-test-env only
......@@ -966,6 +999,8 @@ pages:
- mv coverage-javascript/ public/coverage-javascript/ || true
- mv eslint-report.html public/ || true
- mv webpack-report/ public/webpack-report/ || true
- cp .public/assets/application-*.css public/application.css || true
- cp .public/assets/application-*.css.gz public/application.css.gz || true
artifacts:
paths:
- public
......
......@@ -64,7 +64,7 @@ Some features might be simple enough that they only involve one Component, while
more complex features could involve multiple or even all.
Example (from https://gitlab.com/gitlab-org/gitlab-ce/issues/50353):
* Respository is
* Repository is
* Intuitive
* It's easy to select the desired file template
* It doesn't require unnecessary actions to save the change
......@@ -93,4 +93,4 @@ When adding new automated tests, please keep [testing levels](https://docs.gitla
in mind.
-->
/label ~Quality ~"test plan"
\ No newline at end of file
/label ~Quality ~"test plan"
......@@ -14,6 +14,9 @@ source 'https://rubygems.org'
gem 'rails', gem_versions['rails']
gem 'rails-deprecated_sanitizer', '~> 1.0.3'
# Improves copy-on-write performance for MRI
gem 'nakayoshi_fork', '~> 0.0.4'
# Responders respond_to and respond_with
gem 'responders', '~> 2.0'
......@@ -146,7 +149,7 @@ gem 'rdoc', '~> 6.0'
gem 'org-ruby', '~> 0.9.12'
gem 'creole', '~> 0.5.0'
gem 'wikicloth', '0.8.1'
gem 'asciidoctor', '~> 1.5.6'
gem 'asciidoctor', '~> 1.5.8'
gem 'asciidoctor-plantuml', '0.0.8'
gem 'rouge', '~> 3.1'
gem 'truncato', '~> 0.7.9'
......@@ -236,7 +239,7 @@ gem 'slack-notifier', '~> 1.5.1'
gem 'hangouts-chat', '~> 0.0.5'
# Asana integration
gem 'asana', '~> 0.6.0'
gem 'asana', '~> 0.8.1'
# FogBugz integration
gem 'ruby-fogbugz', '~> 0.2.1'
......
......@@ -53,12 +53,12 @@ GEM
aes_key_wrap (1.0.1)
akismet (2.0.0)
arel (7.1.4)
asana (0.6.0)
asana (0.8.1)
faraday (~> 0.9)
faraday_middleware (~> 0.9)
faraday_middleware-multi_json (~> 0.0)
oauth2 (~> 1.0)
asciidoctor (1.5.6.2)
asciidoctor (1.5.8)
asciidoctor-plantuml (0.0.8)
asciidoctor (~> 1.5)
ast (2.4.0)
......@@ -301,7 +301,10 @@ GEM
github-markup (1.7.0)
gitlab-default_value_for (3.1.1)
activerecord (>= 3.2.0, < 6.0)
<<<<<<< HEAD
gitlab-license (1.0.0)
=======
>>>>>>> upstream/master
gitlab-markup (1.6.5)
gitlab-sidekiq-fetcher (0.3.0)
sidekiq (~> 5)
......@@ -498,6 +501,7 @@ GEM
mustermann-grape (1.0.0)
mustermann (~> 1.0.0)
mysql2 (0.4.10)
nakayoshi_fork (0.0.4)
net-ldap (0.16.0)
net-ntp (2.1.3)
net-ssh (5.0.1)
......@@ -970,8 +974,8 @@ DEPENDENCIES
acts-as-taggable-on (~> 5.0)
addressable (~> 2.5.2)
akismet (~> 2.0)
asana (~> 0.6.0)
asciidoctor (~> 1.5.6)
asana (~> 0.8.1)
asciidoctor (~> 1.5.8)
asciidoctor-plantuml (= 0.0.8)
attr_encrypted (~> 3.1.0)
awesome_print
......@@ -1041,7 +1045,10 @@ DEPENDENCIES
gitaly-proto (~> 0.123.0)
github-markup (~> 1.7.0)
gitlab-default_value_for (~> 3.1.1)
<<<<<<< HEAD
gitlab-license (~> 1.0)
=======
>>>>>>> upstream/master
gitlab-markup (~> 1.6.5)
gitlab-sidekiq-fetcher
gitlab-styles (~> 2.4)
......@@ -1087,6 +1094,7 @@ DEPENDENCIES
mini_magick
minitest (~> 5.7.0)
mysql2 (~> 0.4.10)
nakayoshi_fork (~> 0.0.4)
net-ldap
net-ntp
net-ssh (~> 5.0)
......
......@@ -50,12 +50,12 @@ GEM
aes_key_wrap (1.0.1)
akismet (2.0.0)
arel (6.0.4)
asana (0.6.0)
asana (0.8.1)
faraday (~> 0.9)
faraday_middleware (~> 0.9)
faraday_middleware-multi_json (~> 0.0)
oauth2 (~> 1.0)
asciidoctor (1.5.6.2)
asciidoctor (1.5.8)
asciidoctor-plantuml (0.0.8)
asciidoctor (~> 1.5)
ast (2.4.0)
......@@ -495,6 +495,7 @@ GEM
mustermann-grape (1.0.0)
mustermann (~> 1.0.0)
mysql2 (0.4.10)
nakayoshi_fork (0.0.4)
net-ldap (0.16.0)
net-ntp (2.1.3)
net-ssh (5.0.1)
......@@ -961,8 +962,8 @@ DEPENDENCIES
acts-as-taggable-on (~> 5.0)
addressable (~> 2.5.2)
akismet (~> 2.0)
asana (~> 0.6.0)
asciidoctor (~> 1.5.6)
asana (~> 0.8.1)
asciidoctor (~> 1.5.8)
asciidoctor-plantuml (= 0.0.8)
attr_encrypted (~> 3.1.0)
awesome_print
......@@ -1078,6 +1079,7 @@ DEPENDENCIES
mini_magick
minitest (~> 5.7.0)
mysql2 (~> 0.4.10)
nakayoshi_fork (~> 0.0.4)
net-ldap
net-ntp
net-ssh (~> 5.0)
......
......@@ -69,10 +69,13 @@ export default class DropdownEmoji extends FilteredSearchDropdown {
// Replace empty gl-emoji tag to real content
const dropdownItems = [...this.dropdown.querySelectorAll('.filter-dropdown-item')];
dropdownItems.forEach(dropdownItem => {
const name = dropdownItem.querySelector('.js-data-value').innerText;
const emojiTag = this.glEmojiTag(name);
const emojiElement = dropdownItem.querySelector('gl-emoji');
emojiElement.outerHTML = emojiTag;
const valueElement = dropdownItem.querySelector('.js-data-value');
if (valueElement !== null) {
const name = valueElement.innerText;
const emojiTag = this.glEmojiTag(name);
const emojiElement = dropdownItem.querySelector('gl-emoji');
emojiElement.outerHTML = emojiTag;
}
});
}
......
......@@ -33,6 +33,10 @@ export default {
type: Object,
required: true,
},
showMetrics: {
type: Boolean,
required: true,
},
},
deployedTextMap: {
running: __('Deploying to'),
......@@ -74,6 +78,9 @@ export default {
shouldRenderDropdown() {
return this.deployment.changes && this.deployment.changes.length > 0;
},
showMemoryUsage() {
return this.hasMetrics && this.showMetrics;
},
},
methods: {
stopEnvironment() {
......@@ -136,7 +143,7 @@ export default {
{{ deployTimeago }}
</span>
<memory-usage
v-if="hasMetrics"
v-if="showMemoryUsage"
:metrics-url="deployment.metrics_url"
:metrics-monitoring-url="deployment.metrics_monitoring_url"
/>
......
......@@ -313,6 +313,7 @@ export default {
:key="`pre-merge-deploy-${deployment.id}`"
class="js-pre-merge-deploy"
:deployment="deployment"
:show-metrics="false"
/>
<div class="mr-section-container">
<grouped-test-reports-app
......@@ -367,6 +368,7 @@ export default {
v-for="postMergeDeployment in mr.postMergeDeployments"
:key="`post-merge-deploy-${postMergeDeployment.id}`"
:deployment="postMergeDeployment"
:show-metrics="true"
class="js-post-deployment"
/>
</template>
......
......@@ -230,24 +230,13 @@ class Commit
def lazy_author
BatchLoader.for(author_email.downcase).batch do |emails, loader|
# A Hash that maps user Emails to the corresponding User objects. The
# Emails at this point are the _primary_ Emails of the Users.
users_for_emails = User
.by_any_email(emails)
.each_with_object({}) { |user, hash| hash[user.email] = user }
users_for_ids = users_for_emails
.values
.each_with_object({}) { |user, hash| hash[user.id] = user }
# Some commits may have used an alternative Email address. In this case we
# need to query the "emails" table to map those addresses to User objects.
Email
.where(email: emails - users_for_emails.keys)
.pluck(:email, :user_id)
.each { |(email, id)| users_for_emails[email] = users_for_ids[id] }
users_for_emails.each { |email, user| loader.call(email, user) }
users = User.by_any_email(emails).includes(:emails)
emails.each do |email|
user = users.find { |u| u.any_email?(email) }
loader.call(email, user)
end
end
end
......
......@@ -1965,7 +1965,7 @@ class Project < ActiveRecord::Base
end
def migrate_to_hashed_storage!
return if hashed_storage?(:repository)
return unless storage_upgradable?
update!(repository_read_only: true)
......
......@@ -26,16 +26,8 @@ module ChatMessage
end
def activity
action = if new_branch?
"created"
elsif removed_branch?
"removed"
else
"pushed to"
end
{
title: "#{user_combined_name} #{action} #{ref_type}",
title: humanized_action(short: true),
subtitle: "in #{project_link}",
text: compare_link,
image: user_avatar
......@@ -44,32 +36,21 @@ module ChatMessage
private
def humanized_action(short: false)
action, ref_link, target_link = compose_action_details
text = [user_combined_name, action, ref_type, ref_link]
text << target_link unless short
text.join(' ')
end
def message
if new_branch?
new_branch_message
elsif removed_branch?
removed_branch_message
else
push_message
end
humanized_action
end
def format(string)
Slack::Notifier::LinkFormatter.format(string)
end
def new_branch_message
"#{user_combined_name} pushed new #{ref_type} #{branch_link} to #{project_link}"
end
def removed_branch_message
"#{user_combined_name} removed #{ref_type} #{ref} from #{project_link}"
end
def push_message
"#{user_combined_name} pushed to #{ref_type} #{branch_link} of #{project_link} (#{compare_link})"
end
def commit_messages
commits.map { |commit| compose_commit_message(commit) }.join("\n\n")
end
......@@ -115,6 +96,16 @@ module ChatMessage
"[Compare changes](#{compare_url})"
end
def compose_action_details
if new_branch?
['pushed new', branch_link, "to #{project_link}"]
elsif removed_branch?
['removed', ref, "from #{project_link}"]
else
['pushed to', branch_link, "of #{project_link} (#{compare_link})"]
end
end
def attachment_color
'#345'
end
......
......@@ -349,20 +349,28 @@ class User < ActiveRecord::Base
def find_by_any_email(email, confirmed: false)
return unless email
downcased = email.downcase
find_by_private_commit_email(downcased) || by_any_email(downcased, confirmed: confirmed).take
by_any_email(email, confirmed: confirmed).take
end
# Returns a relation containing all the users for the given Email address
def by_any_email(email, confirmed: false)
users = where(email: email)
users = users.confirmed if confirmed
# Returns a relation containing all the users for the given email addresses
#
# @param emails [String, Array<String>] email addresses to check
# @param confirmed [Boolean] Only return users where the email is confirmed
def by_any_email(emails, confirmed: false)
emails = Array(emails).map(&:downcase)
from_users = where(email: emails)
from_users = from_users.confirmed if confirmed
emails = joins(:emails).where(emails: { email: email })
emails = emails.confirmed if confirmed
from_emails = joins(:emails).where(emails: { email: emails })
from_emails = from_emails.confirmed if confirmed
from_union([users, emails])
items = [from_users, from_emails]
user_ids = Gitlab::PrivateCommitEmail.user_ids_for_emails(emails)
items << where(id: user_ids) if user_ids.present?
from_union(items)
end
def find_by_private_commit_email(email)
......@@ -1031,6 +1039,7 @@ class User < ActiveRecord::Base
def all_emails
all_emails = []
all_emails << email unless temp_oauth_email?
all_emails << private_commit_email
all_emails.concat(emails.map(&:email))
all_emails
end
......@@ -1043,16 +1052,24 @@ class User < ActiveRecord::Base
verified_emails
end
def any_email?(check_email)
downcased = check_email.downcase
# handle the outdated private commit email case
return true if persisted? &&
id == Gitlab::PrivateCommitEmail.user_id_for_email(downcased)
all_emails.include?(check_email.downcase)
end
def verified_email?(check_email)
downcased = check_email.downcase
if email == downcased
primary_email_verified?
else
user_id = Gitlab::PrivateCommitEmail.user_id_for_email(downcased)
# handle the outdated private commit email case
return true if persisted? &&
id == Gitlab::PrivateCommitEmail.user_id_for_email(downcased)
user_id == id || emails.confirmed.where(email: downcased).exists?
end
verified_emails.include?(check_email.downcase)
end
def hook_attrs
......
......@@ -11,5 +11,8 @@ module Projects
end
end
end
<<<<<<< HEAD
Projects::DisableDeployKeyService.prepend(EE::Projects::DisableDeployKeyService)
=======
>>>>>>> upstream/master
- @hide_top_links = true
- page_title _("Merge Requests")
- @breadcrumb_link = merge_requests_dashboard_path(assignee_username: current_user.username)
<<<<<<< HEAD
= render_if_exists "shared/gold_trial_callout"
=======
>>>>>>> upstream/master
.page-title-holder
%h1.page-title= _('Merge Requests')
......
......@@ -21,6 +21,8 @@
.login-body
= render 'devise/sessions/new_base'
= render_if_exists 'devise/sessions/new_smartcard'
- elsif password_authentication_enabled_for_web?
.login-box.tab-pane.active{ id: 'login-pane', role: 'tabpanel' }
.login-body
......
......@@ -2,9 +2,12 @@
- if crowd_enabled?
%li.nav-item
= link_to "Crowd", "#crowd", class: "nav-link #{active_when(form_based_auth_provider_has_active_class?(:crowd))}", 'data-toggle' => 'tab'
<<<<<<< HEAD
- if kerberos_enabled?
%li.nav-item
= link_to "Kerberos", "#kerberos", class: "nav-link #{active_when(form_based_auth_provider_has_active_class?(:kerberos))}", 'data-toggle' => 'tab'
=======
>>>>>>> upstream/master
- @ldap_servers.each_with_index do |server, i|
%li.nav-item
= link_to server['label'], "##{server['provider_name']}", class: "nav-link #{active_when(i.zero? && form_based_auth_provider_has_active_class?(:ldapmain))} qa-ldap-tab", 'data-toggle' => 'tab'
......
---
title: Don't show Memory Usage for unmerged MRs
merge_request:
author:
type: changed
---
title: Chat message push notifications now include links back to GitLab branches
merge_request: 22651
author: Tony Castrogiovanni
type: added
---
title: 'Hashed Storage: allow migration to be retried in partially migrated projects'
merge_request: 23087
author:
type: fixed
---
title: Update asana to 0.8.1
merge_request: 23039
author: Takuya Noguchi
type: other
---
title: Update asciidoctor to 1.5.8
merge_request: 23047
author: Takuya Noguchi
type: other
---
title: Updated Gitaly to v0.133.0
merge_request: 23148
author:
type: other
---
title: Auto DevOps support for Group Security Dashboard
merge_request: 23165
author:
type: fixed
---
title: Fix not render emoji in filter dropdown
merge_request: 23112
author: Hiroyuki Sato
type: fixed
---
title: Fix enabling project deploy key for admins
merge_request: 23043
author:
type: fixed
---
title: Improve memory performance by reducing dirty pages after fork()
merge_request: 23169
author:
type: performance
......@@ -544,13 +544,6 @@
:why: https://github.com/xtuc/webassemblyjs/blob/master/LICENSE
:versions: []
:when: 2018-06-08 05:30:56.764116000 Z
- - :license
- "@gitlab-org/gitlab-ui"
- MIT
- :who: Clement Ho
:why: Our own library
:versions: []
:when: 2018-07-17 21:02:54.529227000 Z
- - :approve
- lz-string
- :who: Phil Hughes
......
......@@ -685,7 +685,7 @@ cache, queues, and shared_state. To make this work with Sentinel:
```
1. Note that for each persistence class, GitLab will default to using the
configuration specified in `gitlab_rails['redis_sentinels']` unless
overriden by the settings above.
overridden by the settings above.
1. Be sure to include BOTH configuration options for each persistent classes. For example,
if you choose to configure a cache instance, you must specify both `gitlab_rails['redis_cache_instance']`
and `gitlab_rails['redis_cache_sentinels']` for GitLab to generate the proper configuration files.
......
......@@ -299,7 +299,7 @@ runners will not use regular runners, they must be tagged accordingly.
[jobs]: #jobs
[jobs-yaml]: yaml/README.md#jobs
[manual]: yaml/README.md#manual
[manual]: yaml/README.md#whenmanual
[env-manual]: environments.md#manually-deploying-to-environments
[stages]: yaml/README.md#stages
[runners]: runners/README.md
......
......@@ -17,7 +17,7 @@ There are two places defined variables can be used. On the:
| Definition | Can be expanded? | Expansion place | Description |
|--------------------------------------|-------------------|-----------------|--------------|
| `environment:url` | yes | GitLab | The variable expansion is made by GitLab's [internal variable expansion mechanism](#gitlab-internal-variable-expansion-mechanism).<ul><li>Supported: all variables defined for a job (project/group variables, variables from `.gitlab-ci.yml`, variables from triggers, variables from pipeline schedules)</li><li>Not suported: variables defined in Runner's `config.toml` and variables created in job's `script`</li></ul> |
| `environment:url` | yes | GitLab | The variable expansion is made by GitLab's [internal variable expansion mechanism](#gitlab-internal-variable-expansion-mechanism).<ul><li>Supported: all variables defined for a job (project/group variables, variables from `.gitlab-ci.yml`, variables from triggers, variables from pipeline schedules)</li><li>Not supported: variables defined in Runner's `config.toml` and variables created in job's `script`</li></ul> |
| `environment:name` | yes | GitLab | Similar to `environment:url`, but the variables expansion doesn't support: <ul><li>variables that are based on the environment's name (`CI_ENVIRONMENT_NAME`, `CI_ENVIRONMENT_SLUG`)</li><li>any other variables related to environment (currently only `CI_ENVIRONMENT_URL`)</li><li>[persisted variables](#persisted-variables)</li></ul> |
| `variables` | yes | Runner | The variable expansion is made by GitLab Runner's [internal variable expansion mechanism](#gitlab-runner-internal-variable-expansion-mechanism) |
| `image` | yes | Runner | The variable expansion is made by GitLab Runner's [internal variable expansion mechanism](#gitlab-runner-internal-variable-expansion-mechanism) |
......
......@@ -1770,7 +1770,7 @@ stages:
production:
script:
- install_depedencies
- install_dependencies
- deploy
- notify_owner
```
......
......@@ -33,7 +33,7 @@ You can follow the progress on that [in the issue on our issue tracker](https://
In general, it's better to have a group- or user-based gate, and you should prefer
it over the use of percentage gates. This would make debugging easier, as you
filter for example logs and errors based on actors too. Futhermore, this allows
filter for example logs and errors based on actors too. Furthermore, this allows
for enabling for the `gitlab-org` group first, while the rest of the users
aren't impacted.
......
......@@ -24,7 +24,7 @@ Review Apps are automatically deployed by each pipeline, both in
[`scripts/review_apps/review-apps.sh`][review-apps.sh]
- These scripts are basically
[our official Auto DevOps scripts][Auto-DevOps.gitlab-ci.yml] where the
default CNG images are overriden with the images built and stored in the
default CNG images are overridden with the images built and stored in the
[`CNG-mirror` project's registry][cng-mirror-registry].
- Since we're using [the official GitLab Helm chart][helm-chart], this means
you get a dedicated environment for your branch that's very close to what it
......@@ -33,7 +33,7 @@ Review Apps are automatically deployed by each pipeline, both in
thanks to the direct link to it from the MR widget. The default username is
`root` and its password can be found in the 1Password secure note named
**gitlab-{ce,ee} Review App's root password** (note that there's currently
[a bug where the default password seems to be overriden][password-bug]).
[a bug where the default password seems to be overridden][password-bug]).
**Additional notes:**
......
......@@ -103,10 +103,15 @@ features of GitLab work with MySQL/MariaDB:
1. MySQL support for subgroups was [dropped with GitLab 9.3][post].
See [issue #30472][30472] for more information.
<<<<<<< HEAD
1. Geo does [not support MySQL](../administration/geo/replication/database.md#mysql-replication). This means no supported Disaster Recovery solution if using MySQL. **[PREMIUM ONLY]**
1. [Zero downtime migrations][../update/README.md#upgrading-without-downtime] do not work with MySQL.
1. [Database load balancing](../administration/database_load_balancing.md) is
supported only for PostgreSQL.
=======
1. Geo does [not support MySQL](https://docs.gitlab.com/ee/administration/geo/replication/database.html#mysql-replication). This means no supported Disaster Recovery solution if using MySQL. **[PREMIUM ONLY]**
1. [Zero downtime migrations](../update/README.md#upgrading-without-downtime) do not work with MySQL.
>>>>>>> upstream/master
1. GitLab [optimizes the loading of dashboard events](https://gitlab.com/gitlab-org/gitlab-ce/issues/31806) using [PostgreSQL LATERAL JOINs](https://blog.heapanalytics.com/postgresqls-powerful-new-join-type-lateral/).
1. In general, SQL optimized for PostgreSQL may run much slower in MySQL due to
differences in query planners. For example, subqueries that work well in PostgreSQL
......
......@@ -657,6 +657,8 @@ also be customized, and you can easily use a [custom buildpack](#custom-buildpac
| `REVIEW_DISABLED` | From GitLab 11.0, this variable can be used to disable the `review` and the manual `review:stop` job. If the variable is present, these jobs will not be created. |
| `DAST_DISABLED` | From GitLab 11.0, this variable can be used to disable the `dast` job. If the variable is present, the job will not be created. |
| `PERFORMANCE_DISABLED` | From GitLab 11.0, this variable can be used to disable the `performance` job. If the variable is present, the job will not be created. |
| `OLD_REPORTS_DISABLED` | From GitLab 11.5, this variable can be used to disable the `sast` job. If the variable is present, the job will not be created. |
| `NEW_REPORTS_DISABLED` | From GitLab 11.5, this variable can be used to disable the `sast_dashboard` job. If the variable is present, the job will not be created. |
TIP: **Tip:**
Set up the replica variables using a
......
......@@ -17,6 +17,7 @@ the [GitHub rake task](../../../administration/raketasks/github_import.md) to im
GitHub without the constraints of a Sidekiq worker.
The following aspects of a project are imported:
* Repository description (GitLab.com & 7.7+)
* Git repository data (GitLab.com & 7.7+)
* Issues (GitLab.com & 7.7+)
......
......@@ -201,11 +201,11 @@ administrator to do so.
### Adding patches when creating a merge request via e-mail
> **Note**: This feature was [implemented in GitLab 11.5](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/22723)
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/22723) in GitLab 11.5.
You can add commits to the merge request being created by adding
patches as attachments to the email, all attachments with a filename
ending in `.patch` will be considered patches. The patches will be processed
patches as attachments to the email. All attachments with a filename
ending in `.patch` will be considered patches and they will be processed
ordered by name.
The combined size of the patches can be 2MB.
......@@ -218,7 +218,7 @@ branch already exists, the patches will be applied on top of it.
## Find the merge request that introduced a change
> **Note**: this feature was [implemented in GitLab 10.5](https://gitlab.com/gitlab-org/gitlab-ce/issues/2383).
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/2383) in GitLab 10.5.
When viewing the commit details page, GitLab will link to the merge request (or
merge requests, if it's in more than one) containing that commit.
......
......@@ -6,6 +6,26 @@ Milestones in GitLab are a way to track issues and merge requests created to ach
Milestones allow you to organize issues and merge requests into a cohesive group, with an optional start date and an optional due date.
## Milestones as Agile sprints
Milestones can be used as Agile sprints.
Set the milestone start date and due date to represent
the start and end of your Agile sprint.
Set the milestone title to the name of your Agile sprint,
such as `November 2018 sprint`.
Add an issue to your Agile sprint by associating
the milestone to the issue.
## Milestones as releases
Milestones can be used as releases.
Set the milestone due date to represent the release date of your release.
(And leave the milestone start date blank.)
Set the the milestone title to the version of your release,
such as `Version 9.4`.
Add an issue to your release by associating
the milestone to the issue.
## Project milestones and group milestones
- **Project milestones** can be assigned to issues or merge requests in that project only. Navigate to **Issues > Milestones** in a project to view the project milestone list.
......
......@@ -19,6 +19,15 @@
# * review: REVIEW_DISABLED
# * stop_review: REVIEW_DISABLED
#
# The sast and sast_dashboard jobs are executed to guarantee full compatibility
# with the group security dashboard and the security reports with old runners.
# If you use only runners with version 11.5 or above, you can disable the sast
# job by setting the OLD_REPORTS_DISABLED environment variable. If you use only
# runners with version below 11.5, you can disable the sast_dashboard job by
# setting the NEW_REPORTS_DISABLED environment variable.
# The sast_dashboard job will be removed in the future, when the sast job will
# use the new reports syntax.
#
# In order to deploy, you must have a Kubernetes cluster configured either
# via a project integration, or via group/project variables.
# AUTO_DEVOPS_DOMAIN must also be set as a variable at the group or project
......@@ -173,6 +182,29 @@ sast:
except:
variables:
- $SAST_DISABLED
- $OLD_REPORTS_DISABLED
sast_dashboard:
stage: test
image: docker:stable
allow_failure: true
services:
- docker:stable-dind
script:
- setup_docker
- sast
artifacts:
reports:
sast: gl-sast-report.json
only:
refs:
- branches
variables:
- $GITLAB_FEATURES =~ /\bsast\b/
except:
variables:
- $SAST_DISABLED
- $NEW_REPORTS_DISABLED
dependency_scanning:
stage: test
......
......@@ -18,6 +18,10 @@ module Gitlab
match[:id].to_i
end
def user_ids_for_emails(emails)
emails.map { |email| user_id_for_email(email) }.compact.uniq
end
def for_user(user)
hostname = Gitlab::CurrentSettings.current_application_settings.commit_email_hostname
......
......@@ -24,8 +24,13 @@
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
"@babel/plugin-syntax-import-meta": "^7.0.0",
"@babel/preset-env": "^7.1.0",
<<<<<<< HEAD
"@gitlab/ui": "^1.11.0",
"@gitlab/svgs": "^1.35.0",
=======
"@gitlab/svgs": "^1.38.0",
"@gitlab/ui": "^1.11.0",
>>>>>>> upstream/master
"autosize": "^4.0.0",
"axios": "^0.17.1",
"babel-loader": "^8.0.4",
......
......@@ -127,7 +127,10 @@ describe Projects::DeployKeysController do
expect do
put :enable, id: deploy_key.id, namespace_id: project.namespace, project_id: project
end.to change { DeployKeysProject.count }.by(1)
<<<<<<< HEAD
.and change { AuditEvent.count }.by(1) ## EE only
=======
>>>>>>> upstream/master
expect(DeployKeysProject.where(project_id: project.id, deploy_key_id: deploy_key.id).count).to eq(1)
expect(response).to have_http_status(302)
......@@ -193,7 +196,10 @@ describe Projects::DeployKeysController do
expect do
put :disable, id: deploy_key.id, namespace_id: project.namespace, project_id: project
end.to change { DeployKey.count }.by(-1)
<<<<<<< HEAD
.and change { AuditEvent.count }.by(1) ## EE only
=======
>>>>>>> upstream/master
expect(response).to have_http_status(302)
expect(response).to redirect_to(namespace_project_settings_repository_path(anchor: 'js-deploy-keys-settings'))
......
......@@ -20,7 +20,7 @@ describe 'Dropdown emoji', :js do
end
def dropdown_emoji_size
page.all('#js-dropdown-my-reaction .filter-dropdown .filter-dropdown-item').size
all('gl-emoji[data-name]').size
end
def click_emoji(text)
......
......@@ -67,6 +67,16 @@ describe AuthHelper do
end
end
describe 'form_based_auth_provider_has_active_class?' do
it 'selects main LDAP server' do
allow(helper).to receive(:auth_providers) { [:twitter, :ldapprimary, :ldapsecondary, :kerberos] }
expect(helper.form_based_auth_provider_has_active_class?(:twitter)).to be(false)
expect(helper.form_based_auth_provider_has_active_class?(:ldapprimary)).to be(true)
expect(helper.form_based_auth_provider_has_active_class?(:ldapsecondary)).to be(false)
expect(helper.form_based_auth_provider_has_active_class?(:kerberos)).to be(false)
end
end
describe 'enabled_button_based_providers' do
before do
allow(helper).to receive(:auth_providers) { [:twitter, :github] }
......
......@@ -41,7 +41,7 @@ describe('Deployment component', () => {
describe('', () => {
beforeEach(() => {
vm = mountComponent(Component, { deployment: { ...deploymentMockData } });
vm = mountComponent(Component, { deployment: { ...deploymentMockData }, showMetrics: true });
});
describe('deployTimeago', () => {
......@@ -174,11 +174,31 @@ describe('Deployment component', () => {
});
});
describe('with showMetrics enabled', () => {
beforeEach(() => {
vm = mountComponent(Component, { deployment: { ...deploymentMockData }, showMetrics: true });
});
it('shows metrics', () => {
expect(vm.$el).toContainElement('.js-mr-memory-usage');
});
});
describe('with showMetrics disabled', () => {
beforeEach(() => {
vm = mountComponent(Component, { deployment: { ...deploymentMockData }, showMetrics: false });
});
it('hides metrics', () => {
expect(vm.$el).not.toContainElement('.js-mr-memory-usage');
});
});
describe('without changes', () => {
beforeEach(() => {
delete deploymentMockData.changes;
vm = mountComponent(Component, { deployment: { ...deploymentMockData } });
vm = mountComponent(Component, { deployment: { ...deploymentMockData }, showMetrics: true });
});
it('renders the link to the review app without dropdown', () => {
......@@ -192,6 +212,7 @@ describe('Deployment component', () => {
beforeEach(() => {
vm = mountComponent(Component, {
deployment: Object.assign({}, deploymentMockData, { status: 'running' }),
showMetrics: true,
});
});
......@@ -208,6 +229,7 @@ describe('Deployment component', () => {
beforeEach(() => {
vm = mountComponent(Component, {
deployment: Object.assign({}, deploymentMockData, { status: 'success' }),
showMetrics: true,
});
});
......@@ -220,6 +242,7 @@ describe('Deployment component', () => {
beforeEach(() => {
vm = mountComponent(Component, {
deployment: Object.assign({}, deploymentMockData, { status: 'failed' }),
showMetrics: true,
});
});
......
......@@ -4,6 +4,9 @@ require 'spec_helper'
describe Gitlab::PrivateCommitEmail do
let(:hostname) { Gitlab::CurrentSettings.current_application_settings.commit_email_hostname }
let(:id) { 1 }
let(:valid_email) { "#{id}-foo@#{hostname}" }
let(:invalid_email) { "#{id}-foo@users.noreply.bar.com" }
context '.regex' do
subject { described_class.regex }
......@@ -16,18 +19,25 @@ describe Gitlab::PrivateCommitEmail do
end
context '.user_id_for_email' do
let(:id) { 1 }
it 'parses user id from email' do
email = "#{id}-foo@#{hostname}"
expect(described_class.user_id_for_email(email)).to eq(id)
expect(described_class.user_id_for_email(valid_email)).to eq(id)
end
it 'returns nil on invalid commit email' do
email = "#{id}-foo@users.noreply.bar.com"
expect(described_class.user_id_for_email(invalid_email)).to be_nil
end
end
context '.user_ids_for_email' do
it 'returns deduplicated user IDs for each valid email' do
result = described_class.user_ids_for_emails([valid_email, valid_email, invalid_email])
expect(result).to eq([id])
end
expect(described_class.user_id_for_email(email)).to be_nil
it 'returns an empty array with no valid emails' do
result = described_class.user_ids_for_emails([invalid_email])
expect(result).to eq([])
end
end
......
......@@ -72,6 +72,7 @@ describe Commit do
context 'using eager loading' do
let!(:alice) { create(:user, email: 'alice@example.com') }
let!(:bob) { create(:user, email: 'hunter2@example.com') }
let!(:jeff) { create(:user) }
let(:alice_commit) do
described_class.new(RepoHelpers.sample_commit, project).tap do |c|
......@@ -93,7 +94,14 @@ describe Commit do
end
end
let!(:commits) { [alice_commit, bob_commit, eve_commit] }
let(:jeff_commit) do
# The commit for Jeff uses his private commit email
described_class.new(RepoHelpers.sample_commit, project).tap do |c|
c.author_email = jeff.private_commit_email
end
end
let!(:commits) { [alice_commit, bob_commit, eve_commit, jeff_commit] }
before do
create(:email, user: bob, email: 'bob@example.com')
......@@ -125,6 +133,20 @@ describe Commit do
expect(bob_commit.author).to eq(bob)
end
it "preloads the authors for Commits using a User's private commit Email" do
commits.each(&:lazy_author)
expect(jeff_commit.author).to eq(jeff)
end
it "preloads the authors for Commits using a User's outdated private commit Email" do
jeff.update!(username: 'new-username')
commits.each(&:lazy_author)
expect(jeff_commit.author).to eq(jeff)
end
it 'sets the author to Nil if an author could not be found for a Commit' do
commits.each(&:lazy_author)
......
......@@ -48,12 +48,12 @@ describe ChatMessage::PushMessage do
'test.user pushed to branch [master](http://url.com/commits/master) of [project_name](http://url.com) ([Compare changes](http://url.com/compare/before...after))')
expect(subject.attachments).to eq(
"[abcdefgh](http://url1.com): message1 - author1\n\n[12345678](http://url2.com): message2 - author2")
expect(subject.activity).to eq({
title: 'test.user pushed to branch',
expect(subject.activity).to eq(
title: 'test.user pushed to branch [master](http://url.com/commits/master)',
subtitle: 'in [project_name](http://url.com)',
text: '[Compare changes](http://url.com/compare/before...after)',
image: 'http://someavatar.com'
})
)
end
end
end
......@@ -89,12 +89,53 @@ describe ChatMessage::PushMessage do
expect(subject.pretext).to eq(
'test.user pushed new tag [new_tag](http://url.com/commits/new_tag) to [project_name](http://url.com)')
expect(subject.attachments).to be_empty
expect(subject.activity).to eq({
title: 'test.user created tag',
expect(subject.activity).to eq(
title: 'test.user pushed new tag [new_tag](http://url.com/commits/new_tag)',
subtitle: 'in [project_name](http://url.com)',
text: '[Compare changes](http://url.com/compare/0000000000000000000000000000000000000000...after)',
image: 'http://someavatar.com'
})
)
end
end
end
context 'removed tag' do
let(:args) do
{
after: Gitlab::Git::BLANK_SHA,
before: 'before',
project_name: 'project_name',
ref: 'refs/tags/new_tag',
user_name: 'test.user',
user_avatar: 'http://someavatar.com',
project_url: 'http://url.com'
}
end
context 'without markdown' do
it 'returns a message regarding removal of tags' do
expect(subject.pretext).to eq('test.user removed tag ' \
'new_tag from ' \
'<http://url.com|project_name>')
expect(subject.attachments).to be_empty
end
end
context 'with markdown' do
before do
args[:markdown] = true
end
it 'returns a message regarding removal of tags' do
expect(subject.pretext).to eq(
'test.user removed tag new_tag from [project_name](http://url.com)')
expect(subject.attachments).to be_empty
expect(subject.activity).to eq(
title: 'test.user removed tag new_tag',
subtitle: 'in [project_name](http://url.com)',
text: '[Compare changes](http://url.com/compare/before...0000000000000000000000000000000000000000)',
image: 'http://someavatar.com'
)
end
end
end
......@@ -122,12 +163,12 @@ describe ChatMessage::PushMessage do
expect(subject.pretext).to eq(
'test.user pushed new branch [master](http://url.com/commits/master) to [project_name](http://url.com)')
expect(subject.attachments).to be_empty
expect(subject.activity).to eq({
title: 'test.user created branch',
expect(subject.activity).to eq(
title: 'test.user pushed new branch [master](http://url.com/commits/master)',
subtitle: 'in [project_name](http://url.com)',
text: '[Compare changes](http://url.com/compare/0000000000000000000000000000000000000000...after)',
image: 'http://someavatar.com'
})
)
end
end
end
......@@ -154,12 +195,12 @@ describe ChatMessage::PushMessage do
expect(subject.pretext).to eq(
'test.user removed branch master from [project_name](http://url.com)')
expect(subject.attachments).to be_empty
expect(subject.activity).to eq({
title: 'test.user removed branch',
expect(subject.activity).to eq(
title: 'test.user removed branch master',
subtitle: 'in [project_name](http://url.com)',
text: '[Compare changes](http://url.com/compare/before...0000000000000000000000000000000000000000)',
image: 'http://someavatar.com'
})
)
end
end
end
......
......@@ -3378,6 +3378,14 @@ describe Project do
it 'does not flag as read-only' do
expect { project.migrate_to_hashed_storage! }.not_to change { project.repository_read_only }
end
context 'when partially migrated' do
it 'returns true' do
project = create(:project, storage_version: 1, skip_disk_validation: true)
expect(project.migrate_to_hashed_storage!).to be_truthy
end
end
end
end
......
......@@ -1202,6 +1202,22 @@ describe User do
expect(described_class.by_any_email(user.email, confirmed: true)).to eq([user])
end
it 'finds user through a private commit email' do
user = create(:user)
private_email = user.private_commit_email
expect(described_class.by_any_email(private_email)).to eq([user])
expect(described_class.by_any_email(private_email, confirmed: true)).to eq([user])
end
it 'finds user through a private commit email in an array' do
user = create(:user)
private_email = user.private_commit_email
expect(described_class.by_any_email([private_email])).to eq([user])
expect(described_class.by_any_email([private_email], confirmed: true)).to eq([user])
end
end
describe '.search' do
......@@ -1529,7 +1545,12 @@ describe User do
email_unconfirmed = create :email, user: user
user.reload
expect(user.all_emails).to match_array([user.email, email_unconfirmed.email, email_confirmed.email])
expect(user.all_emails).to contain_exactly(
user.email,
user.private_commit_email,
email_unconfirmed.email,
email_confirmed.email
)
end
end
......@@ -1540,7 +1561,11 @@ describe User do
email_confirmed = create :email, user: user, confirmed_at: Time.now
create :email, user: user
expect(user.verified_emails).to match_array([user.email, user.private_commit_email, email_confirmed.email])
expect(user.verified_emails).to contain_exactly(
user.email,
user.private_commit_email,
email_confirmed.email
)
end
end
......@@ -1560,6 +1585,14 @@ describe User do
expect(user.verified_email?(user.private_commit_email)).to be_truthy
end
it 'returns true for an outdated private commit email' do
old_email = user.private_commit_email
user.update!(username: 'changed-username')
expect(user.verified_email?(old_email)).to be_truthy
end
it 'returns false when the email is not verified/confirmed' do
email_unconfirmed = create :email, user: user
user.reload
......
......@@ -67,9 +67,8 @@
@babel/template,7.1.2,MIT
@babel/traverse,7.1.0,MIT
@babel/types,7.1.2,MIT
@gitlab-org/gitlab-svgs,1.32.0,MIT
@gitlab-org/gitlab-ui,1.10.0,MIT
@gitlab/svgs,1.35.0,MIT
@gitlab/ui,1.11.0,MIT
@sindresorhus/is,0.7.0,MIT
@types/jquery,2.0.48,MIT
@vue/component-compiler-utils,2.2.0,MIT
......
......@@ -629,10 +629,25 @@
eslint-plugin-promise "^4.0.1"
eslint-plugin-vue "^5.0.0-beta.3"
"@gitlab/svgs@^1.35.0":
version "1.35.0"
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.35.0.tgz#01b6a0948bb3897fbbac9f50ce23c559c514ea0e"
integrity sha512-XKrTniSYKG5U8+8ZqDJqoW8ORahuPBfHrfsC1dHBPvo1xA/QGJxlpUdeqSFw2O19h481ut4yW1dF+OFpIa/mrw==
"@gitlab/svgs@^1.38.0":
version "1.38.0"
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.38.0.tgz#e2f6e73379d60c7c63af4df8242a94c4671a1dfe"
integrity sha512-Mzv6PxVbWEPvvMgXHaGxk8UE1Gard2gifca6loLgfLH7BtjXfESiZyJdQkkTSeBYp5MoqQa88Kw+vJYobwjsSw==
"@gitlab/ui@^1.11.0":
version "1.11.0"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-1.11.0.tgz#b771c2c3d627cf9efbe98c71ee5739624f2ff51f"
integrity sha512-hGMHM45kcv9725R6G+n/HxvF3KfVb9oBGRNf1+4n3xAGmtXJ2NlPdIXIsDaye3EeVF9PTOtjLuaqrcp6AGNqZg==
dependencies:
babel-standalone "^6.26.0"
bootstrap-vue "^2.0.0-rc.11"
copy-to-clipboard "^3.0.8"
highlight.js "^9.13.1"
js-beautify "^1.8.8"
lodash "^4.17.11"
url-search-params-polyfill "^5.0.0"
vue "^2.5.16"
vue-loader "^15.4.2"
"@gitlab/ui@^1.11.0":
version "1.11.0"
......
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