Skip to content
Snippets Groups Projects
Commit 83ab2898 authored by John Jarvis's avatar John Jarvis
Browse files

Merge branch 'master' into 11-10-stable

parents bfec819f a6e9175f
No related branches found
No related tags found
No related merge requests found
Showing
with 195 additions and 53 deletions
Loading
Loading
@@ -47,6 +47,19 @@ module Gitlab
self.source == other.source
end
 
# Handles regular expressions with the preferred RE2 library where possible
# via UntustedRegex. Falls back to Ruby's built-in regular expression library
# when the syntax would be invalid in RE2.
#
# One difference between these is `(?m)` multi-line mode. Ruby regex enables
# this by default, but also handles `^` and `$` differently.
# See: https://www.regular-expressions.info/modifiers.html
def self.with_fallback(pattern, multiline: false)
UntrustedRegexp.new(pattern, multiline: multiline)
rescue RegexpError
Regexp.new(pattern)
end
private
 
attr_reader :regexp
Loading
Loading
Loading
Loading
@@ -14,6 +14,12 @@ namespace :gitlab do
rake_version = run_and_match(%w(rake --version), /[\d\.]+/).try(:to_s)
# check redis version
redis_version = run_and_match(%w(redis-cli --version), /redis-cli (\d+\.\d+\.\d+)/).to_a
# check for system defined proxies
if Gitlab.ee?
proxies = Gitlab::Proxy.detect_proxy.map {|k, v| "#{k}: #{v}"}.join("\n\t\t")
end
# check Git version
git_version = run_and_match([Gitlab.config.git.bin_path, '--version'], /git version ([\d\.]+)/).to_a
# check Go version
Loading
Loading
@@ -22,6 +28,11 @@ namespace :gitlab do
puts ""
puts "System information".color(:yellow)
puts "System:\t\t#{os_name || "unknown".color(:red)}"
if Gitlab.ee?
puts "Proxy:\t\t#{proxies.present? ? proxies.color(:green) : "no"}"
end
puts "Current User:\t#{run_command(%w(whoami))}"
puts "Using RVM:\t#{rvm_version.present? ? "yes".color(:green) : "no"}"
puts "RVM Version:\t#{rvm_version}" if rvm_version.present?
Loading
Loading
@@ -39,6 +50,15 @@ namespace :gitlab do
http_clone_url = project.http_url_to_repo
ssh_clone_url = project.ssh_url_to_repo
 
if Gitlab.ee?
geo_node_type =
if Gitlab::Geo.current_node
Gitlab::Geo.current_node.primary ? 'Primary' : 'Secondary'
else
'Undefined'.color(:red)
end
end
omniauth_providers = Gitlab.config.omniauth.providers.map { |provider| provider['name'] }
 
puts ""
Loading
Loading
@@ -51,6 +71,13 @@ namespace :gitlab do
puts "URL:\t\t#{Gitlab.config.gitlab.url}"
puts "HTTP Clone URL:\t#{http_clone_url}"
puts "SSH Clone URL:\t#{ssh_clone_url}"
if Gitlab.ee?
puts "Elasticsearch:\t#{Gitlab::CurrentSettings.current_application_settings.elasticsearch_indexing? ? "yes".color(:green) : "no"}"
puts "Geo:\t\t#{Gitlab::Geo.enabled? ? "yes".color(:green) : "no"}"
puts "Geo node:\t#{geo_node_type}" if Gitlab::Geo.enabled?
end
puts "Using LDAP:\t#{Gitlab.config.ldap.enabled ? "yes".color(:green) : "no"}"
puts "Using Omniauth:\t#{Gitlab::Auth.omniauth_enabled? ? "yes".color(:green) : "no"}"
puts "Omniauth Providers: #{omniauth_providers.join(', ')}" if Gitlab::Auth.omniauth_enabled?
Loading
Loading
Loading
Loading
@@ -1620,6 +1620,9 @@ msgstr ""
msgid "CiVariables|Remove variable row"
msgstr ""
 
msgid "CiVariables|This variable will not be masked"
msgstr ""
msgid "CiVariable|* (All environments)"
msgstr ""
 
Loading
Loading
@@ -1629,9 +1632,15 @@ msgstr ""
msgid "CiVariable|Error occurred while saving variables"
msgstr ""
 
