Commit 5e0e0974 authored by Stan Hu's avatar Stan Hu

Merge branch 'ce-to-ee-2018-11-19' into 'master'

CE upstream - 2018-11-19 17:21 UTC

Closes gitlab-ce#54093, gitlab-ui#65, and gitlab-ui#95

See merge request gitlab-org/gitlab-ee!8510
parents afa489ea f562a3e6
...@@ -917,6 +917,39 @@ qa:selectors: ...@@ -917,6 +917,39 @@ qa:selectors:
- bundle install - bundle install
- bundle exec bin/qa Test::Sanity::Selectors - 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: coverage:
# Don't include dedicated-no-docs-no-db-pull-cache-job here since we need to # 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 # download artifacts from all the rspec jobs instead of from setup-test-env only
...@@ -966,6 +999,8 @@ pages: ...@@ -966,6 +999,8 @@ pages:
- mv coverage-javascript/ public/coverage-javascript/ || true - mv coverage-javascript/ public/coverage-javascript/ || true
- mv eslint-report.html public/ || true - mv eslint-report.html public/ || true
- mv webpack-report/ public/webpack-report/ || 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: artifacts:
paths: paths:
- public - public
......
...@@ -64,7 +64,7 @@ Some features might be simple enough that they only involve one Component, while ...@@ -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. more complex features could involve multiple or even all.
Example (from https://gitlab.com/gitlab-org/gitlab-ce/issues/50353): Example (from https://gitlab.com/gitlab-org/gitlab-ce/issues/50353):
* Respository is * Repository is
* Intuitive * Intuitive
* It's easy to select the desired file template * It's easy to select the desired file template
* It doesn't require unnecessary actions to save the change * 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 ...@@ -93,4 +93,4 @@ When adding new automated tests, please keep [testing levels](https://docs.gitla
in mind. in mind.
--> -->
/label ~Quality ~"test plan" /label ~Quality ~"test plan"
\ No newline at end of file
...@@ -14,6 +14,9 @@ source 'https://rubygems.org' ...@@ -14,6 +14,9 @@ source 'https://rubygems.org'
gem 'rails', gem_versions['rails'] gem 'rails', gem_versions['rails']
gem 'rails-deprecated_sanitizer', '~> 1.0.3' 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 # Responders respond_to and respond_with
gem 'responders', '~> 2.0' gem 'responders', '~> 2.0'
...@@ -146,7 +149,7 @@ gem 'rdoc', '~> 6.0' ...@@ -146,7 +149,7 @@ gem 'rdoc', '~> 6.0'
gem 'org-ruby', '~> 0.9.12' gem 'org-ruby', '~> 0.9.12'
gem 'creole', '~> 0.5.0' gem 'creole', '~> 0.5.0'
gem 'wikicloth', '0.8.1' gem 'wikicloth', '0.8.1'
gem 'asciidoctor', '~> 1.5.6' gem 'asciidoctor', '~> 1.5.8'
gem 'asciidoctor-plantuml', '0.0.8' gem 'asciidoctor-plantuml', '0.0.8'
gem 'rouge', '~> 3.1' gem 'rouge', '~> 3.1'
gem 'truncato', '~> 0.7.9' gem 'truncato', '~> 0.7.9'
...@@ -236,7 +239,7 @@ gem 'slack-notifier', '~> 1.5.1' ...@@ -236,7 +239,7 @@ gem 'slack-notifier', '~> 1.5.1'
gem 'hangouts-chat', '~> 0.0.5' gem 'hangouts-chat', '~> 0.0.5'
# Asana integration # Asana integration
gem 'asana', '~> 0.6.0' gem 'asana', '~> 0.8.1'
# FogBugz integration # FogBugz integration
gem 'ruby-fogbugz', '~> 0.2.1' gem 'ruby-fogbugz', '~> 0.2.1'
......
...@@ -53,12 +53,12 @@ GEM ...@@ -53,12 +53,12 @@ GEM
aes_key_wrap (1.0.1) aes_key_wrap (1.0.1)
akismet (2.0.0) akismet (2.0.0)
arel (7.1.4) arel (7.1.4)
asana (0.6.0) asana (0.8.1)
faraday (~> 0.9) faraday (~> 0.9)
faraday_middleware (~> 0.9) faraday_middleware (~> 0.9)
faraday_middleware-multi_json (~> 0.0) faraday_middleware-multi_json (~> 0.0)
oauth2 (~> 1.0) oauth2 (~> 1.0)
asciidoctor (1.5.6.2) asciidoctor (1.5.8)
asciidoctor-plantuml (0.0.8) asciidoctor-plantuml (0.0.8)
asciidoctor (~> 1.5) asciidoctor (~> 1.5)
ast (2.4.0) ast (2.4.0)
...@@ -498,6 +498,7 @@ GEM ...@@ -498,6 +498,7 @@ GEM
mustermann-grape (1.0.0) mustermann-grape (1.0.0)
mustermann (~> 1.0.0) mustermann (~> 1.0.0)
mysql2 (0.4.10) mysql2 (0.4.10)
nakayoshi_fork (0.0.4)
net-ldap (0.16.0) net-ldap (0.16.0)
net-ntp (2.1.3) net-ntp (2.1.3)
net-ssh (5.0.1) net-ssh (5.0.1)
...@@ -970,8 +971,8 @@ DEPENDENCIES ...@@ -970,8 +971,8 @@ DEPENDENCIES
acts-as-taggable-on (~> 5.0) acts-as-taggable-on (~> 5.0)
addressable (~> 2.5.2) addressable (~> 2.5.2)
akismet (~> 2.0) akismet (~> 2.0)
asana (~> 0.6.0) asana (~> 0.8.1)
asciidoctor (~> 1.5.6) asciidoctor (~> 1.5.8)
asciidoctor-plantuml (= 0.0.8) asciidoctor-plantuml (= 0.0.8)
attr_encrypted (~> 3.1.0) attr_encrypted (~> 3.1.0)
awesome_print awesome_print
...@@ -1087,6 +1088,7 @@ DEPENDENCIES ...@@ -1087,6 +1088,7 @@ DEPENDENCIES
mini_magick mini_magick
minitest (~> 5.7.0) minitest (~> 5.7.0)
mysql2 (~> 0.4.10) mysql2 (~> 0.4.10)
nakayoshi_fork (~> 0.0.4)
net-ldap net-ldap
net-ntp net-ntp
net-ssh (~> 5.0) net-ssh (~> 5.0)
......
...@@ -50,12 +50,12 @@ GEM ...@@ -50,12 +50,12 @@ GEM
aes_key_wrap (1.0.1) aes_key_wrap (1.0.1)
akismet (2.0.0) akismet (2.0.0)
arel (6.0.4) arel (6.0.4)
asana (0.6.0) asana (0.8.1)
faraday (~> 0.9) faraday (~> 0.9)
faraday_middleware (~> 0.9) faraday_middleware (~> 0.9)
faraday_middleware-multi_json (~> 0.0) faraday_middleware-multi_json (~> 0.0)
oauth2 (~> 1.0) oauth2 (~> 1.0)
asciidoctor (1.5.6.2) asciidoctor (1.5.8)
asciidoctor-plantuml (0.0.8) asciidoctor-plantuml (0.0.8)
asciidoctor (~> 1.5) asciidoctor (~> 1.5)
ast (2.4.0) ast (2.4.0)
...@@ -495,6 +495,7 @@ GEM ...@@ -495,6 +495,7 @@ GEM
mustermann-grape (1.0.0) mustermann-grape (1.0.0)
mustermann (~> 1.0.0) mustermann (~> 1.0.0)
mysql2 (0.4.10) mysql2 (0.4.10)
nakayoshi_fork (0.0.4)
net-ldap (0.16.0) net-ldap (0.16.0)
net-ntp (2.1.3) net-ntp (2.1.3)
net-ssh (5.0.1) net-ssh (5.0.1)
...@@ -961,8 +962,8 @@ DEPENDENCIES ...@@ -961,8 +962,8 @@ DEPENDENCIES
acts-as-taggable-on (~> 5.0) acts-as-taggable-on (~> 5.0)
addressable (~> 2.5.2) addressable (~> 2.5.2)
akismet (~> 2.0) akismet (~> 2.0)
asana (~> 0.6.0) asana (~> 0.8.1)
asciidoctor (~> 1.5.6) asciidoctor (~> 1.5.8)
asciidoctor-plantuml (= 0.0.8) asciidoctor-plantuml (= 0.0.8)
attr_encrypted (~> 3.1.0) attr_encrypted (~> 3.1.0)
awesome_print awesome_print
...@@ -1078,6 +1079,7 @@ DEPENDENCIES ...@@ -1078,6 +1079,7 @@ DEPENDENCIES
mini_magick mini_magick
minitest (~> 5.7.0) minitest (~> 5.7.0)
mysql2 (~> 0.4.10) mysql2 (~> 0.4.10)
nakayoshi_fork (~> 0.0.4)
net-ldap net-ldap
net-ntp net-ntp
net-ssh (~> 5.0) net-ssh (~> 5.0)
......
...@@ -69,10 +69,13 @@ export default class DropdownEmoji extends FilteredSearchDropdown { ...@@ -69,10 +69,13 @@ export default class DropdownEmoji extends FilteredSearchDropdown {
// Replace empty gl-emoji tag to real content // Replace empty gl-emoji tag to real content
const dropdownItems = [...this.dropdown.querySelectorAll('.filter-dropdown-item')]; const dropdownItems = [...this.dropdown.querySelectorAll('.filter-dropdown-item')];
dropdownItems.forEach(dropdownItem => { dropdownItems.forEach(dropdownItem => {
const name = dropdownItem.querySelector('.js-data-value').innerText; const valueElement = dropdownItem.querySelector('.js-data-value');
const emojiTag = this.glEmojiTag(name); if (valueElement !== null) {
const emojiElement = dropdownItem.querySelector('gl-emoji'); const name = valueElement.innerText;
emojiElement.outerHTML = emojiTag; const emojiTag = this.glEmojiTag(name);
const emojiElement = dropdownItem.querySelector('gl-emoji');
emojiElement.outerHTML = emojiTag;
}
}); });
} }
......
...@@ -33,6 +33,10 @@ export default { ...@@ -33,6 +33,10 @@ export default {
type: Object, type: Object,
required: true, required: true,
}, },
showMetrics: {
type: Boolean,
required: true,
},
}, },
deployedTextMap: { deployedTextMap: {
running: __('Deploying to'), running: __('Deploying to'),
...@@ -74,6 +78,9 @@ export default { ...@@ -74,6 +78,9 @@ export default {
shouldRenderDropdown() { shouldRenderDropdown() {
return this.deployment.changes && this.deployment.changes.length > 0; return this.deployment.changes && this.deployment.changes.length > 0;
}, },
showMemoryUsage() {
return this.hasMetrics && this.showMetrics;
},
}, },
methods: { methods: {
stopEnvironment() { stopEnvironment() {
...@@ -136,7 +143,7 @@ export default { ...@@ -136,7 +143,7 @@ export default {
{{ deployTimeago }} {{ deployTimeago }}
</span> </span>
<memory-usage <memory-usage
v-if="hasMetrics" v-if="showMemoryUsage"
:metrics-url="deployment.metrics_url" :metrics-url="deployment.metrics_url"
:metrics-monitoring-url="deployment.metrics_monitoring_url" :metrics-monitoring-url="deployment.metrics_monitoring_url"
/> />
......
...@@ -313,6 +313,7 @@ export default { ...@@ -313,6 +313,7 @@ export default {
:key="`pre-merge-deploy-${deployment.id}`" :key="`pre-merge-deploy-${deployment.id}`"
class="js-pre-merge-deploy" class="js-pre-merge-deploy"
:deployment="deployment" :deployment="deployment"
:show-metrics="false"
/> />
<div class="mr-section-container"> <div class="mr-section-container">
<grouped-test-reports-app <grouped-test-reports-app
...@@ -367,6 +368,7 @@ export default { ...@@ -367,6 +368,7 @@ export default {
v-for="postMergeDeployment in mr.postMergeDeployments" v-for="postMergeDeployment in mr.postMergeDeployments"
:key="`post-merge-deploy-${postMergeDeployment.id}`" :key="`post-merge-deploy-${postMergeDeployment.id}`"
:deployment="postMergeDeployment" :deployment="postMergeDeployment"
:show-metrics="true"
class="js-post-deployment" class="js-post-deployment"
/> />
</template> </template>
......
...@@ -230,24 +230,13 @@ class Commit ...@@ -230,24 +230,13 @@ class Commit
def lazy_author def lazy_author
BatchLoader.for(author_email.downcase).batch do |emails, loader| BatchLoader.for(author_email.downcase).batch do |emails, loader|
# A Hash that maps user Emails to the corresponding User objects. The users = User.by_any_email(emails).includes(:emails)
# Emails at this point are the _primary_ Emails of the Users.
users_for_emails = User emails.each do |email|
.by_any_email(emails) user = users.find { |u| u.any_email?(email) }
.each_with_object({}) { |user, hash| hash[user.email] = user }
loader.call(email, user)
users_for_ids = users_for_emails end
.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) }
end end
end end
......
...@@ -1965,7 +1965,7 @@ class Project < ActiveRecord::Base ...@@ -1965,7 +1965,7 @@ class Project < ActiveRecord::Base
end end
def migrate_to_hashed_storage! def migrate_to_hashed_storage!
return if hashed_storage?(:repository) return unless storage_upgradable?
update!(repository_read_only: true) update!(repository_read_only: true)
......
...@@ -26,16 +26,8 @@ module ChatMessage ...@@ -26,16 +26,8 @@ module ChatMessage
end end
def activity 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}", subtitle: "in #{project_link}",
text: compare_link, text: compare_link,
image: user_avatar image: user_avatar
...@@ -44,32 +36,21 @@ module ChatMessage ...@@ -44,32 +36,21 @@ module ChatMessage
private 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 def message
if new_branch? humanized_action
new_branch_message
elsif removed_branch?
removed_branch_message
else
push_message
end
end end
def format(string) def format(string)
Slack::Notifier::LinkFormatter.format(string) Slack::Notifier::LinkFormatter.format(string)
end 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 def commit_messages
commits.map { |commit| compose_commit_message(commit) }.join("\n\n") commits.map { |commit| compose_commit_message(commit) }.join("\n\n")
end end
...@@ -115,6 +96,16 @@ module ChatMessage ...@@ -115,6 +96,16 @@ module ChatMessage
"[Compare changes](#{compare_url})" "[Compare changes](#{compare_url})"
end 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 def attachment_color
'#345' '#345'
end end
......
...@@ -349,20 +349,28 @@ class User < ActiveRecord::Base ...@@ -349,20 +349,28 @@ class User < ActiveRecord::Base
def find_by_any_email(email, confirmed: false) def find_by_any_email(email, confirmed: false)
return unless email return unless email
downcased = email.downcase by_any_email(email, confirmed: confirmed).take
find_by_private_commit_email(downcased) || by_any_email(downcased, confirmed: confirmed).take
end end
# Returns a relation containing all the users for the given Email address # Returns a relation containing all the users for the given email addresses
def by_any_email(email, confirmed: false) #
users = where(email: email) # @param emails [String, Array<String>] email addresses to check
users = users.confirmed if confirmed # @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 }) from_emails = joins(:emails).where(emails: { email: emails })
emails = emails.confirmed if confirmed 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 end
def find_by_private_commit_email(email) def find_by_private_commit_email(email)
...@@ -1031,6 +1039,7 @@ class User < ActiveRecord::Base ...@@ -1031,6 +1039,7 @@ class User < ActiveRecord::Base
def all_emails def all_emails
all_emails = [] all_emails = []
all_emails << email unless temp_oauth_email? all_emails << email unless temp_oauth_email?
all_emails << private_commit_email
all_emails.concat(emails.map(&:email)) all_emails.concat(emails.map(&:email))
all_emails all_emails
end end
...@@ -1043,16 +1052,24 @@ class User < ActiveRecord::Base ...@@ -1043,16 +1052,24 @@ class User < ActiveRecord::Base
verified_emails verified_emails
end 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) def verified_email?(check_email)
downcased = check_email.downcase downcased = check_email.downcase
if email == downcased # handle the outdated private commit email case
primary_email_verified? return true if persisted? &&
else id == Gitlab::PrivateCommitEmail.user_id_for_email(downcased)
user_id = Gitlab::PrivateCommitEmail.user_id_for_email(downcased)
user_id == id || emails.confirmed.where(email: downcased).exists? verified_emails.include?(check_email.downcase)
end
end end
def hook_attrs def hook_attrs
......
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
.login-body .login-body
= render 'devise/sessions/new_base' = render 'devise/sessions/new_base'
= render_if_exists 'devise/sessions/new_smartcard'
- elsif password_authentication_enabled_for_web? - elsif password_authentication_enabled_for_web?
.login-box.tab-pane.active{ id: 'login-pane', role: 'tabpanel' } .login-box.tab-pane.active{ id: 'login-pane', role: 'tabpanel' }
.login-body .login-body
......
---
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 @@ ...@@ -544,13 +544,6 @@
:why: https://github.com/xtuc/webassemblyjs/blob/master/LICENSE :why: https://github.com/xtuc/webassemblyjs/blob/master/LICENSE
:versions: [] :versions: []
:when: 2018-06-08 05:30:56.764116000 Z :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 - - :approve
- lz-string - lz-string
- :who: Phil Hughes - :who: Phil Hughes
......
...@@ -685,7 +685,7 @@ cache, queues, and shared_state. To make this work with Sentinel: ...@@ -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 1. Note that for each persistence class, GitLab will default to using the
configuration specified in `gitlab_rails['redis_sentinels']` unless 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, 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']` 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. 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. ...@@ -299,7 +299,7 @@ runners will not use regular runners, they must be tagged accordingly.
[jobs]: #jobs [jobs]: #jobs
[jobs-yaml]: yaml/README.md#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 [env-manual]: environments.md#manually-deploying-to-environments
[stages]: yaml/README.md#stages [stages]: yaml/README.md#stages
[runners]: runners/README.md [runners]: runners/README.md
......
...@@ -17,7 +17,7 @@ There are two places defined variables can be used. On the: ...@@ -17,7 +17,7 @@ There are two places defined variables can be used. On the:
| Definition | Can be expanded? | Expansion place | Description | | 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> | | `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) | | `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) | | `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: ...@@ -1770,7 +1770,7 @@ stages:
production: production:
script: script:
- install_depedencies - install_dependencies
- deploy - deploy
- notify_owner - notify_owner
``` ```
......
...@@ -33,7 +33,7 @@ You can follow the progress on that [in the issue on our issue tracker](https:// ...@@ -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 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 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 for enabling for the `gitlab-org` group first, while the rest of the users
aren't impacted. aren't impacted.
......
...@@ -24,7 +24,7 @@ Review Apps are automatically deployed by each pipeline, both in ...@@ -24,7 +24,7 @@ Review Apps are automatically deployed by each pipeline, both in
[`scripts/review_apps/review-apps.sh`][review-apps.sh] [`scripts/review_apps/review-apps.sh`][review-apps.sh]
- These scripts are basically - These scripts are basically
[our official Auto DevOps scripts][Auto-DevOps.gitlab-ci.yml] where the [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]. [`CNG-mirror` project's registry][cng-mirror-registry].
- Since we're using [the official GitLab Helm chart][helm-chart], this means - 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 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 ...@@ -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 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 `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 **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:** **Additional notes:**
......
...@@ -104,7 +104,7 @@ features of GitLab work with MySQL/MariaDB: ...@@ -104,7 +104,7 @@ features of GitLab work with MySQL/MariaDB:
1. MySQL support for subgroups was [dropped with GitLab 9.3][post]. 1. MySQL support for subgroups was [dropped with GitLab 9.3][post].
See [issue #30472][30472] for more information. See [issue #30472][30472] for more information.
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. 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. [Zero downtime migrations](../update/README.md#upgrading-without-downtime) do not work with MySQL.
1. [Database load balancing](../administration/database_load_balancing.md) is 1. [Database load balancing](../administration/database_load_balancing.md) is
supported only for PostgreSQL. supported only for PostgreSQL.
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. 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/).
......
...@@ -657,6 +657,8 @@ also be customized, and you can easily use a [custom buildpack](#custom-buildpac ...@@ -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. | | `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. | | `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. | | `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:** TIP: **Tip:**
Set up the replica variables using a Set up the replica variables using a
......
...@@ -17,6 +17,7 @@ the [GitHub rake task](../../../administration/raketasks/github_import.md) to im ...@@ -17,6 +17,7 @@ the [GitHub rake task](../../../administration/raketasks/github_import.md) to im
GitHub without the constraints of a Sidekiq worker. GitHub without the constraints of a Sidekiq worker.
The following aspects of a project are imported: The following aspects of a project are imported:
* Repository description (GitLab.com & 7.7+) * Repository description (GitLab.com & 7.7+)
* Git repository data (GitLab.com & 7.7+) * Git repository data (GitLab.com & 7.7+)
* Issues (GitLab.com & 7.7+) * Issues (GitLab.com & 7.7+)
......
...@@ -201,11 +201,11 @@ administrator to do so. ...@@ -201,11 +201,11 @@ administrator to do so.
### Adding patches when creating a merge request via e-mail ### 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 You can add commits to the merge request being created by adding
patches as attachments to the email, all attachments with a filename patches as attachments to the email. All attachments with a filename
ending in `.patch` will be considered patches. The patches will be processed ending in `.patch` will be considered patches and they will be processed
ordered by name. ordered by name.
The combined size of the patches can be 2MB. 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. ...@@ -218,7 +218,7 @@ branch already exists, the patches will be applied on top of it.
## Find the merge request that introduced a change ## 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 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. 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 ...@@ -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 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 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. - **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.
......
...@@ -205,6 +205,7 @@ export default { ...@@ -205,6 +205,7 @@ export default {
:key="`pre-merge-deploy-${deployment.id}`" :key="`pre-merge-deploy-${deployment.id}`"
class="js-pre-merge-deploy" class="js-pre-merge-deploy"
:deployment="deployment" :deployment="deployment"
:show-metrics="false"
/> />
<div class="mr-section-container"> <div class="mr-section-container">
<mr-widget-approvals <mr-widget-approvals
...@@ -320,6 +321,7 @@ export default { ...@@ -320,6 +321,7 @@ export default {
v-for="postMergeDeployment in mr.postMergeDeployments" v-for="postMergeDeployment in mr.postMergeDeployments"
:key="`post-merge-deploy-${postMergeDeployment.id}`" :key="`post-merge-deploy-${postMergeDeployment.id}`"
:deployment="postMergeDeployment" :deployment="postMergeDeployment"
:show-metrics="true"
class="js-post-deployment" class="js-post-deployment"
/> />
</template> </template>
......
...@@ -19,6 +19,15 @@ ...@@ -19,6 +19,15 @@
# * review: REVIEW_DISABLED # * review: REVIEW_DISABLED
# * stop_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 # In order to deploy, you must have a Kubernetes cluster configured either
# via a project integration, or via group/project variables. # via a project integration, or via group/project variables.
# AUTO_DEVOPS_DOMAIN must also be set as a variable at the group or project # AUTO_DEVOPS_DOMAIN must also be set as a variable at the group or project
...@@ -173,6 +182,29 @@ sast: ...@@ -173,6 +182,29 @@ sast:
except: except:
variables: variables:
- $SAST_DISABLED - $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: dependency_scanning:
stage: test stage: test
......
...@@ -18,6 +18,10 @@ module Gitlab ...@@ -18,6 +18,10 @@ module Gitlab
match[:id].to_i match[:id].to_i
end end
def user_ids_for_emails(emails)
emails.map { |email| user_id_for_email(email) }.compact.uniq
end
def for_user(user) def for_user(user)
hostname = Gitlab::CurrentSettings.current_application_settings.commit_email_hostname hostname = Gitlab::CurrentSettings.current_application_settings.commit_email_hostname
......
...@@ -20,7 +20,7 @@ describe 'Dropdown emoji', :js do ...@@ -20,7 +20,7 @@ describe 'Dropdown emoji', :js do
end end
def dropdown_emoji_size def dropdown_emoji_size
page.all('#js-dropdown-my-reaction .filter-dropdown .filter-dropdown-item').size all('gl-emoji[data-name]').size
end end
def click_emoji(text) def click_emoji(text)
......
...@@ -67,6 +67,16 @@ describe AuthHelper do ...@@ -67,6 +67,16 @@ describe AuthHelper do
end end
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 describe 'enabled_button_based_providers' do
before do before do
allow(helper).to receive(:auth_providers) { [:twitter, :github] } allow(helper).to receive(:auth_providers) { [:twitter, :github] }
......
...@@ -41,7 +41,7 @@ describe('Deployment component', () => { ...@@ -41,7 +41,7 @@ describe('Deployment component', () => {
describe('', () => { describe('', () => {
beforeEach(() => { beforeEach(() => {
vm = mountComponent(Component, { deployment: { ...deploymentMockData } }); vm = mountComponent(Component, { deployment: { ...deploymentMockData }, showMetrics: true });
}); });
describe('deployTimeago', () => { describe('deployTimeago', () => {
...@@ -174,11 +174,31 @@ describe('Deployment component', () => { ...@@ -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', () => { describe('without changes', () => {
beforeEach(() => { beforeEach(() => {
delete deploymentMockData.changes; 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', () => { it('renders the link to the review app without dropdown', () => {
...@@ -192,6 +212,7 @@ describe('Deployment component', () => { ...@@ -192,6 +212,7 @@ describe('Deployment component', () => {
beforeEach(() => { beforeEach(() => {
vm = mountComponent(Component, { vm = mountComponent(Component, {
deployment: Object.assign({}, deploymentMockData, { status: 'running' }), deployment: Object.assign({}, deploymentMockData, { status: 'running' }),
showMetrics: true,
}); });
}); });
...@@ -208,6 +229,7 @@ describe('Deployment component', () => { ...@@ -208,6 +229,7 @@ describe('Deployment component', () => {
beforeEach(() => { beforeEach(() => {
vm = mountComponent(Component, { vm = mountComponent(Component, {
deployment: Object.assign({}, deploymentMockData, { status: 'success' }), deployment: Object.assign({}, deploymentMockData, { status: 'success' }),
showMetrics: true,
}); });
}); });
...@@ -220,6 +242,7 @@ describe('Deployment component', () => { ...@@ -220,6 +242,7 @@ describe('Deployment component', () => {
beforeEach(() => { beforeEach(() => {
vm = mountComponent(Component, { vm = mountComponent(Component, {
deployment: Object.assign({}, deploymentMockData, { status: 'failed' }), deployment: Object.assign({}, deploymentMockData, { status: 'failed' }),
showMetrics: true,
}); });
}); });
......
...@@ -4,6 +4,9 @@ require 'spec_helper' ...@@ -4,6 +4,9 @@ require 'spec_helper'
describe Gitlab::PrivateCommitEmail do describe Gitlab::PrivateCommitEmail do
let(:hostname) { Gitlab::CurrentSettings.current_application_settings.commit_email_hostname } 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 context '.regex' do
subject { described_class.regex } subject { described_class.regex }
...@@ -16,18 +19,25 @@ describe Gitlab::PrivateCommitEmail do ...@@ -16,18 +19,25 @@ describe Gitlab::PrivateCommitEmail do
end end
context '.user_id_for_email' do context '.user_id_for_email' do
let(:id) { 1 }
it 'parses user id from email' do it 'parses user id from email' do
email = "#{id}-foo@#{hostname}" expect(described_class.user_id_for_email(valid_email)).to eq(id)
expect(described_class.user_id_for_email(email)).to eq(id)
end end
it 'returns nil on invalid commit email' do 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
end end
......
...@@ -72,6 +72,7 @@ describe Commit do ...@@ -72,6 +72,7 @@ describe Commit do
context 'using eager loading' do context 'using eager loading' do
let!(:alice) { create(:user, email: 'alice@example.com') } let!(:alice) { create(:user, email: 'alice@example.com') }
let!(:bob) { create(:user, email: 'hunter2@example.com') } let!(:bob) { create(:user, email: 'hunter2@example.com') }
let!(:jeff) { create(:user) }
let(:alice_commit) do let(:alice_commit) do
described_class.new(RepoHelpers.sample_commit, project).tap do |c| described_class.new(RepoHelpers.sample_commit, project).tap do |c|
...@@ -93,7 +94,14 @@ describe Commit do ...@@ -93,7 +94,14 @@ describe Commit do
end end
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 before do
create(:email, user: bob, email: 'bob@example.com') create(:email, user: bob, email: 'bob@example.com')
...@@ -125,6 +133,20 @@ describe Commit do ...@@ -125,6 +133,20 @@ describe Commit do
expect(bob_commit.author).to eq(bob) expect(bob_commit.author).to eq(bob)
end 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 it 'sets the author to Nil if an author could not be found for a Commit' do
commits.each(&:lazy_author) commits.each(&:lazy_author)
......
...@@ -48,12 +48,12 @@ describe ChatMessage::PushMessage do ...@@ -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))') '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( expect(subject.attachments).to eq(
"[abcdefgh](http://url1.com): message1 - author1\n\n[12345678](http://url2.com): message2 - author2") "[abcdefgh](http://url1.com): message1 - author1\n\n[12345678](http://url2.com): message2 - author2")
expect(subject.activity).to eq({ expect(subject.activity).to eq(
title: 'test.user pushed to branch', title: 'test.user pushed to branch [master](http://url.com/commits/master)',
subtitle: 'in [project_name](http://url.com)', subtitle: 'in [project_name](http://url.com)',
text: '[Compare changes](http://url.com/compare/before...after)', text: '[Compare changes](http://url.com/compare/before...after)',
image: 'http://someavatar.com' image: 'http://someavatar.com'
}) )
end end
end end
end end
...@@ -89,12 +89,53 @@ describe ChatMessage::PushMessage do ...@@ -89,12 +89,53 @@ describe ChatMessage::PushMessage do
expect(subject.pretext).to eq( expect(subject.pretext).to eq(
'test.user pushed new tag [new_tag](http://url.com/commits/new_tag) to [project_name](http://url.com)') '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.attachments).to be_empty
expect(subject.activity).to eq({ expect(subject.activity).to eq(
title: 'test.user created tag', title: 'test.user pushed new tag [new_tag](http://url.com/commits/new_tag)',
subtitle: 'in [project_name](http://url.com)', subtitle: 'in [project_name](http://url.com)',
text: '[Compare changes](http://url.com/compare/0000000000000000000000000000000000000000...after)', text: '[Compare changes](http://url.com/compare/0000000000000000000000000000000000000000...after)',
image: 'http://someavatar.com' 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 end
end end
...@@ -122,12 +163,12 @@ describe ChatMessage::PushMessage do ...@@ -122,12 +163,12 @@ describe ChatMessage::PushMessage do
expect(subject.pretext).to eq( expect(subject.pretext).to eq(
'test.user pushed new branch [master](http://url.com/commits/master) to [project_name](http://url.com)') '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.attachments).to be_empty
expect(subject.activity).to eq({ expect(subject.activity).to eq(
title: 'test.user created branch', title: 'test.user pushed new branch [master](http://url.com/commits/master)',
subtitle: 'in [project_name](http://url.com)', subtitle: 'in [project_name](http://url.com)',
text: '[Compare changes](http://url.com/compare/0000000000000000000000000000000000000000...after)', text: '[Compare changes](http://url.com/compare/0000000000000000000000000000000000000000...after)',
image: 'http://someavatar.com' image: 'http://someavatar.com'
}) )
end end
end end
end end
...@@ -154,12 +195,12 @@ describe ChatMessage::PushMessage do ...@@ -154,12 +195,12 @@ describe ChatMessage::PushMessage do
expect(subject.pretext).to eq( expect(subject.pretext).to eq(
'test.user removed branch master from [project_name](http://url.com)') 'test.user removed branch master from [project_name](http://url.com)')
expect(subject.attachments).to be_empty expect(subject.attachments).to be_empty
expect(subject.activity).to eq({ expect(subject.activity).to eq(
title: 'test.user removed branch', title: 'test.user removed branch master',
subtitle: 'in [project_name](http://url.com)', subtitle: 'in [project_name](http://url.com)',
text: '[Compare changes](http://url.com/compare/before...0000000000000000000000000000000000000000)', text: '[Compare changes](http://url.com/compare/before...0000000000000000000000000000000000000000)',
image: 'http://someavatar.com' image: 'http://someavatar.com'
}) )
end end
end end
end end
......
...@@ -3378,6 +3378,14 @@ describe Project do ...@@ -3378,6 +3378,14 @@ describe Project do
it 'does not flag as read-only' do it 'does not flag as read-only' do
expect { project.migrate_to_hashed_storage! }.not_to change { project.repository_read_only } expect { project.migrate_to_hashed_storage! }.not_to change { project.repository_read_only }
end 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
end end
......
...@@ -1202,6 +1202,22 @@ describe User do ...@@ -1202,6 +1202,22 @@ describe User do
expect(described_class.by_any_email(user.email, confirmed: true)).to eq([user]) expect(described_class.by_any_email(user.email, confirmed: true)).to eq([user])
end 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 end
describe '.search' do describe '.search' do
...@@ -1529,7 +1545,12 @@ describe User do ...@@ -1529,7 +1545,12 @@ describe User do
email_unconfirmed = create :email, user: user email_unconfirmed = create :email, user: user
user.reload 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
end end
...@@ -1540,7 +1561,11 @@ describe User do ...@@ -1540,7 +1561,11 @@ describe User do
email_confirmed = create :email, user: user, confirmed_at: Time.now email_confirmed = create :email, user: user, confirmed_at: Time.now
create :email, user: user 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
end end
...@@ -1560,6 +1585,14 @@ describe User do ...@@ -1560,6 +1585,14 @@ describe User do
expect(user.verified_email?(user.private_commit_email)).to be_truthy expect(user.verified_email?(user.private_commit_email)).to be_truthy
end 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 it 'returns false when the email is not verified/confirmed' do
email_unconfirmed = create :email, user: user email_unconfirmed = create :email, user: user
user.reload user.reload
......
...@@ -67,9 +67,8 @@ ...@@ -67,9 +67,8 @@
@babel/template,7.1.2,MIT @babel/template,7.1.2,MIT
@babel/traverse,7.1.0,MIT @babel/traverse,7.1.0,MIT
@babel/types,7.1.2,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/svgs,1.35.0,MIT
@gitlab/ui,1.11.0,MIT
@sindresorhus/is,0.7.0,MIT @sindresorhus/is,0.7.0,MIT
@types/jquery,2.0.48,MIT @types/jquery,2.0.48,MIT
@vue/component-compiler-utils,2.2.0,MIT @vue/component-compiler-utils,2.2.0,MIT
......
...@@ -629,10 +629,25 @@ ...@@ -629,10 +629,25 @@
eslint-plugin-promise "^4.0.1" eslint-plugin-promise "^4.0.1"
eslint-plugin-vue "^5.0.0-beta.3" eslint-plugin-vue "^5.0.0-beta.3"
"@gitlab/svgs@^1.35.0": "@gitlab/svgs@^1.38.0":
version "1.35.0" version "1.38.0"
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.35.0.tgz#01b6a0948bb3897fbbac9f50ce23c559c514ea0e" resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.38.0.tgz#e2f6e73379d60c7c63af4df8242a94c4671a1dfe"
integrity sha512-XKrTniSYKG5U8+8ZqDJqoW8ORahuPBfHrfsC1dHBPvo1xA/QGJxlpUdeqSFw2O19h481ut4yW1dF+OFpIa/mrw== 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": "@gitlab/ui@^1.11.0":
version "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