summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2019-10-29 18:06:15 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2019-10-29 18:06:15 +0000
commitcb3e6b9c1b020378b5f94b4c38319a2dc961de01 (patch)
tree7933db817fb945478151685a393420b44fa52f7c
parentdee9315801b5dc49b795d13081086c22622a11ec (diff)
downloadgitlab-ce-cb3e6b9c1b020378b5f94b4c38319a2dc961de01.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/assets/javascripts/diffs/components/diff_file.vue13
-rw-r--r--changelogs/unreleased/bug-fix-27164-Image-cannot-be-collapsed-on-merge-request-changes-tab.yml5
-rw-r--r--changelogs/unreleased/feature-reduce-cluster-ip-size.yml5
-rw-r--r--changelogs/unreleased/job-log-support-mac-line-break.yml5
-rw-r--r--changelogs/unreleased/mc-feature-flatten-ci-scripts.yml5
-rw-r--r--doc/ci/yaml/README.md46
-rw-r--r--doc/user/project/clusters/add_remove_clusters.md3
-rw-r--r--lib/gitlab/ci/ansi2json/converter.rb103
-rw-r--r--lib/gitlab/ci/ansi2json/line.rb7
-rw-r--r--lib/gitlab/ci/ansi2json/state.rb4
-rw-r--r--lib/gitlab/ci/config/entry/commands.rb4
-rw-r--r--lib/gitlab/ci/config/entry/script.rb6
-rw-r--r--lib/gitlab/config/entry/validators.rb28
-rw-r--r--lib/google_api/cloud_platform/client.rb4
-rw-r--r--spec/javascripts/diffs/components/diff_file_spec.js49
-rw-r--r--spec/javascripts/diffs/mock_data/diff_file_unreadable.js244
-rw-r--r--spec/lib/gitlab/ci/ansi2json_spec.rb63
-rw-r--r--spec/lib/gitlab/ci/config/entry/commands_spec.rb67
-rw-r--r--spec/lib/gitlab/ci/config/entry/root_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/config/entry/script_spec.rb67
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/validate/config_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/yaml_processor_spec.rb80
-rw-r--r--spec/lib/google_api/cloud_platform/client_spec.rb3
23 files changed, 710 insertions, 105 deletions
diff --git a/app/assets/javascripts/diffs/components/diff_file.vue b/app/assets/javascripts/diffs/components/diff_file.vue
index 2514274224d..9236f0d5349 100644
--- a/app/assets/javascripts/diffs/components/diff_file.vue
+++ b/app/assets/javascripts/diffs/components/diff_file.vue
@@ -54,11 +54,12 @@ export default {
showLoadingIcon() {
return this.isLoadingCollapsedDiff || (!this.file.renderIt && !this.isCollapsed);
},
- hasDiffLines() {
+ hasDiff() {
return (
- this.file.highlighted_diff_lines &&
- this.file.parallel_diff_lines &&
- this.file.parallel_diff_lines.length > 0
+ (this.file.highlighted_diff_lines &&
+ this.file.parallel_diff_lines &&
+ this.file.parallel_diff_lines.length > 0) ||
+ !this.file.blob.readable_text
);
},
isFileTooLarge() {
@@ -82,7 +83,7 @@ export default {
},
watch: {
isCollapsed: function fileCollapsedWatch(newVal, oldVal) {
- if (!newVal && oldVal && !this.hasDiffLines) {
+ if (!newVal && oldVal && !this.hasDiff) {
this.handleLoadCollapsedDiff();
}
@@ -103,7 +104,7 @@ export default {
'setFileCollapsed',
]),
handleToggle() {
- if (!this.hasDiffLines) {
+ if (!this.hasDiff) {
this.handleLoadCollapsedDiff();
} else {
this.isCollapsed = !this.isCollapsed;
diff --git a/changelogs/unreleased/bug-fix-27164-Image-cannot-be-collapsed-on-merge-request-changes-tab.yml b/changelogs/unreleased/bug-fix-27164-Image-cannot-be-collapsed-on-merge-request-changes-tab.yml
new file mode 100644
index 00000000000..22956631131
--- /dev/null
+++ b/changelogs/unreleased/bug-fix-27164-Image-cannot-be-collapsed-on-merge-request-changes-tab.yml
@@ -0,0 +1,5 @@
+---
+title: 'fixed #27164 Image cannot be collapsed on merge request changes tab'
+merge_request: 18917
+author: Jannik Lehmann
+type: fixed
diff --git a/changelogs/unreleased/feature-reduce-cluster-ip-size.yml b/changelogs/unreleased/feature-reduce-cluster-ip-size.yml
new file mode 100644
index 00000000000..62bdd3b8592
--- /dev/null
+++ b/changelogs/unreleased/feature-reduce-cluster-ip-size.yml
@@ -0,0 +1,5 @@
+---
+title: Reduce the allocated IP for Cluster and Services
+merge_request: 18341
+author:
+type: changed
diff --git a/changelogs/unreleased/job-log-support-mac-line-break.yml b/changelogs/unreleased/job-log-support-mac-line-break.yml
new file mode 100644
index 00000000000..12be5be687d
--- /dev/null
+++ b/changelogs/unreleased/job-log-support-mac-line-break.yml
@@ -0,0 +1,5 @@
+---
+title: Let ANSI \r code replace the current job log line
+merge_request: 18933
+author:
+type: fixed
diff --git a/changelogs/unreleased/mc-feature-flatten-ci-scripts.yml b/changelogs/unreleased/mc-feature-flatten-ci-scripts.yml
new file mode 100644
index 00000000000..3dfcc5e871c
--- /dev/null
+++ b/changelogs/unreleased/mc-feature-flatten-ci-scripts.yml
@@ -0,0 +1,5 @@
+---
+title: Add support for YAML anchors in CI scripts.
+merge_request: 18849
+author:
+type: changed
diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md
index 28c6bc6c418..8449dfec049 100644
--- a/doc/ci/yaml/README.md
+++ b/doc/ci/yaml/README.md
@@ -181,6 +181,25 @@ that the YAML parser knows to interpret the whole thing as a string rather than
a "key: value" pair. Be careful when using special characters:
`:`, `{`, `}`, `[`, `]`, `,`, `&`, `*`, `#`, `?`, `|`, `-`, `<`, `>`, `=`, `!`, `%`, `@`, `` ` ``.
+#### YAML anchors for `script`
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/23005) in GitLab 12.5.
+
+You can use [YAML anchors](#anchors) with scripts, which makes it possible to
+include a predefined list of commands in multiple jobs.
+
+Example:
+
+```yaml
+.something: &something
+- echo 'something'
+
+job_name:
+ script:
+ - *something
+ - echo 'this is the script'
+```
+
### `image`
Used to specify [a Docker image](../docker/using_docker_images.md#what-is-an-image) to use for the job.
@@ -284,6 +303,33 @@ job:
- execute this after my script
```
+#### YAML anchors for `before_script` and `after_script`
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/23005) in GitLab 12.5.
+
+You can use [YAML anchors](#anchors) with `before_script` and `after_script`,
+which makes it possible to include a predefined list of commands in multiple
+jobs.
+
+Example:
+
+```yaml
+.something_before: &something_before
+- echo 'something before'
+
+.something_after: &something_after
+- echo 'something after'
+
+
+job_name:
+ before_script:
+ - *something_before
+ script:
+ - echo 'this is the script'
+ after_script:
+ - *something_after
+```
+
### `stages`
`stages` is used to define stages that can be used by jobs and is defined
diff --git a/doc/user/project/clusters/add_remove_clusters.md b/doc/user/project/clusters/add_remove_clusters.md
index b1d93577823..84f8da526d7 100644
--- a/doc/user/project/clusters/add_remove_clusters.md
+++ b/doc/user/project/clusters/add_remove_clusters.md
@@ -175,6 +175,9 @@ NOTE: **Note:**
Starting from [GitLab 12.1](https://gitlab.com/gitlab-org/gitlab-foss/issues/55902), all GKE clusters
created by GitLab are RBAC-enabled. Take a look at the [RBAC section](#rbac-cluster-resources) for more information.
+NOTE: **Note:**
+Starting from [GitLab 12.5](https://gitlab.com/gitlab-org/gitlab/merge_requests/18341), the cluster's pod address IP range will be set to /16 instead of the regular /14. (/16 is a CIDR notation)
+
### Cloud Run on GKE
> [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/16566) in GitLab 12.4.
diff --git a/lib/gitlab/ci/ansi2json/converter.rb b/lib/gitlab/ci/ansi2json/converter.rb
index 8d25b66af9c..908e560999e 100644
--- a/lib/gitlab/ci/ansi2json/converter.rb
+++ b/lib/gitlab/ci/ansi2json/converter.rb
@@ -22,11 +22,11 @@ module Gitlab
start_offset = @state.offset
- @state.set_current_line!(style: Style.new(@state.inherited_style))
+ @state.new_line!(
+ style: Style.new(@state.inherited_style))
stream.each_line do |line|
- s = StringScanner.new(line)
- convert_line(s)
+ consume_line(line)
end
# This must be assigned before flushing the current line
@@ -52,26 +52,43 @@ module Gitlab
private
- def convert_line(scanner)
- until scanner.eos?
-
- if scanner.scan(Gitlab::Regex.build_trace_section_regex)
- handle_section(scanner)
- elsif scanner.scan(/\e([@-_])(.*?)([@-~])/)
- handle_sequence(scanner)
- elsif scanner.scan(/\e(([@-_])(.*?)?)?$/)
- break
- elsif scanner.scan(/</)
- @state.current_line << '&lt;'
- elsif scanner.scan(/\r?\n/)
- # we advance the offset of the next current line
- # so it does not start from \n
- flush_current_line(advance_offset: scanner.matched_size)
- else
- @state.current_line << scanner.scan(/./m)
- end
-
- @state.offset += scanner.matched_size
+ def consume_line(line)
+ scanner = StringScanner.new(line)
+
+ consume_token(scanner) until scanner.eos?
+ end
+
+ def consume_token(scanner)
+ if scan_token(scanner, Gitlab::Regex.build_trace_section_regex, consume: false)
+ handle_section(scanner)
+ elsif scan_token(scanner, /\e([@-_])(.*?)([@-~])/)
+ handle_sequence(scanner)
+ elsif scan_token(scanner, /\e(([@-_])(.*?)?)?$/)
+ # stop scanning
+ scanner.terminate
+ elsif scan_token(scanner, /</)
+ @state.current_line << '&lt;'
+ elsif scan_token(scanner, /\r?\n/)
+ flush_current_line
+ elsif scan_token(scanner, /\r/)
+ # drop last line
+ @state.current_line.clear!
+ elsif scan_token(scanner, /.[^\e<\r\ns]*/m)
+ # this is a join from all previous tokens and first letters
+ # it always matches at least one character `.`
+ # it matches everything that is not start of:
+ # `\e`, `<`, `\r`, `\n`, `s` (for section_start)
+ @state.current_line << scanner[0]
+ else
+ raise 'invalid parser state'
+ end
+ end
+
+ def scan_token(scanner, match, consume: true)
+ scanner.scan(match).tap do |result|
+ # we need to move offset as soon
+ # as we match the token
+ @state.offset += scanner.matched_size if consume && result
end
end
@@ -96,32 +113,50 @@ module Gitlab
section_name = sanitize_section_name(section)
if action == "start"
- handle_section_start(section_name, timestamp)
+ handle_section_start(scanner, section_name, timestamp)
elsif action == "end"
- handle_section_end(section_name, timestamp)
+ handle_section_end(scanner, section_name, timestamp)
+ else
+ raise 'unsupported action'
end
end
- def handle_section_start(section, timestamp)
- flush_current_line unless @state.current_line.empty?
+ def handle_section_start(scanner, section, timestamp)
+ # We make a new line for new section
+ flush_current_line
+
@state.open_section(section, timestamp)
+
+ # we need to consume match after handling
+ # the open of section, as we want the section
+ # marker to be refresh on incremental update
+ @state.offset += scanner.matched_size
end
- def handle_section_end(section, timestamp)
+ def handle_section_end(scanner, section, timestamp)
return unless @state.section_open?(section)
- flush_current_line unless @state.current_line.empty?
+ # We flush the content to make the end
+ # of section to be a new line
+ flush_current_line
+
@state.close_section(section, timestamp)
- # ensure that section end is detached from the last
- # line in the section
+ # we need to consume match before handling
+ # as we want the section close marker
+ # not to be refreshed on incremental update
+ @state.offset += scanner.matched_size
+
+ # this flushes an empty line with `section_duration`
flush_current_line
end
- def flush_current_line(advance_offset: 0)
- @lines << @state.current_line.to_h
+ def flush_current_line
+ unless @state.current_line.empty?
+ @lines << @state.current_line.to_h
+ end
- @state.set_current_line!(advance_offset: advance_offset)
+ @state.new_line!
end
def sanitize_section_name(section)
diff --git a/lib/gitlab/ci/ansi2json/line.rb b/lib/gitlab/ci/ansi2json/line.rb
index 173fb1df88e..21aa1f84353 100644
--- a/lib/gitlab/ci/ansi2json/line.rb
+++ b/lib/gitlab/ci/ansi2json/line.rb
@@ -47,12 +47,17 @@ module Gitlab
@current_segment.text << data
end
+ def clear!
+ @segments.clear
+ @current_segment = Segment.new(style: style)
+ end
+
def style
@current_segment.style
end
def empty?
- @segments.empty? && @current_segment.empty?
+ @segments.empty? && @current_segment.empty? && @section_duration.nil?
end
def update_style(ansi_commands)
diff --git a/lib/gitlab/ci/ansi2json/state.rb b/lib/gitlab/ci/ansi2json/state.rb
index db7a9035b8b..7e1a8102a35 100644
--- a/lib/gitlab/ci/ansi2json/state.rb
+++ b/lib/gitlab/ci/ansi2json/state.rb
@@ -46,9 +46,9 @@ module Gitlab
@open_sections.key?(section)
end
- def set_current_line!(style: nil, advance_offset: 0)
+ def new_line!(style: nil)
new_line = Line.new(
- offset: @offset + advance_offset,
+ offset: @offset,
style: style || @current_line.style,
sections: @open_sections.keys
)
diff --git a/lib/gitlab/ci/config/entry/commands.rb b/lib/gitlab/ci/config/entry/commands.rb
index 02e368c1813..7a86fca3056 100644
--- a/lib/gitlab/ci/config/entry/commands.rb
+++ b/lib/gitlab/ci/config/entry/commands.rb
@@ -11,11 +11,11 @@ module Gitlab
include ::Gitlab::Config::Entry::Validatable
validations do
- validates :config, array_of_strings_or_string: true
+ validates :config, string_or_nested_array_of_strings: true
end
def value
- Array(@config)
+ Array(@config).flatten(1)
end
end
end
diff --git a/lib/gitlab/ci/config/entry/script.rb b/lib/gitlab/ci/config/entry/script.rb
index 9d25a82b521..285e18218b3 100644
--- a/lib/gitlab/ci/config/entry/script.rb
+++ b/lib/gitlab/ci/config/entry/script.rb
@@ -11,7 +11,11 @@ module Gitlab
include ::Gitlab::Config::Entry::Validatable
validations do
- validates :config, array_of_strings: true
+ validates :config, nested_array_of_strings: true
+ end
+
+ def value
+ config.flatten(1)
end
end
end
diff --git a/lib/gitlab/config/entry/validators.rb b/lib/gitlab/config/entry/validators.rb
index 8a04cca60d7..d1c23c41d35 100644
--- a/lib/gitlab/config/entry/validators.rb
+++ b/lib/gitlab/config/entry/validators.rb
@@ -228,6 +228,34 @@ module Gitlab
end
end
+ class NestedArrayOfStringsValidator < ArrayOfStringsOrStringValidator
+ def validate_each(record, attribute, value)
+ unless validate_nested_array_of_strings(value)
+ record.errors.add(attribute, 'should be an array containing strings and arrays of strings')
+ end
+ end
+
+ private
+
+ def validate_nested_array_of_strings(values)
+ values.is_a?(Array) && values.all? { |element| validate_array_of_strings_or_string(element) }
+ end
+ end
+
+ class StringOrNestedArrayOfStringsValidator < NestedArrayOfStringsValidator
+ def validate_each(record, attribute, value)
+ unless validate_string_or_nested_array_of_strings(value)
+ record.errors.add(attribute, 'should be a string or an array containing strings and arrays of strings')
+ end
+ end
+
+ private
+
+ def validate_string_or_nested_array_of_strings(values)
+ validate_string(values) || validate_nested_array_of_strings(values)
+ end
+ end
+
class TypeValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
type = options[:with]
diff --git a/lib/google_api/cloud_platform/client.rb b/lib/google_api/cloud_platform/client.rb
index 9085835dee6..99029b54a69 100644
--- a/lib/google_api/cloud_platform/client.rb
+++ b/lib/google_api/cloud_platform/client.rb
@@ -12,6 +12,7 @@ module GoogleApi
SCOPE = 'https://www.googleapis.com/auth/cloud-platform'
LEAST_TOKEN_LIFE_TIME = 10.minutes
CLUSTER_MASTER_AUTH_USERNAME = 'admin'
+ CLUSTER_IPV4_CIDR_BLOCK = '/16'
class << self
def session_key_for_token
@@ -97,7 +98,8 @@ module GoogleApi
enabled: legacy_abac
},
ip_allocation_policy: {
- use_ip_aliases: true
+ use_ip_aliases: true,
+ cluster_ipv4_cidr_block: CLUSTER_IPV4_CIDR_BLOCK
},
addons_config: enable_addons.each_with_object({}) do |addon, hash|
hash[addon] = { disabled: false }
diff --git a/spec/javascripts/diffs/components/diff_file_spec.js b/spec/javascripts/diffs/components/diff_file_spec.js
index 3ca2d1dc934..6ffdb6ba85d 100644
--- a/spec/javascripts/diffs/components/diff_file_spec.js
+++ b/spec/javascripts/diffs/components/diff_file_spec.js
@@ -3,14 +3,15 @@ import DiffFileComponent from '~/diffs/components/diff_file.vue';
import { diffViewerModes, diffViewerErrors } from '~/ide/constants';
import { createStore } from 'ee_else_ce/mr_notes/stores';
import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
-import diffFileMockData from '../mock_data/diff_file';
+import diffFileMockDataReadable from '../mock_data/diff_file';
+import diffFileMockDataUnreadable from '../mock_data/diff_file_unreadable';
describe('DiffFile', () => {
let vm;
beforeEach(() => {
vm = createComponentWithStore(Vue.extend(DiffFileComponent), createStore(), {
- file: JSON.parse(JSON.stringify(diffFileMockData)),
+ file: JSON.parse(JSON.stringify(diffFileMockDataReadable)),
canCurrentUserFork: false,
}).$mount();
});
@@ -81,6 +82,24 @@ describe('DiffFile', () => {
});
});
+ it('should be collapsable for unreadable files', done => {
+ vm.$destroy();
+ vm = createComponentWithStore(Vue.extend(DiffFileComponent), createStore(), {
+ file: JSON.parse(JSON.stringify(diffFileMockDataUnreadable)),
+ canCurrentUserFork: false,
+ }).$mount();
+
+ vm.renderIt = false;
+ vm.isCollapsed = true;
+
+ vm.$nextTick(() => {
+ expect(vm.$el.innerText).toContain('This diff is collapsed');
+ expect(vm.$el.querySelectorAll('.js-click-to-expand').length).toEqual(1);
+
+ done();
+ });
+ });
+
it('should be collapsed for renamed files', done => {
vm.renderIt = true;
vm.isCollapsed = false;
@@ -184,5 +203,31 @@ describe('DiffFile', () => {
.then(done)
.catch(done.fail);
});
+
+ it('does not call handleLoadCollapsedDiff if collapsed changed & file is unreadable', done => {
+ vm.$destroy();
+ vm = createComponentWithStore(Vue.extend(DiffFileComponent), createStore(), {
+ file: JSON.parse(JSON.stringify(diffFileMockDataUnreadable)),
+ canCurrentUserFork: false,
+ }).$mount();
+
+ spyOn(vm, 'handleLoadCollapsedDiff');
+
+ vm.file.highlighted_diff_lines = undefined;
+ vm.file.parallel_diff_lines = [];
+ vm.isCollapsed = true;
+
+ vm.$nextTick()
+ .then(() => {
+ vm.isCollapsed = false;
+
+ return vm.$nextTick();
+ })
+ .then(() => {
+ expect(vm.handleLoadCollapsedDiff).not.toHaveBeenCalled();
+ })
+ .then(done)
+ .catch(done.fail);
+ });
});
});
diff --git a/spec/javascripts/diffs/mock_data/diff_file_unreadable.js b/spec/javascripts/diffs/mock_data/diff_file_unreadable.js
new file mode 100644
index 00000000000..8c2df45988e
--- /dev/null
+++ b/spec/javascripts/diffs/mock_data/diff_file_unreadable.js
@@ -0,0 +1,244 @@
+export default {
+ submodule: false,
+ submodule_link: null,
+ blob: {
+ id: '9e10516ca50788acf18c518a231914a21e5f16f7',
+ path: 'CHANGELOG',
+ name: 'CHANGELOG',
+ mode: '100644',
+ readable_text: false,
+ icon: 'file-text-o',
+ },
+ blob_path: 'CHANGELOG',
+ blob_name: 'CHANGELOG',
+ blob_icon: '<i aria-hidden="true" data-hidden="true" class="fa fa-file-text-o fa-fw"></i>',
+ file_hash: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a',
+ file_path: 'CHANGELOG',
+ new_file: false,
+ deleted_file: false,
+ renamed_file: false,
+ old_path: 'CHANGELOG',
+ new_path: 'CHANGELOG',
+ mode_changed: false,
+ a_mode: '100644',
+ b_mode: '100644',
+ text: true,
+ viewer: {
+ name: 'text',
+ error: null,
+ collapsed: false,
+ },
+ added_lines: 0,
+ removed_lines: 0,
+ diff_refs: {
+ base_sha: 'e63f41fe459e62e1228fcef60d7189127aeba95a',
+ start_sha: 'd9eaefe5a676b820c57ff18cf5b68316025f7962',
+ head_sha: 'c48ee0d1bf3b30453f5b32250ce03134beaa6d13',
+ },
+ content_sha: 'c48ee0d1bf3b30453f5b32250ce03134beaa6d13',
+ stored_externally: null,
+ external_storage: null,
+ old_path_html: 'CHANGELOG',
+ new_path_html: 'CHANGELOG',
+ edit_path: '/gitlab-org/gitlab-test/edit/spooky-stuff/CHANGELOG',
+ view_path: '/gitlab-org/gitlab-test/blob/spooky-stuff/CHANGELOG',
+ replaced_view_path: null,
+ collapsed: false,
+ renderIt: false,
+ too_large: false,
+ context_lines_path:
+ '/gitlab-org/gitlab-test/blob/c48ee0d1bf3b30453f5b32250ce03134beaa6d13/CHANGELOG/diff',
+ highlighted_diff_lines: [
+ {
+ line_code: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_1_1',
+ type: 'new',
+ old_line: null,
+ new_line: 1,
+ discussions: [],
+ text: '+<span id="LC1" class="line" lang="plaintext"> - Bad dates</span>\n',
+ rich_text: '+<span id="LC1" class="line" lang="plaintext"> - Bad dates</span>\n',
+ meta_data: null,
+ },
+ {
+ line_code: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_1_2',
+ type: 'new',
+ old_line: null,
+ new_line: 2,
+ discussions: [],
+ text: '+<span id="LC2" class="line" lang="plaintext"></span>\n',
+ rich_text: '+<span id="LC2" class="line" lang="plaintext"></span>\n',
+ meta_data: null,
+ },
+ {
+ line_code: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_1_3',
+ type: null,
+ old_line: 1,
+ new_line: 3,
+ discussions: [],
+ text: ' <span id="LC3" class="line" lang="plaintext">v6.8.0</span>\n',
+ rich_text: ' <span id="LC3" class="line" lang="plaintext">v6.8.0</span>\n',
+ meta_data: null,
+ },
+ {
+ line_code: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_2_4',
+ type: null,
+ old_line: 2,
+ new_line: 4,
+ discussions: [],
+ text: ' <span id="LC4" class="line" lang="plaintext"></span>\n',
+ rich_text: ' <span id="LC4" class="line" lang="plaintext"></span>\n',
+ meta_data: null,
+ },
+ {
+ line_code: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_3_5',
+ type: null,
+ old_line: 3,
+ new_line: 5,
+ discussions: [],
+ text: ' <span id="LC5" class="line" lang="plaintext">v6.7.0</span>\n',
+ rich_text: ' <span id="LC5" class="line" lang="plaintext">v6.7.0</span>\n',
+ meta_data: null,
+ },
+ {
+ line_code: null,
+ type: 'match',
+ old_line: null,
+ new_line: null,
+ discussions: [],
+ text: '',
+ rich_text: '',
+ meta_data: {
+ old_pos: 3,
+ new_pos: 5,
+ },
+ },
+ ],
+ parallel_diff_lines: [
+ {
+ left: {
+ type: 'empty-cell',
+ },
+ right: {
+ line_code: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_1_1',
+ type: 'new',
+ old_line: null,
+ new_line: 1,
+ discussions: [],
+ text: '+<span id="LC1" class="line" lang="plaintext"> - Bad dates</span>\n',
+ rich_text: '<span id="LC1" class="line" lang="plaintext"> - Bad dates</span>\n',
+ meta_data: null,
+ },
+ },
+ {
+ left: {
+ type: 'empty-cell',
+ },
+ right: {
+ line_code: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_1_2',
+ type: 'new',
+ old_line: null,
+ new_line: 2,
+ discussions: [],
+ text: '+<span id="LC2" class="line" lang="plaintext"></span>\n',
+ rich_text: '<span id="LC2" class="line" lang="plaintext"></span>\n',
+ meta_data: null,
+ },
+ },
+ {
+ left: {
+ line_Code: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_1_3',
+ type: null,
+ old_line: 1,
+ new_line: 3,
+ discussions: [],
+ text: ' <span id="LC3" class="line" lang="plaintext">v6.8.0</span>\n',
+ rich_text: '<span id="LC3" class="line" lang="plaintext">v6.8.0</span>\n',
+ meta_data: null,
+ },
+ right: {
+ line_code: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_1_3',
+ type: null,
+ old_line: 1,
+ new_line: 3,
+ discussions: [],
+ text: ' <span id="LC3" class="line" lang="plaintext">v6.8.0</span>\n',
+ rich_text: '<span id="LC3" class="line" lang="plaintext">v6.8.0</span>\n',
+ meta_data: null,
+ },
+ },
+ {
+ left: {
+ line_code: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_2_4',
+ type: null,
+ old_line: 2,
+ new_line: 4,
+ discussions: [],
+ text: ' <span id="LC4" class="line" lang="plaintext"></span>\n',
+ rich_text: '<span id="LC4" class="line" lang="plaintext"></span>\n',
+ meta_data: null,
+ },
+ right: {
+ line_code: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_2_4',
+ type: null,
+ old_line: 2,
+ new_line: 4,
+ discussions: [],
+ text: ' <span id="LC4" class="line" lang="plaintext"></span>\n',
+ rich_text: '<span id="LC4" class="line" lang="plaintext"></span>\n',
+ meta_data: null,
+ },
+ },
+ {
+ left: {
+ line_code: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_3_5',
+ type: null,
+ old_line: 3,
+ new_line: 5,
+ discussions: [],
+ text: ' <span id="LC5" class="line" lang="plaintext">v6.7.0</span>\n',
+ rich_text: '<span id="LC5" class="line" lang="plaintext">v6.7.0</span>\n',
+ meta_data: null,
+ },
+ right: {
+ line_code: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_3_5',
+ type: null,
+ old_line: 3,
+ new_line: 5,
+ discussions: [],
+ text: ' <span id="LC5" class="line" lang="plaintext">v6.7.0</span>\n',
+ rich_text: '<span id="LC5" class="line" lang="plaintext">v6.7.0</span>\n',
+ meta_data: null,
+ },
+ },
+ {
+ left: {
+ line_code: null,
+ type: 'match',
+ old_line: null,
+ new_line: null,
+ discussions: [],
+ text: '',
+ rich_text: '',
+ meta_data: {
+ old_pos: 3,
+ new_pos: 5,
+ },
+ },
+ right: {
+ line_code: null,
+ type: 'match',
+ old_line: null,
+ new_line: null,
+ discussions: [],
+ text: '',
+ rich_text: '',
+ meta_data: {
+ old_pos: 3,
+ new_pos: 5,
+ },
+ },
+ },
+ ],
+ discussions: [],
+ renderingLines: false,
+};
diff --git a/spec/lib/gitlab/ci/ansi2json_spec.rb b/spec/lib/gitlab/ci/ansi2json_spec.rb
index 3c6bc46436b..3cd448d1aae 100644
--- a/spec/lib/gitlab/ci/ansi2json_spec.rb
+++ b/spec/lib/gitlab/ci/ansi2json_spec.rb
@@ -12,11 +12,26 @@ describe Gitlab::Ci::Ansi2json do
])
end
- it 'adds new line in a separate element' do
- expect(convert_json("Hello\nworld")).to eq([
- { offset: 0, content: [{ text: 'Hello' }] },
- { offset: 6, content: [{ text: 'world' }] }
- ])
+ context 'new lines' do
+ it 'adds new line when encountering \n' do
+ expect(convert_json("Hello\nworld")).to eq([
+ { offset: 0, content: [{ text: 'Hello' }] },
+ { offset: 6, content: [{ text: 'world' }] }
+ ])
+ end
+
+ it 'adds new line when encountering \r\n' do
+ expect(convert_json("Hello\r\nworld")).to eq([
+ { offset: 0, content: [{ text: 'Hello' }] },
+ { offset: 7, content: [{ text: 'world' }] }
+ ])
+ end
+
+ it 'replace the current line when encountering \r' do
+ expect(convert_json("Hello\rworld")).to eq([
+ { offset: 0, content: [{ text: 'world' }] }
+ ])
+ end
end
it 'recognizes color changing ANSI sequences' do
@@ -113,10 +128,6 @@ describe Gitlab::Ci::Ansi2json do
content: [],
section_duration: '01:03',
section: 'prepare-script'
- },
- {
- offset: 63,
- content: []
}
])
end
@@ -134,10 +145,6 @@ describe Gitlab::Ci::Ansi2json do
content: [],
section: 'prepare-script',
section_duration: '01:03'
- },
- {
- offset: 56,
- content: []
}
])
end
@@ -157,7 +164,7 @@ describe Gitlab::Ci::Ansi2json do
section_duration: '01:03'
},
{
- offset: 49,
+ offset: 91,
content: [{ text: 'world' }]
}
])
@@ -198,7 +205,7 @@ describe Gitlab::Ci::Ansi2json do
expect(convert_json("#{section_start}hello")).to eq([
{
offset: 0,
- content: [{ text: "#{section_start.gsub("\033[0K", '')}hello" }]
+ content: [{ text: 'hello' }]
}
])
end
@@ -211,7 +218,7 @@ describe Gitlab::Ci::Ansi2json do
expect(convert_json("#{section_start}hello")).to eq([
{
offset: 0,
- content: [{ text: "#{section_start.gsub("\033[0K", '').gsub('<', '&lt;')}hello" }]
+ content: [{ text: 'hello' }]
}
])
end
@@ -231,10 +238,6 @@ describe Gitlab::Ci::Ansi2json do
content: [],
section: 'prepare-script',
section_duration: '01:03'
- },
- {
- offset: 95,
- content: []
}
])
end
@@ -274,7 +277,7 @@ describe Gitlab::Ci::Ansi2json do
section_duration: '00:02'
},
{
- offset: 106,
+ offset: 155,
content: [{ text: 'baz' }],
section: 'prepare-script'
},
@@ -285,7 +288,7 @@ describe Gitlab::Ci::Ansi2json do
section_duration: '01:03'
},
{
- offset: 158,
+ offset: 200,
content: [{ text: 'world' }]
}
])
@@ -318,14 +321,10 @@ describe Gitlab::Ci::Ansi2json do
section_duration: '00:02'
},
{
- offset: 115,
+ offset: 164,
content: [],
section: 'prepare-script',
section_duration: '01:03'
- },
- {
- offset: 164,
- content: []
}
])
end
@@ -380,7 +379,7 @@ describe Gitlab::Ci::Ansi2json do
]
end
- it 'returns the full line' do
+ it 'returns the line since last partially processed line' do
expect(pass2.lines).to eq(lines)
expect(pass2.append).to be_truthy
end
@@ -399,7 +398,7 @@ describe Gitlab::Ci::Ansi2json do
]
end
- it 'returns the full line' do
+ it 'returns the line since last partially processed line' do
expect(pass2.lines).to eq(lines)
expect(pass2.append).to be_falsey
end
@@ -416,7 +415,7 @@ describe Gitlab::Ci::Ansi2json do
]
end
- it 'returns the full line' do
+ it 'returns a blank line and the next line' do
expect(pass2.lines).to eq(lines)
expect(pass2.append).to be_falsey
end
@@ -502,10 +501,6 @@ describe Gitlab::Ci::Ansi2json do
content: [],
section: 'prepare-script',
section_duration: '01:03'
- },
- {
- offset: 77,
- content: []
}
]
end
diff --git a/spec/lib/gitlab/ci/config/entry/commands_spec.rb b/spec/lib/gitlab/ci/config/entry/commands_spec.rb
index 269a3406913..8e7f9ab9706 100644
--- a/spec/lib/gitlab/ci/config/entry/commands_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/commands_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
describe Gitlab::Ci::Config::Entry::Commands do
let(:entry) { described_class.new(config) }
- context 'when entry config value is an array' do
+ context 'when entry config value is an array of strings' do
let(:config) { %w(ls pwd) }
describe '#value' do
@@ -37,13 +37,74 @@ describe Gitlab::Ci::Config::Entry::Commands do
end
end
- context 'when entry value is not valid' do
+ context 'when entry config value is array of arrays of strings' do
+ let(:config) { [['ls'], ['pwd', 'echo 1']] }
+
+ describe '#value' do
+ it 'returns array of strings' do
+ expect(entry.value).to eq ['ls', 'pwd', 'echo 1']
+ end
+ end
+
+ describe '#errors' do
+ it 'does not append errors' do
+ expect(entry.errors).to be_empty
+ end
+ end
+
+ describe '#valid?' do
+ it 'is valid' do
+ expect(entry).to be_valid
+ end
+ end
+ end
+
+ context 'when entry config value is array of strings and arrays of strings' do
+ let(:config) { ['ls', ['pwd', 'echo 1']] }
+
+ describe '#value' do
+ it 'returns array of strings' do
+ expect(entry.value).to eq ['ls', 'pwd', 'echo 1']
+ end
+ end
+
+ describe '#errors' do
+ it 'does not append errors' do
+ expect(entry.errors).to be_empty
+ end
+ end
+
+ describe '#valid?' do
+ it 'is valid' do
+ expect(entry).to be_valid
+ end
+ end
+ end
+
+ context 'when entry value is integer' do
let(:config) { 1 }
describe '#errors' do
it 'saves errors' do
expect(entry.errors)
- .to include 'commands config should be an array of strings or a string'
+ .to include 'commands config should be a string or an array containing strings and arrays of strings'
+ end
+ end
+ end
+
+ context 'when entry value is multi-level nested array' do
+ let(:config) { [['ls', ['echo 1']], 'pwd'] }
+
+ describe '#errors' do
+ it 'saves errors' do
+ expect(entry.errors)
+ .to include 'commands config should be a string or an array containing strings and arrays of strings'
+ end
+ end
+
+ describe '#valid?' do
+ it 'is not valid' do
+ expect(entry).not_to be_valid
end
end
end
diff --git a/spec/lib/gitlab/ci/config/entry/root_spec.rb b/spec/lib/gitlab/ci/config/entry/root_spec.rb
index 8243fcfd162..3877eec8887 100644
--- a/spec/lib/gitlab/ci/config/entry/root_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/root_spec.rb
@@ -298,7 +298,7 @@ describe Gitlab::Ci::Config::Entry::Root do
describe '#errors' do
it 'reports errors from child nodes' do
expect(root.errors)
- .to include 'before_script config should be an array of strings'
+ .to include 'before_script config should be an array containing strings and arrays of strings'
end
end
end
diff --git a/spec/lib/gitlab/ci/config/entry/script_spec.rb b/spec/lib/gitlab/ci/config/entry/script_spec.rb
index d523243d3b6..57dc20ea628 100644
--- a/spec/lib/gitlab/ci/config/entry/script_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/script_spec.rb
@@ -6,7 +6,7 @@ describe Gitlab::Ci::Config::Entry::Script do
let(:entry) { described_class.new(config) }
describe 'validations' do
- context 'when entry config value is correct' do
+ context 'when entry config value is array of strings' do
let(:config) { %w(ls pwd) }
describe '#value' do
@@ -28,13 +28,74 @@ describe Gitlab::Ci::Config::Entry::Script do
end
end
- context 'when entry value is not correct' do
+ context 'when entry config value is array of arrays of strings' do
+ let(:config) { [['ls'], ['pwd', 'echo 1']] }
+
+ describe '#value' do
+ it 'returns array of strings' do
+ expect(entry.value).to eq ['ls', 'pwd', 'echo 1']
+ end
+ end
+
+ describe '#errors' do
+ it 'does not append errors' do
+ expect(entry.errors).to be_empty
+ end
+ end
+
+ describe '#valid?' do
+ it 'is valid' do
+ expect(entry).to be_valid
+ end
+ end
+ end
+
+ context 'when entry config value is array containing strings and arrays of strings' do
+ let(:config) { ['ls', ['pwd', 'echo 1']] }
+
+ describe '#value' do
+ it 'returns array of strings' do
+ expect(entry.value).to eq ['ls', 'pwd', 'echo 1']
+ end
+ end
+
+ describe '#errors' do
+ it 'does not append errors' do
+ expect(entry.errors).to be_empty
+ end
+ end
+
+ describe '#valid?' do
+ it 'is valid' do
+ expect(entry).to be_valid
+ end
+ end
+ end
+
+ context 'when entry value is string' do
let(:config) { 'ls' }
describe '#errors' do
it 'saves errors' do
expect(entry.errors)
- .to include 'script config should be an array of strings'
+ .to include 'script config should be an array containing strings and arrays of strings'
+ end
+ end
+
+ describe '#valid?' do
+ it 'is not valid' do
+ expect(entry).not_to be_valid
+ end
+ end
+ end
+
+ context 'when entry value is multi-level nested array' do
+ let(:config) { [['ls', ['echo 1']], 'pwd'] }
+
+ describe '#errors' do
+ it 'saves errors' do
+ expect(entry.errors)
+ .to include 'script config should be an array containing strings and arrays of strings'
end
end
diff --git a/spec/lib/gitlab/ci/pipeline/chain/validate/config_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/validate/config_spec.rb
index 79acd3e4f54..e23aa09d881 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/validate/config_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/validate/config_spec.rb
@@ -94,7 +94,7 @@ describe Gitlab::Ci::Pipeline::Chain::Validate::Config do
it 'appends configuration validation errors to pipeline errors' do
expect(pipeline.errors.to_a)
- .to include "jobs:rspec:before_script config should be an array of strings"
+ .to include "jobs:rspec:before_script config should be an array containing strings and arrays of strings"
end
it 'breaks the chain' do
diff --git a/spec/lib/gitlab/ci/yaml_processor_spec.rb b/spec/lib/gitlab/ci/yaml_processor_spec.rb
index 375075ce8f3..c7ea6ed9ddb 100644
--- a/spec/lib/gitlab/ci/yaml_processor_spec.rb
+++ b/spec/lib/gitlab/ci/yaml_processor_spec.rb
@@ -330,7 +330,7 @@ module Gitlab
}
end
- it "return commands with scripts concencaced" do
+ it "return commands with scripts concatenated" do
expect(subject[:options][:before_script]).to eq(["global script"])
end
end
@@ -343,7 +343,7 @@ module Gitlab
}
end
- it "return commands with scripts concencaced" do
+ it "return commands with scripts concatenated" do
expect(subject[:options][:before_script]).to eq(["global script"])
end
end
@@ -356,21 +356,48 @@ module Gitlab
}
end
- it "return commands with scripts concencaced" do
+ it "return commands with scripts concatenated" do
expect(subject[:options][:before_script]).to eq(["local script"])
end
end
+
+ context 'when script is array of arrays of strings' do
+ let(:config) do
+ {
+ before_script: [["global script", "echo 1"], ["ls"], "pwd"],
+ test: { script: ["script"] }
+ }
+ end
+
+ it "return commands with scripts concatenated" do
+ expect(subject[:options][:before_script]).to eq(["global script", "echo 1", "ls", "pwd"])
+ end
+ end
end
describe "script" do
- let(:config) do
- {
- test: { script: ["script"] }
- }
+ context 'when script is array of strings' do
+ let(:config) do
+ {
+ test: { script: ["script"] }
+ }
+ end
+
+ it "return commands with scripts concatenated" do
+ expect(subject[:options][:script]).to eq(["script"])
+ end
end
- it "return commands with scripts concencaced" do
- expect(subject[:options][:script]).to eq(["script"])
+ context 'when script is array of arrays of strings' do
+ let(:config) do
+ {
+ test: { script: [["script"], ["echo 1"], "ls"] }
+ }
+ end
+
+ it "return commands with scripts concatenated" do
+ expect(subject[:options][:script]).to eq(["script", "echo 1", "ls"])
+ end
end
end
@@ -413,6 +440,19 @@ module Gitlab
expect(subject[:options][:after_script]).to eq(["local after_script"])
end
end
+
+ context 'when script is array of arrays of strings' do
+ let(:config) do
+ {
+ after_script: [["global script", "echo 1"], ["ls"], "pwd"],
+ test: { script: ["script"] }
+ }
+ end
+
+ it "return after_script in options" do
+ expect(subject[:options][:after_script]).to eq(["global script", "echo 1", "ls", "pwd"])
+ end
+ end
end
end
@@ -1536,28 +1576,42 @@ module Gitlab
config = YAML.dump({ before_script: "bundle update", rspec: { script: "test" } })
expect do
Gitlab::Ci::YamlProcessor.new(config)
- end.to raise_error(Gitlab::Ci::YamlProcessor::ValidationError, "before_script config should be an array of strings")
+ end.to raise_error(Gitlab::Ci::YamlProcessor::ValidationError, "before_script config should be an array containing strings and arrays of strings")
end
it "returns errors if job before_script parameter is not an array of strings" do
config = YAML.dump({ rspec: { script: "test", before_script: [10, "test"] } })
expect do
Gitlab::Ci::YamlProcessor.new(config)
- end.to raise_error(Gitlab::Ci::YamlProcessor::ValidationError, "jobs:rspec:before_script config should be an array of strings")
+ end.to raise_error(Gitlab::Ci::YamlProcessor::ValidationError, "jobs:rspec:before_script config should be an array containing strings and arrays of strings")
+ end
+
+ it "returns errors if job before_script parameter is multi-level nested array of strings" do
+ config = YAML.dump({ rspec: { script: "test", before_script: [["ls", ["pwd"]], "test"] } })
+ expect do
+ Gitlab::Ci::YamlProcessor.new(config)
+ end.to raise_error(Gitlab::Ci::YamlProcessor::ValidationError, "jobs:rspec:before_script config should be an array containing strings and arrays of strings")
end
it "returns errors if after_script parameter is invalid" do
config = YAML.dump({ after_script: "bundle update", rspec: { script: "test" } })
expect do
Gitlab::Ci::YamlProcessor.new(config)
- end.to raise_error(Gitlab::Ci::YamlProcessor::ValidationError, "after_script config should be an array of strings")
+ end.to raise_error(Gitlab::Ci::YamlProcessor::ValidationError, "after_script config should be an array containing strings and arrays of strings")
end
it "returns errors if job after_script parameter is not an array of strings" do
config = YAML.dump({ rspec: { script: "test", after_script: [10, "test"] } })
expect do
Gitlab::Ci::YamlProcessor.new(config)
- end.to raise_error(Gitlab::Ci::YamlProcessor::ValidationError, "jobs:rspec:after_script config should be an array of strings")
+ end.to raise_error(Gitlab::Ci::YamlProcessor::ValidationError, "jobs:rspec:after_script config should be an array containing strings and arrays of strings")
+ end
+
+ it "returns errors if job after_script parameter is multi-level nested array of strings" do
+ config = YAML.dump({ rspec: { script: "test", after_script: [["ls", ["pwd"]], "test"] } })
+ expect do
+ Gitlab::Ci::YamlProcessor.new(config)
+ end.to raise_error(Gitlab::Ci::YamlProcessor::ValidationError, "jobs:rspec:after_script config should be an array containing strings and arrays of strings")
end
it "returns errors if image parameter is invalid" do
diff --git a/spec/lib/google_api/cloud_platform/client_spec.rb b/spec/lib/google_api/cloud_platform/client_spec.rb
index 0f7f57095df..473ad639ead 100644
--- a/spec/lib/google_api/cloud_platform/client_spec.rb
+++ b/spec/lib/google_api/cloud_platform/client_spec.rb
@@ -104,7 +104,8 @@ describe GoogleApi::CloudPlatform::Client do
enabled: legacy_abac
},
ip_allocation_policy: {
- use_ip_aliases: true
+ use_ip_aliases: true,
+ cluster_ipv4_cidr_block: '/16'
},
addons_config: addons_config
}