msgid "CiVariable|Masked"
msgstr ""
msgid "CiVariable|Protected"
msgstr ""
 
msgid "CiVariable|Toggle masked"
msgstr ""
msgid "CiVariable|Toggle protected"
msgstr ""
 
Loading
Loading
@@ -3181,10 +3190,7 @@ msgstr ""
msgid "Enter the merge request title"
msgstr ""
 
msgid "Environment variables"
msgstr ""
msgid "Environment variables are applied to environments via the runner. They can be protected by only exposing them to protected branches or tags. You can use environment variables for passwords, secret keys, or whatever you want."
msgid "Environment variables are applied to environments via the runner. They can be protected by only exposing them to protected branches or tags. Additionally, they will be masked by default so they are hidden in job logs, though they must match certain regexp requirements to do so. You can use environment variables for passwords, secret keys, or whatever you want."
msgstr ""
 
msgid "Environment variables are configured by your administrator to be %{link_start}protected%{link_end} by default"
Loading
Loading
@@ -3595,6 +3601,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
 
msgid "Failed to save new settings"
msgstr ""
msgid "Failed to update issues, please try again."
msgstr ""
 
Loading
Loading
@@ -8278,9 +8287,6 @@ msgstr ""
msgid "This setting will update the hostname that is used to generate private commit emails. %{learn_more}"
msgstr ""
 
msgid "This source diff could not be displayed because it is too large."
msgstr ""
msgid "This timeout will take precedence when lower than project-defined timeout and accepts a human readable time input language like \"1 hour\". Values without specification represent seconds."
msgstr ""
 
Loading
Loading
@@ -8353,9 +8359,6 @@ msgstr ""
msgid "Timeago|%s months remaining"
msgstr ""
 
msgid "Timeago|%s seconds ago"
msgstr ""
msgid "Timeago|%s seconds remaining"
msgstr ""
 
Loading
Loading
@@ -8948,6 +8951,9 @@ msgstr ""
msgid "Value"
msgstr ""
 
msgid "Variables"
msgstr ""
msgid "Various container registry settings."
msgstr ""
 
Loading
Loading
Loading
Loading
@@ -7,6 +7,7 @@
"eslint-fix": "eslint --max-warnings 0 --report-unused-disable-directives --ext .js,.vue --fix .",
"eslint-report": "eslint --max-warnings 0 --ext .js,.vue --format html --output-file ./eslint-report.html --no-inline-config .",
"jest": "BABEL_ENV=jest jest",
"jest-debug": "BABEL_ENV=jest node --inspect-brk node_modules/.bin/jest --runInBand",
"jsdoc": "jsdoc -c config/jsdocs.config.js",
"karma": "BABEL_ENV=${BABEL_ENV:=karma} karma start --single-run true config/karma.config.js",
"karma-coverage": "BABEL_ENV=coverage karma start --single-run true config/karma.config.js",
Loading
Loading
@@ -32,7 +33,7 @@
"@babel/plugin-syntax-import-meta": "^7.2.0",
"@babel/preset-env": "^7.3.1",
"@gitlab/csslab": "^1.9.0",
"@gitlab/svgs": "^1.57.0",
"@gitlab/svgs": "^1.58.0",
"@gitlab/ui": "^3.0.0",
"apollo-cache-inmemory": "^1.5.1",
"apollo-client": "^2.5.1",
Loading
Loading
@@ -56,11 +57,13 @@
"d3-array": "^1.2.1",
"d3-axis": "^1.0.8",
"d3-brush": "^1.0.4",
"d3-ease": "^1.0.3",
"d3-scale": "^1.0.7",
"d3-selection": "^1.2.0",
"d3-shape": "^1.2.0",
"d3-time": "^1.0.8",
"d3-time-format": "^2.1.1",
"d3-transition": "^1.1.1",
"dateformat": "^3.0.3",
"deckar01-task_list": "^2.2.0",
"diff": "^3.4.0",
Loading
Loading
Loading
Loading
@@ -43,4 +43,4 @@ end
 
Notice that in the above example, before clicking the `:operations_environments_link`, another element is hovered over.
 
> We can create these methods as helpers to abstrac multi-step navigation.
\ No newline at end of file
> We can create these methods as helpers to abstract multi-step navigation.
\ No newline at end of file
Loading
Loading
@@ -392,7 +392,7 @@ describe Projects::EnvironmentsController do
 
