Commit 77a72746 authored by GitLab Bot's avatar GitLab Bot

Merge remote-tracking branch 'upstream/master' into ce-to-ee-2019-02-02

# Conflicts:
#	app/assets/javascripts/monitoring/components/dashboard.vue
#	app/views/admin/application_settings/_account_and_limit.html.haml
#	ee/app/assets/javascripts/geo_nodes/event_hub.js
#	locale/gitlab.pot
#	qa/qa/page/main/login.rb

[ci skip]
parents 77f0b417 dd26a9ad
...@@ -151,9 +151,8 @@ stages: ...@@ -151,9 +151,8 @@ stages:
variables: &single-script-job-variables variables: &single-script-job-variables
GIT_STRATEGY: none GIT_STRATEGY: none
before_script: before_script:
# We need to download the script rather than clone the repo since the # We don't clone the repo by using GIT_STRATEGY: none and only download the
# package-and-qa job will not be able to run when the branch gets # single script we need here so it's much faster than cloning.
# deleted (when merging the MR).
- export SCRIPT_NAME="${SCRIPT_NAME:-$CI_JOB_NAME}" - export SCRIPT_NAME="${SCRIPT_NAME:-$CI_JOB_NAME}"
- apk add --update openssl - apk add --update openssl
- wget $CI_PROJECT_URL/raw/$CI_COMMIT_SHA/scripts/$SCRIPT_NAME - wget $CI_PROJECT_URL/raw/$CI_COMMIT_SHA/scripts/$SCRIPT_NAME
...@@ -319,20 +318,21 @@ stages: ...@@ -319,20 +318,21 @@ stages:
# Trigger a package build in omnibus-gitlab repository # Trigger a package build in omnibus-gitlab repository
# #
package-and-qa: package-and-qa:
<<: *single-script-job image: ruby:2.5-alpine
stage: test
before_script: []
dependencies: []
cache: {}
variables: variables:
<<: *single-script-job-variables GIT_DEPTH: "1"
API_TOKEN: "${GITLAB_BOT_MULTI_PROJECT_PIPELINE_POLLING_TOKEN}" API_TOKEN: "${GITLAB_BOT_MULTI_PROJECT_PIPELINE_POLLING_TOKEN}"
SCRIPT_NAME: trigger-build
retry: 0 retry: 0
script: script:
- gem install gitlab --no-document
- apk add --update openssl curl jq - apk add --update openssl curl jq
- wget $CI_PROJECT_URL/raw/$CI_COMMIT_SHA/scripts/review_apps/review-apps.sh - gem install gitlab --no-document
- chmod 755 review-apps.sh - source ./scripts/review_apps/review-apps.sh
- source ./review-apps.sh
- wait_for_job_to_be_done "gitlab:assets:compile" - wait_for_job_to_be_done "gitlab:assets:compile"
- ./$SCRIPT_NAME omnibus - ./scripts/trigger-build omnibus
when: manual when: manual
only: only:
- //@gitlab-org/gitlab-ce - //@gitlab-org/gitlab-ce
...@@ -1121,20 +1121,21 @@ no_ee_check: ...@@ -1121,20 +1121,21 @@ no_ee_check:
# GitLab Review apps # GitLab Review apps
review-build-cng: review-build-cng:
<<: *single-script-job
<<: *review-only <<: *review-only
image: ruby:2.5-alpine
stage: test
before_script: []
dependencies: []
cache: {}
variables: variables:
<<: *single-script-job-variables GIT_DEPTH: "1"
SCRIPT_NAME: trigger-build
API_TOKEN: "${GITLAB_BOT_MULTI_PROJECT_PIPELINE_POLLING_TOKEN}" API_TOKEN: "${GITLAB_BOT_MULTI_PROJECT_PIPELINE_POLLING_TOKEN}"
script: script:
- gem install gitlab --no-document
- apk add --update openssl curl jq - apk add --update openssl curl jq
- wget $CI_PROJECT_URL/raw/$CI_COMMIT_SHA/scripts/review_apps/review-apps.sh - gem install gitlab --no-document
- chmod 755 review-apps.sh - source ./scripts/review_apps/review-apps.sh
- source ./review-apps.sh
- wait_for_job_to_be_done "gitlab:assets:compile" - wait_for_job_to_be_done "gitlab:assets:compile"
- BUILD_TRIGGER_TOKEN=$REVIEW_APPS_BUILD_TRIGGER_TOKEN ./$SCRIPT_NAME cng - BUILD_TRIGGER_TOKEN=$REVIEW_APPS_BUILD_TRIGGER_TOKEN ./scripts/trigger-build cng
review-deploy: review-deploy:
<<: *review-base <<: *review-base
......
...@@ -39,7 +39,9 @@ export default { ...@@ -39,7 +39,9 @@ export default {
<ci-icon :status="pipeline.details.status" class="vertical-align-middle" /> <ci-icon :status="pipeline.details.status" class="vertical-align-middle" />
<span class="font-weight-bold">{{ __('Pipeline') }}</span> <span class="font-weight-bold">{{ __('Pipeline') }}</span>
<a :href="pipeline.path" class="js-pipeline-path link-commit">#{{ pipeline.id }}</a> <a :href="pipeline.path" class="js-pipeline-path link-commit qa-pipeline-path"
>#{{ pipeline.id }}</a
>
<template v-if="hasRef"> <template v-if="hasRef">
{{ __('from') }} {{ __('from') }}
<a :href="pipeline.ref.path" class="link-commit ref-name">{{ pipeline.ref.name }}</a> <a :href="pipeline.ref.path" class="link-commit ref-name">{{ pipeline.ref.name }}</a>
......
...@@ -221,6 +221,7 @@ export default { ...@@ -221,6 +221,7 @@ export default {
:graph-data="graphData" :graph-data="graphData"
:alert-data="getGraphAlerts(graphData.id)" :alert-data="getGraphAlerts(graphData.id)"
group-id="monitor-area-chart" group-id="monitor-area-chart"
<<<<<<< HEAD
> >
<!-- EE content --> <!-- EE content -->
<alert-widget <alert-widget
...@@ -233,6 +234,9 @@ export default { ...@@ -233,6 +234,9 @@ export default {
@setAlerts="setAlerts" @setAlerts="setAlerts"
/> />
</monitor-area-chart> </monitor-area-chart>
=======
/>
>>>>>>> upstream/master
</graph-group> </graph-group>
</div> </div>
<empty-state <empty-state
......
...@@ -108,7 +108,7 @@ export default { ...@@ -108,7 +108,7 @@ export default {
:href="status.details_path" :href="status.details_path"
:title="tooltipText" :title="tooltipText"
:class="cssClassJobName" :class="cssClassJobName"
class="js-pipeline-graph-job-link" class="js-pipeline-graph-job-link qa-job-link"
> >
<job-name-component :name="job.name" :status="job.status" /> <job-name-component :name="job.name" :status="job.status" />
</gl-link> </gl-link>
......
...@@ -4,6 +4,10 @@ module Resolvers ...@@ -4,6 +4,10 @@ module Resolvers
class IssuesResolver < BaseResolver class IssuesResolver < BaseResolver
extend ActiveSupport::Concern extend ActiveSupport::Concern
argument :iids, [GraphQL::ID_TYPE],
required: false,
description: 'The list of IIDs of issues, e.g., [1, 2]'
argument :search, GraphQL::STRING_TYPE, argument :search, GraphQL::STRING_TYPE,
required: false required: false
argument :sort, Types::Sort, argument :sort, Types::Sort,
......
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
= f.label :user_show_add_ssh_key_message, class: 'form-check-label' do = f.label :user_show_add_ssh_key_message, class: 'form-check-label' do
Inform users without uploaded SSH keys that they can't push over SSH until one is added Inform users without uploaded SSH keys that they can't push over SSH until one is added
<<<<<<< HEAD
- if ::Gitlab.dev_env_or_com? - if ::Gitlab.dev_env_or_com?
.form-group .form-group
= f.label :check_namespace_plan, 'Check feature availability on namespace plan', class: 'label-bold' = f.label :check_namespace_plan, 'Check feature availability on namespace plan', class: 'label-bold'
...@@ -58,4 +59,6 @@ ...@@ -58,4 +59,6 @@
Enabling this will only make licensed EE features available to projects if the project namespace's plan Enabling this will only make licensed EE features available to projects if the project namespace's plan
includes the feature or if the project is public. includes the feature or if the project is public.
=======
>>>>>>> upstream/master
= f.submit 'Save changes', class: 'btn btn-success qa-save-changes-button' = f.submit 'Save changes', class: 'btn btn-success qa-save-changes-button'
---
title: 'API: Support username with dots'
merge_request: 24395
author: Robert Schilling
type: fixed
---
title: Add argument iids for issues in GraphQL
merge_request: 24802
author:
type: added
---
title: Update Gitaly to v1.17.0
merge_request: 24873
author:
type: other
...@@ -183,6 +183,7 @@ Parameters: ...@@ -183,6 +183,7 @@ Parameters:
| `source_branch` | string | no | Return merge requests with the given source branch | | `source_branch` | string | no | Return merge requests with the given source branch |
| `target_branch` | string | no | Return merge requests with the given target branch | | `target_branch` | string | no | Return merge requests with the given target branch |
| `search` | string | no | Search merge requests against their `title` and `description` | | `search` | string | no | Search merge requests against their `title` and `description` |
| `wip` | string | no | Filter merge requests against their `wip` status. `yes` to return *only* WIP merge requests, `no` to return *non* WIP merge requests |
```json ```json
[ [
......
...@@ -9,6 +9,7 @@ module API ...@@ -9,6 +9,7 @@ module API
NO_SLASH_URL_PART_REGEX = %r{[^/]+} NO_SLASH_URL_PART_REGEX = %r{[^/]+}
NAMESPACE_OR_PROJECT_REQUIREMENTS = { id: NO_SLASH_URL_PART_REGEX }.freeze NAMESPACE_OR_PROJECT_REQUIREMENTS = { id: NO_SLASH_URL_PART_REGEX }.freeze
COMMIT_ENDPOINT_REQUIREMENTS = NAMESPACE_OR_PROJECT_REQUIREMENTS.merge(sha: NO_SLASH_URL_PART_REGEX).freeze COMMIT_ENDPOINT_REQUIREMENTS = NAMESPACE_OR_PROJECT_REQUIREMENTS.merge(sha: NO_SLASH_URL_PART_REGEX).freeze
USER_REQUIREMENTS = { user_id: NO_SLASH_URL_PART_REGEX }.freeze
insert_before Grape::Middleware::Error, insert_before Grape::Middleware::Error,
GrapeLogging::Middleware::RequestLogger, GrapeLogging::Middleware::RequestLogger,
......
...@@ -130,7 +130,7 @@ module API ...@@ -130,7 +130,7 @@ module API
end end
end end
resource :users, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :users, requirements: API::USER_REQUIREMENTS do
desc 'Get a user projects' do desc 'Get a user projects' do
success Entities::BasicProjectDetails success Entities::BasicProjectDetails
end end
......
...@@ -139,10 +139,10 @@ module API ...@@ -139,10 +139,10 @@ module API
desc "Get the status of a user" desc "Get the status of a user"
params do params do
requires :id_or_username, type: String, desc: 'The ID or username of the user' requires :user_id, type: String, desc: 'The ID or username of the user'
end end
get ":id_or_username/status" do get ":user_id/status", requirements: API::USER_REQUIREMENTS do
user = find_user(params[:id_or_username]) user = find_user(params[:user_id])
not_found!('User') unless user && can?(current_user, :read_user, user) not_found!('User') unless user && can?(current_user, :read_user, user)
present user.status || {}, with: Entities::UserStatus present user.status || {}, with: Entities::UserStatus
......
...@@ -5809,6 +5809,7 @@ msgstr "" ...@@ -5809,6 +5809,7 @@ msgstr ""
msgid "Metrics|Learn about environments" msgid "Metrics|Learn about environments"
msgstr "" msgstr ""
<<<<<<< HEAD
msgid "Metrics|Legend label (optional)" msgid "Metrics|Legend label (optional)"
msgstr "" msgstr ""
...@@ -5821,6 +5822,8 @@ msgstr "" ...@@ -5821,6 +5822,8 @@ msgstr ""
msgid "Metrics|New metric" msgid "Metrics|New metric"
msgstr "" msgstr ""
=======
>>>>>>> upstream/master
msgid "Metrics|No deployed environments" msgid "Metrics|No deployed environments"
msgstr "" msgstr ""
...@@ -7304,6 +7307,7 @@ msgstr "" ...@@ -7304,6 +7307,7 @@ msgstr ""
msgid "ProjectsDropdown|This feature requires browser localStorage support" msgid "ProjectsDropdown|This feature requires browser localStorage support"
msgstr "" msgstr ""
<<<<<<< HEAD
msgid "PrometheusAlerts|Add alert" msgid "PrometheusAlerts|Add alert"
msgstr "" msgstr ""
...@@ -7334,6 +7338,8 @@ msgstr "" ...@@ -7334,6 +7338,8 @@ msgstr ""
msgid "PrometheusAlerts|Threshold" msgid "PrometheusAlerts|Threshold"
msgstr "" msgstr ""
=======
>>>>>>> upstream/master
msgid "PrometheusService|%{exporters} with %{metrics} were found" msgid "PrometheusService|%{exporters} with %{metrics} were found"
msgstr "" msgstr ""
......
...@@ -153,6 +153,7 @@ module QA ...@@ -153,6 +153,7 @@ module QA
def sign_in_with_github def sign_in_with_github
set_initial_password_if_present set_initial_password_if_present
click_element :github_login_button click_element :github_login_button
<<<<<<< HEAD
end end
def sign_in_with_saml def sign_in_with_saml
...@@ -162,6 +163,25 @@ module QA ...@@ -162,6 +163,25 @@ module QA
private private
=======
end
def sign_in_with_saml
set_initial_password_if_present
click_element :saml_login_button
end
private
def sign_in_using_ldap_credentials
switch_to_ldap_tab
fill_element :username_field, Runtime::User.ldap_username
fill_element :password_field, Runtime::User.ldap_password
click_element :sign_in_button
end
>>>>>>> upstream/master
def sign_in_using_gitlab_credentials(user) def sign_in_using_gitlab_credentials(user)
switch_to_sign_in_tab if has_sign_in_tab? switch_to_sign_in_tab if has_sign_in_tab?
switch_to_standard_tab if has_standard_tab? switch_to_standard_tab if has_standard_tab?
......
...@@ -16,11 +16,19 @@ module QA::Page ...@@ -16,11 +16,19 @@ module QA::Page
element :status_badge element :status_badge
end end
view 'app/assets/javascripts/jobs/components/stages_dropdown.vue' do
element :pipeline_path
end
def completed? def completed?
COMPLETED_STATUSES.include?(status_badge) COMPLETED_STATUSES.include?(status_badge)
end end
def passed? def successful?(timeout: 60)
wait(reload: false, max: timeout) do
completed? && !trace_loading?
end
status_badge == PASSED_STATUS status_badge == PASSED_STATUS
end end
......
...@@ -11,7 +11,7 @@ module QA::Page ...@@ -11,7 +11,7 @@ module QA::Page
view 'app/assets/javascripts/pipelines/components/graph/job_item.vue' do view 'app/assets/javascripts/pipelines/components/graph/job_item.vue' do
element :job_component, /class.*ci-job-component.*/ # rubocop:disable QA/ElementWithPattern element :job_component, /class.*ci-job-component.*/ # rubocop:disable QA/ElementWithPattern
element :job_link, /class.*js-pipeline-graph-job-link.*/ # rubocop:disable QA/ElementWithPattern element :job_link
end end
view 'app/assets/javascripts/vue_shared/components/ci_icon.vue' do view 'app/assets/javascripts/vue_shared/components/ci_icon.vue' do
...@@ -32,6 +32,10 @@ module QA::Page ...@@ -32,6 +32,10 @@ module QA::Page
end end
end end
def go_to_job(job_name)
find_element(:job_link, job_name).click
end
def go_to_first_job def go_to_first_job
css = '.js-pipeline-graph-job-link' css = '.js-pipeline-graph-job-link'
......
...@@ -95,11 +95,7 @@ module QA ...@@ -95,11 +95,7 @@ module QA
Page::Project::Pipeline::Show.act { go_to_first_job } Page::Project::Pipeline::Show.act { go_to_first_job }
Page::Project::Job::Show.perform do |job| Page::Project::Job::Show.perform do |job|
job.wait(reload: false) do expect(job).to be_successful, "Job status did not become \"passed\"."
job.completed? && !job.trace_loading?
end
expect(job.passed?).to be_truthy, "Job status did not become \"passed\"."
expect(job.output).to include(sha1sum) expect(job.output).to include(sha1sum)
end end
end end
......
...@@ -75,9 +75,30 @@ module QA ...@@ -75,9 +75,30 @@ module QA
Page::Project::Pipeline::Index.act { go_to_latest_pipeline } Page::Project::Pipeline::Index.act { go_to_latest_pipeline }
Page::Project::Pipeline::Show.perform do |pipeline| Page::Project::Pipeline::Show.perform do |pipeline|
expect(pipeline).to have_build('build', status: :success, wait: 600) pipeline.go_to_job('build')
expect(pipeline).to have_build('test', status: :success, wait: 600) end
expect(pipeline).to have_build('production', status: :success, wait: 1200) Page::Project::Job::Show.perform do |job|
expect(job).to be_sucessful(timeout: 600), "Job did not pass"
job.click_element(:pipeline_path)
end
Page::Project::Pipeline::Show.perform do |pipeline|
pipeline.go_to_job('test')
end
Page::Project::Job::Show.perform do |job|
expect(job).to be_sucessful(timeout: 600), "Job did not pass"
job.click_element(:pipeline_path)
end
Page::Project::Pipeline::Show.perform do |pipeline|
pipeline.go_to_job('production')
end
Page::Project::Job::Show.perform do |job|
expect(job).to be_sucessful(timeout: 1200), "Job did not pass"
job.click_element(:pipeline_path)
end end
Page::Project::Menu.act { click_operations_environments } Page::Project::Menu.act { click_operations_environments }
...@@ -115,9 +136,30 @@ module QA ...@@ -115,9 +136,30 @@ module QA
Page::Project::Pipeline::Index.act { go_to_latest_pipeline } Page::Project::Pipeline::Index.act { go_to_latest_pipeline }
Page::Project::Pipeline::Show.perform do |pipeline| Page::Project::Pipeline::Show.perform do |pipeline|
expect(pipeline).to have_build('build', status: :success, wait: 600) pipeline.go_to_job('build')
expect(pipeline).to have_build('test', status: :success, wait: 600) end
expect(pipeline).to have_build('production', status: :success, wait: 1200) Page::Project::Job::Show.perform do |job|
expect(job).to be_sucessful(timeout: 600), "Job did not pass"
job.click_element(:pipeline_path)
end
Page::Project::Pipeline::Show.perform do |pipeline|
pipeline.go_to_job('test')
end
Page::Project::Job::Show.perform do |job|
expect(job).to be_sucessful(timeout: 600), "Job did not pass"
job.click_element(:pipeline_path)
end
Page::Project::Pipeline::Show.perform do |pipeline|
pipeline.go_to_job('production')
end
Page::Project::Job::Show.perform do |job|
expect(job).to be_sucessful(timeout: 1200), "Job did not pass"
job.click_element(:pipeline_path)
end end
Page::Project::Menu.act { click_operations_environments } Page::Project::Menu.act { click_operations_environments }
......
...@@ -32,6 +32,26 @@ describe Resolvers::IssuesResolver do ...@@ -32,6 +32,26 @@ describe Resolvers::IssuesResolver do
expect(resolve_issues).to contain_exactly(issue, issue2) expect(resolve_issues).to contain_exactly(issue, issue2)
end end
it 'finds a specific issue with iids' do
expect(resolve_issues(iids: issue.iid)).to contain_exactly(issue)
end
it 'finds multiple issues with iids' do
expect(resolve_issues(iids: [issue.iid, issue2.iid]))
.to contain_exactly(issue, issue2)
end
it 'finds only the issues within the project we are looking at' do
another_project = create(:project)
iids = [issue, issue2].map(&:iid)
iids.each do |iid|
create(:issue, project: another_project, iid: iid)
end
expect(resolve_issues(iids: iids)).to contain_exactly(issue, issue2)
end
end end
def resolve_issues(args = {}, context = { current_user: current_user }) def resolve_issues(args = {}, context = { current_user: current_user })
......
...@@ -21,7 +21,7 @@ describe API::Projects do ...@@ -21,7 +21,7 @@ describe API::Projects do
let(:project) { create(:project, :repository, namespace: user.namespace) } let(:project) { create(:project, :repository, namespace: user.namespace) }
let(:project2) { create(:project, namespace: user.namespace) } let(:project2) { create(:project, namespace: user.namespace) }
let(:project_member) { create(:project_member, :developer, user: user3, project: project) } let(:project_member) { create(:project_member, :developer, user: user3, project: project) }
let(:user4) { create(:user) } let(:user4) { create(:user, username: 'user.with.dot') }
let(:project3) do let(:project3) do
create(:project, create(:project,
:private, :private,
...@@ -724,7 +724,7 @@ describe API::Projects do ...@@ -724,7 +724,7 @@ describe API::Projects do
expect(json_response['message']).to eq('404 User Not Found') expect(json_response['message']).to eq('404 User Not Found')
end end
it 'returns projects filtered by user' do it 'returns projects filtered by user id' do
get api("/users/#{user4.id}/projects/", user) get api("/users/#{user4.id}/projects/", user)
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(200)
...@@ -733,6 +733,15 @@ describe API::Projects do ...@@ -733,6 +733,15 @@ describe API::Projects do
expect(json_response.map { |project| project['id'] }).to contain_exactly(public_project.id) expect(json_response.map { |project| project['id'] }).to contain_exactly(public_project.id)
end end
it 'returns projects filtered by username' do
get api("/users/#{user4.username}/projects/", user)
expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.map { |project| project['id'] }).to contain_exactly(public_project.id)
end
it 'returns projects filtered by minimal access level' do it 'returns projects filtered by minimal access level' do
private_project1 = create(:project, :private, name: 'private_project1', creator_id: user4.id, namespace: user4.namespace) private_project1 = create(:project, :private, name: 'private_project1', creator_id: user4.id, namespace: user4.namespace)
private_project2 = create(:project, :private, name: 'private_project2', creator_id: user4.id, namespace: user4.namespace) private_project2 = create(:project, :private, name: 'private_project2', creator_id: user4.id, namespace: user4.namespace)
......
require 'spec_helper' require 'spec_helper'
describe API::Users do describe API::Users do
let(:user) { create(:user) } let(:user) { create(:user, username: 'user.with.dot') }
let(:admin) { create(:admin) } let(:admin) { create(:admin) }
let(:key) { create(:key, user: user) } let(:key) { create(:key, user: user) }
let(:gpg_key) { create(:gpg_key, user: user) } let(:gpg_key) { create(:gpg_key, user: user) }
......
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