context 'when requesting metrics as JSON' do
it 'returns a metrics JSON document' do
get :additional_metrics, params: environment_params(format: :json)
additional_metrics
 
expect(response).to have_gitlab_http_status(204)
expect(json_response).to eq({})
Loading
Loading
@@ -412,7 +412,7 @@ describe Projects::EnvironmentsController do
end
 
it 'returns a metrics JSON document' do
get :additional_metrics, params: environment_params(format: :json)
additional_metrics
 
expect(response).to be_ok
expect(json_response['success']).to be(true)
Loading
Loading
@@ -420,6 +420,32 @@ describe Projects::EnvironmentsController do
expect(json_response['last_update']).to eq(42)
end
end
context 'when only one time param is provided' do
context 'when :metrics_time_window feature flag is disabled' do
before do
stub_feature_flags(metrics_time_window: false)
expect(environment).to receive(:additional_metrics).with(no_args).and_return(nil)
end
it 'returns a time-window agnostic response' do
additional_metrics(start: '1552647300.651094')
expect(response).to have_gitlab_http_status(204)
expect(json_response).to eq({})
end
end
it 'raises an error when start is missing' do
expect { additional_metrics(start: '1552647300.651094') }
.to raise_error(ActionController::ParameterMissing)
end
it 'raises an error when end is missing' do
expect { additional_metrics(start: '1552647300.651094') }
.to raise_error(ActionController::ParameterMissing)
end
end
end
 
describe 'GET #search' do
Loading
Loading
@@ -500,4 +526,8 @@ describe Projects::EnvironmentsController do
project_id: project,
id: environment.id)
end
def additional_metrics(opts = {})
get :additional_metrics, params: environment_params(format: :json, **opts)
end
end
Loading
Loading
@@ -28,6 +28,8 @@ describe Projects::PipelinesController do
end
 
it 'returns serialized pipelines', :request_store do
expect(::Gitlab::GitalyClient).to receive(:allow_ref_name_caching).and_call_original
queries = ActiveRecord::QueryRecorder.new do
get_pipelines_index_json
end
Loading
Loading
Loading
Loading
@@ -3,7 +3,7 @@ require 'spec_helper'
describe 'Group variables', :js do
let(:user) { create(:user) }
let(:group) { create(:group) }
let!(:variable) { create(:ci_group_variable, key: 'test_key', value: 'test_value', group: group) }
let!(:variable) { create(:ci_group_variable, key: 'test_key', value: 'test_value', masked: true, group: group) }
let(:page_path) { group_settings_ci_cd_path(group) }
 
before do
Loading
Loading
Loading
Loading
@@ -67,18 +67,7 @@ describe 'Merge request > User posts notes', :js do
end
end
 
describe 'when reply_to_individual_notes feature flag is disabled' do
before do
stub_feature_flags(reply_to_individual_notes: false)
visit project_merge_request_path(project, merge_request)
end
it 'does not show a reply button' do
expect(page).to have_no_selector('.js-reply-button')
end
end
describe 'when reply_to_individual_notes feature flag is not set' do
describe 'reply button' do
before do
visit project_merge_request_path(project, merge_request)
end
Loading
Loading
Loading
Loading
@@ -3,7 +3,7 @@ require 'spec_helper'
describe 'Project variables', :js do
let(:user) { create(:user) }
let(:project) { create(:project) }
let(:variable) { create(:ci_variable, key: 'test_key', value: 'test_value') }
let(:variable) { create(:ci_variable, key: 'test_key', value: 'test_value', masked: true) }
let(:page_path) { project_settings_ci_cd_path(project) }
 
before do
Loading
Loading
Loading
Loading
@@ -17,12 +17,14 @@ describe 'Merge request > User sees revert modal', :js do
end
 
it 'shows the revert modal' do
expect(page).to have_content('Revert this merge request')
page.within('.modal-header') do
expect(page).to have_content 'Revert this merge request'
end
end
 
it 'closes the revert modal with escape keypress' do
find('#modal-revert-commit').send_keys(:escape)
 
expect(page).not_to have_content('Revert this merge request')
expect(page).not_to have_selector('#modal-revert-commit', visible: true)
end
end
Loading
Loading
@@ -119,6 +119,12 @@
"merge_status", "sha", "merge_commit_sha", "user_notes_count",
"should_remove_source_branch", "force_remove_source_branch",
"web_url", "squash"
]
],
"head_pipeline": {
"oneOf": [
{ "type": "null" },
{ "$ref": "pipeline/detail.json" }
]
}
}
}
Loading
Loading
@@ -13,6 +13,5 @@
"ref": { "type": "string" },
"status": { "type": "string" },
"web_url": { "type": "string" }
},
"additionalProperties": false
}
}
{
"type": "object",
"allOf": [
{ "$ref": "basic.json" },
{
"properties": {
"before_sha": { "type": ["string", "null"] },
"tag": { "type": ["boolean"] },
"yaml_errors": { "type": ["string", "null"] },
"user": {
"anyOf": [
{ "type": ["object", "null"] },
{ "$ref": "../user/basic.json" }
]
},
"created_at": { "type": ["date", "null"] },
"updated_at": { "type": ["date", "null"] },
"started_at": { "type": ["date", "null"] },
"finished_at": { "type": ["date", "null"] },
"committed_at": { "type": ["date", "null"] },
"duration": { "type": ["number", "null"] },
"coverage": { "type": ["string", "null"] },
"detailed_status": {
"oneOf": [
{ "type": "null" },
{ "$ref": "../../../status/ci_detailed_status.json" }
]
}
}
}
]
}
Loading
Loading
@@ -4,12 +4,14 @@
"id",
"key",
"value",
"masked",
"protected"
],
"properties": {
"id": { "type": "integer" },
"key": { "type": "string" },
"value": { "type": "string" },
"masked": { "type": "boolean" },
"protected": { "type": "boolean" },
"environment_scope": { "type": "string", "optional": true }
},
Loading
Loading
import { viewerInformationForPath } from '~/vue_shared/components/content_viewer/lib/viewer_utils';
import { decorateFiles, splitParent } from '~/ide/lib/files';
import { decorateFiles, splitParent, escapeFileUrl } from '~/ide/lib/files';
import { decorateData } from '~/ide/stores/utils';
 
const TEST_BRANCH_ID = 'lorem-ipsum';
Loading
Loading
@@ -20,7 +20,7 @@ const createEntries = paths => {
id: path,
name,
path,
url: createUrl(`/${TEST_PROJECT_ID}/${type}/${TEST_BRANCH_ID}/-/${path}`),
url: createUrl(`/${TEST_PROJECT_ID}/${type}/${TEST_BRANCH_ID}/-/${escapeFileUrl(path)}`),
type,
previewMode: viewerInformationForPath(path),
parentPath: parent,
Loading
Loading
@@ -28,7 +28,7 @@ const createEntries = paths => {
? parentEntry.url
: createUrl(`/${TEST_PROJECT_ID}/${type}/${TEST_BRANCH_ID}`),
}),
tree: children.map(childName => jasmine.objectContaining({ name: childName })),
tree: children.map(childName => expect.objectContaining({ name: childName })),
};
 
return acc;
Loading
Loading
@@ -36,10 +36,10 @@ const createEntries = paths => {
 
const entries = paths.reduce(createEntry, {});
 
// Wrap entries in jasmine.objectContaining.
// Wrap entries in expect.objectContaining.
// We couldn't do this earlier because we still need to select properties from parent entries.
return Object.keys(entries).reduce((acc, key) => {
acc[key] = jasmine.objectContaining(entries[key]);
acc[key] = expect.objectContaining(entries[key]);
 
return acc;
}, {});
Loading
Loading
@@ -47,13 +47,14 @@ const createEntries = paths => {
 
describe('IDE lib decorate files', () => {
it('creates entries and treeList', () => {
const data = ['app/assets/apples/foo.js', 'app/bugs.js', 'README.md'];
const data = ['app/assets/apples/foo.js', 'app/bugs.js', 'app/#weird#file?.txt', 'README.md'];
const expectedEntries = createEntries([
{ path: 'app', type: 'tree', children: ['assets', 'bugs.js'] },
{ path: 'app', type: 'tree', children: ['assets', '#weird#file?.txt', 'bugs.js'] },
{ path: 'app/assets', type: 'tree', children: ['apples'] },
{ path: 'app/assets/apples', type: 'tree', children: ['foo.js'] },
{ path: 'app/assets/apples/foo.js', type: 'blob', children: [] },
{ path: 'app/bugs.js', type: 'blob', children: [] },
{ path: 'app/#weird#file?.txt', type: 'blob', children: [] },
{ path: 'README.md', type: 'blob', children: [] },
]);
 
Loading
Loading
@@ -64,7 +65,7 @@ describe('IDE lib decorate files', () => {
});
 
// Here we test the keys and then each key/value individually because `expect(entries).toEqual(expectedEntries)`
// was taking a very long time for some reason. Probably due to large objects and nested `jasmine.objectContaining`.
// was taking a very long time for some reason. Probably due to large objects and nested `expect.objectContaining`.
const entryKeys = Object.keys(entries);
 
expect(entryKeys).toEqual(Object.keys(expectedEntries));
Loading
Loading
Loading
Loading
@@ -230,5 +230,18 @@ describe BlobHelper do
 
expect(helper.ide_edit_path(project, "master", "")).to eq("/gitlab/-/ide/project/#{project.namespace.path}/#{project.path}/edit/master")
end
it 'escapes special characters' do
Rails.application.routes.default_url_options[:script_name] = nil
expect(helper.ide_edit_path(project, "testing/#hashes", "readme.md#test")).to eq("/-/ide/project/#{project.namespace.path}/#{project.path}/edit/testing/#hashes/-/readme.md%23test")
expect(helper.ide_edit_path(project, "testing/#hashes", "src#/readme.md#test")).to eq("/-/ide/project/#{project.namespace.path}/#{project.path}/edit/testing/#hashes/-/src%23/readme.md%23test")
end
it 'does not escape "/" character' do
Rails.application.routes.default_url_options[:script_name] = nil
expect(helper.ide_edit_path(project, "testing/slashes", "readme.md/")).to eq("/-/ide/project/#{project.namespace.path}/#{project.path}/edit/testing/slashes/-/readme.md/")
end
end
end
Loading
Loading
@@ -103,4 +103,18 @@ describe('Board component', () => {
})
.catch(done.fail);
});
it('does render add issue button', () => {
expect(vm.$el.querySelector('.issue-count-badge-add-button')).not.toBeNull();
});
it('does not render add issue button when list type is blank', done => {
vm.list.type = 'blank';
Vue.nextTick(() => {
expect(vm.$el.querySelector('.issue-count-badge-add-button')).toBeNull();
done();
});
});
});
Loading
Loading
@@ -127,20 +127,25 @@ describe('VariableList', () => {
variableList.init();
});
 
it('should add another row when editing the last rows protected checkbox', done => {
it('should not add another row when editing the last rows protected checkbox', done => {
const $row = $wrapper.find('.js-row:last-child');
$row.find('.ci-variable-protected-item .js-project-feature-toggle').click();
 
getSetTimeoutPromise()
.then(() => {
expect($wrapper.find('.js-row').length).toBe(2);
expect($wrapper.find('.js-row').length).toBe(1);
})
.then(done)
.catch(done.fail);
});
 
// Check for the correct default in the new row
const $protectedInput = $wrapper
.find('.js-row:last-child')
.find('.js-ci-variable-input-protected');
it('should not add another row when editing the last rows masked checkbox', done => {
const $row = $wrapper.find('.js-row:last-child');
$row.find('.ci-variable-masked-item .js-project-feature-toggle').click();
 
expect($protectedInput.val()).toBe('false');
getSetTimeoutPromise()
.then(() => {
expect($wrapper.find('.js-row').length).toBe(1);
})
.then(done)
.catch(done.fail);
Loading
Loading
Loading
Loading
@@ -141,18 +141,16 @@ describe('DiffFile', () => {
it('should have too large warning and blob link', done => {
const BLOB_LINK = '/file/view/path';
vm.file.viewer.error = diffViewerErrors.too_large;
vm.file.viewer.error_message =
'This source diff could not be displayed because it is too large';
vm.file.view_path = BLOB_LINK;
vm.file.renderIt = true;
 
vm.$nextTick(() => {
expect(vm.$el.innerText).toContain(
'This source diff could not be displayed because it is too large',
);
 
expect(vm.$el.querySelector('.js-too-large-diff')).toBeDefined();
expect(
vm.$el.querySelector('.js-too-large-diff a').href.indexOf(BLOB_LINK),
).toBeGreaterThan(-1);
done();
});
});
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment