Commit 6929e1c3 authored by GitLab Bot's avatar GitLab Bot

Merge remote-tracking branch 'upstream/master' into ce-to-ee-2018-08-15

# Conflicts:
#	db/schema.rb
#	doc/README.md
#	doc/ci/examples/README.md
#	doc/user/project/merge_requests/index.md
#	locale/gitlab.pot

[ci skip]
parents 087673ac 353360ef
......@@ -12,7 +12,7 @@ Set the title to: `[Security] Description of the original issue`
- [ ] Link to the original issue adding it to the [links section](#links)
- [ ] Run `scripts/security-harness` in the CE, EE, and/or Omnibus to prevent pushing to any remote besides `dev.gitlab.org`
- [ ] Create an MR targetting `org` `master`, prefixing your branch with `security-`
- [ ] Label your MR with the ~security label, prefix the title with `WIP: [master]`
- [ ] Label your MR with the ~security label, prefix the title with `WIP: [master]`
- [ ] Add a link to the MR to the [links section](#links)
- [ ] Add a link to an EE MR if required
- [ ] Make sure the MR remains in-progress and gets approved after the review cycle, **but never merged**.
......@@ -22,13 +22,13 @@ Set the title to: `[Security] Description of the original issue`
- [ ] Once the MR is ready to be merged, create MRs targetting the last 3 releases
- [ ] At this point, it might be easy to squash the commits from the MR into one
- You can use the script `bin/secpick` instead of the following steps, to help you cherry-picking. See the [seckpick documentation]
- You can use the script `bin/secpick` instead of the following steps, to help you cherry-picking. See the [secpick documentation]
- [ ] Create the branch `security-X-Y` from `X-Y-stable` if it doesn't exist (and make sure it's up to date with stable)
- [ ] Create each MR targetting the security branch `security-X-Y`
- [ ] Add the ~security label and prefix with the version `WIP: [X.Y]` the title of the MR
- [ ] Make sure all MRs have a link in the [links section](#links) and are assigned to a Release Manager.
[seckpick documentation]: https://gitlab.com/gitlab-org/release/docs/blob/master/general/security/developer.md#secpick-script
[secpick documentation]: https://gitlab.com/gitlab-org/release/docs/blob/master/general/security/developer.md#secpick-script
#### Documentation and final details
......@@ -68,4 +68,4 @@ Set the title to: `[Security] Description of the original issue`
[security process for developers]: https://gitlab.com/gitlab-org/release/docs/blob/master/general/security/developer.md
[RM list]: https://about.gitlab.com/release-managers/
/label ~security
/label ~security
......@@ -190,7 +190,7 @@ gem 'rufus-scheduler', '~> 3.4'
gem 'httparty', '~> 0.13.3'
# Colored output to console
gem 'rainbow', '~> 2.2'
gem 'rainbow', '~> 3.0'
# Progress bar
gem 'ruby-progressbar'
......
......@@ -720,8 +720,7 @@ GEM
activesupport (= 4.2.10)
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
rainbow (2.2.2)
rake
rainbow (3.0.0)
raindrops (0.18.0)
rake (12.3.1)
rb-fsevent (0.10.2)
......@@ -1171,7 +1170,7 @@ DEPENDENCIES
rails (= 4.2.10)
rails-deprecated_sanitizer (~> 1.0.3)
rails-i18n (~> 4.0.9)
rainbow (~> 2.2)
rainbow (~> 3.0)
raindrops (~> 0.18)
rblineprof (~> 0.3.6)
rbtrace (~> 0.4)
......
......@@ -730,8 +730,7 @@ GEM
method_source
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
rainbow (2.2.2)
rake
rainbow (3.0.0)
raindrops (0.18.0)
rake (12.3.1)
rb-fsevent (0.10.2)
......@@ -1184,7 +1183,7 @@ DEPENDENCIES
rails-controller-testing
rails-deprecated_sanitizer (~> 1.0.3)
rails-i18n (~> 5.1)
rainbow (~> 2.2)
rainbow (~> 3.0)
raindrops (~> 0.18)
rblineprof (~> 0.3.6)
rbtrace (~> 0.4)
......
......@@ -8,6 +8,7 @@ import 'core-js/fn/object/assign';
import 'core-js/fn/promise';
import 'core-js/fn/string/code-point-at';
import 'core-js/fn/string/from-code-point';
import 'core-js/fn/string/includes';
import 'core-js/fn/symbol';
import 'core-js/es6/map';
import 'core-js/es6/weak-map';
......
......@@ -114,11 +114,15 @@ export default {
this.adjustView();
},
methods: {
...mapActions('diffs', ['setBaseConfig', 'fetchDiffFiles']),
...mapActions('diffs', ['setBaseConfig', 'fetchDiffFiles', 'startRenderDiffsQueue']),
fetchData() {
this.fetchDiffFiles().catch(() => {
createFlash(__('Something went wrong on our end. Please try again!'));
});
this.fetchDiffFiles()
.then(() => {
requestIdleCallback(this.startRenderDiffsQueue, { timeout: 1000 });
})
.catch(() => {
createFlash(__('Something went wrong on our end. Please try again!'));
});
if (!this.isNotesFetched) {
eventHub.$emit('fetchNotesData');
......
......@@ -46,16 +46,25 @@ export default {
showExpandMessage() {
return this.isCollapsed && !this.isLoadingCollapsedDiff && !this.file.tooLarge;
},
showLoadingIcon() {
return this.isLoadingCollapsedDiff || (!this.file.renderIt && !this.isCollapsed);
},
},
methods: {
...mapActions('diffs', ['loadCollapsedDiff']),
handleToggle() {
const { collapsed, highlightedDiffLines, parallelDiffLines } = this.file;
if (collapsed && !highlightedDiffLines && !parallelDiffLines.length) {
if (
collapsed &&
!highlightedDiffLines &&
parallelDiffLines !== undefined &&
!parallelDiffLines.length
) {
this.handleLoadCollapsedDiff();
} else {
this.file.collapsed = !this.file.collapsed;
this.file.renderIt = true;
}
},
handleLoadCollapsedDiff() {
......@@ -65,6 +74,7 @@ export default {
.then(() => {
this.isLoadingCollapsedDiff = false;
this.file.collapsed = false;
this.file.renderIt = true;
})
.catch(() => {
this.isLoadingCollapsedDiff = false;
......@@ -121,12 +131,12 @@ export default {
</div>
<diff-content
v-if="!isCollapsed"
v-if="!isCollapsed && file.renderIt"
:class="{ hidden: isCollapsed || file.tooLarge }"
:diff-file="file"
/>
<loading-icon
v-if="isLoadingCollapsedDiff"
v-else-if="showLoadingIcon"
class="diff-content loading"
/>
<div
......
......@@ -25,3 +25,6 @@ export const CONTEXT_LINE_CLASS_NAME = 'diff-expanded';
export const UNFOLD_COUNT = 20;
export const COUNT_OF_AVATARS_IN_GUTTER = 3;
export const LENGTH_OF_AVATAR_TOOLTIP = 17;
export const LINES_TO_BE_RENDERED_DIRECTLY = 100;
export const MAX_LINES_TO_BE_RENDERED = 2000;
......@@ -29,6 +29,27 @@ export const fetchDiffFiles = ({ state, commit }) => {
.then(handleLocationHash);
};
export const startRenderDiffsQueue = ({ state, commit }) => {
const checkItem = () => {
const nextFile = state.diffFiles.find(
file => !file.renderIt && (!file.collapsed || !file.text),
);
if (nextFile) {
requestAnimationFrame(() => {
commit(types.RENDER_FILE, nextFile);
});
requestIdleCallback(
() => {
checkItem();
},
{ timeout: 1000 },
);
}
};
checkItem();
};
export const setInlineDiffViewType = ({ commit }) => {
commit(types.SET_DIFF_VIEW_TYPE, INLINE_DIFF_VIEW_TYPE);
......
......@@ -8,3 +8,4 @@ export const REMOVE_COMMENT_FORM_LINE = 'REMOVE_COMMENT_FORM_LINE';
export const ADD_CONTEXT_LINES = 'ADD_CONTEXT_LINES';
export const ADD_COLLAPSED_DIFFS = 'ADD_COLLAPSED_DIFFS';
export const EXPAND_ALL_FILES = 'EXPAND_ALL_FILES';
export const RENDER_FILE = 'RENDER_FILE';
......@@ -2,6 +2,7 @@ import Vue from 'vue';
import _ from 'underscore';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { findDiffFile, addLineReferences, removeMatchLine, addContextLines } from './utils';
import { LINES_TO_BE_RENDERED_DIRECTLY, MAX_LINES_TO_BE_RENDERED } from '../constants';
import * as types from './mutation_types';
export default {
......@@ -15,8 +16,48 @@ export default {
},
[types.SET_DIFF_DATA](state, data) {
const diffData = convertObjectPropsToCamelCase(data, { deep: true });
let showingLines = 0;
const filesLength = diffData.diffFiles.length;
let i;
for (i = 0; i < filesLength; i += 1) {
const file = diffData.diffFiles[i];
if (file.parallelDiffLines) {
const linesLength = file.parallelDiffLines.length;
let u = 0;
for (u = 0; u < linesLength; u += 1) {
const line = file.parallelDiffLines[u];
if (line.left) delete line.left.text;
if (line.right) delete line.right.text;
}
}
if (file.highlightedDiffLines) {
const linesLength = file.highlightedDiffLines.length;
let u;
for (u = 0; u < linesLength; u += 1) {
const line = file.highlightedDiffLines[u];
delete line.text;
}
}
if (file.highlightedDiffLines) {
showingLines += file.parallelDiffLines.length;
}
Object.assign(file, {
renderIt: showingLines < LINES_TO_BE_RENDERED_DIRECTLY,
collapsed: file.text && showingLines > MAX_LINES_TO_BE_RENDERED,
});
}
Object.assign(state, {
...convertObjectPropsToCamelCase(data, { deep: true }),
...diffData,
});
},
[types.RENDER_FILE](state, file) {
Object.assign(file, {
renderIt: true,
});
},
......
<script>
import TimeagoTooltiop from '~/vue_shared/components/time_ago_tooltip.vue';
export default {
components: {
TimeagoTooltiop,
},
props: {
// @build.artifacts_expired?
haveArtifactsExpired: {
type: Boolean,
required: true,
},
// @build.has_expiring_artifacts?
willArtifactsExpire: {
type: Boolean,
required: true,
},
expireAt: {
type: String,
required: false,
default: null,
},
keepArtifactsPath: {
type: String,
required: false,
default: null,
},
downloadArtifactsPath: {
type: String,
required: false,
default: null,
},
browseArtifactsPath: {
type: String,
required: false,
default: null,
},
},
};
</script>
<template>
<div class="block">
<div class="title">
{{ s__('Job|Job artifacts') }}
</div>
<p
v-if="haveArtifactsExpired"
class="js-artifacts-removed build-detail-row"
>
{{ s__('Job|The artifacts were removed') }}
</p>
<p
v-else-if="willArtifactsExpire"
class="js-artifacts-will-be-removed build-detail-row"
>
{{ s__('Job|The artifacts will be removed') }}
</p>
<timeago-tooltiop
v-if="expireAt"
:time="expireAt"
/>
<div
class="btn-group d-flex"
role="group"
>
<a
v-if="keepArtifactsPath"
:href="keepArtifactsPath"
class="js-keep-artifacts btn btn-sm btn-default"
data-method="post"
>
{{ s__('Job|Keep') }}
</a>
<a
v-if="downloadArtifactsPath"
:href="downloadArtifactsPath"
class="js-download-artifacts btn btn-sm btn-default"
download
rel="nofollow"
>
{{ s__('Job|Download') }}
</a>
<a
v-if="browseArtifactsPath"
:href="browseArtifactsPath"
class="js-browse-artifacts btn btn-sm btn-default"
>
{{ s__('Job|Browse') }}
</a>
</div>
</div>
</template>
......@@ -255,6 +255,7 @@ module ApplicationSettingsHelper
:usage_ping_enabled,
:instance_statistics_visibility_private,
:user_default_external,
:user_show_add_ssh_key_message,
:user_oauth_applications,
:version_check_enabled,
:web_ide_clientside_preview_enabled
......
......@@ -74,7 +74,11 @@ module ButtonHelper
end
def ssh_clone_button(project, append_link: true)
dropdown_description = _("You won't be able to pull or push project code via SSH until you add an SSH key to your profile") if current_user.try(:require_ssh_key?)
if Gitlab::CurrentSettings.user_show_add_ssh_key_message? &&
current_user.try(:require_ssh_key?)
dropdown_description = _("You won't be able to pull or push project code via SSH until you add an SSH key to your profile")
end
append_url = project.ssh_url_to_repo if append_link
geo_url = geo_primary_ssh_url_to_repo(project) if Gitlab::Geo.secondary?
......
......@@ -194,7 +194,10 @@ module ProjectsHelper
end
def show_no_ssh_key_message?
cookies[:hide_no_ssh_message].blank? && !current_user.hide_no_ssh_key && current_user.require_ssh_key?
Gitlab::CurrentSettings.user_show_add_ssh_key_message? &&
cookies[:hide_no_ssh_message].blank? &&
!current_user.hide_no_ssh_key &&
current_user.require_ssh_key?
end
def show_no_password_message?
......
......@@ -299,7 +299,8 @@ class ApplicationSetting < ActiveRecord::Base
unique_ips_limit_time_window: 3600,
usage_ping_enabled: Settings.gitlab['usage_ping_enabled'],
instance_statistics_visibility_private: false,
user_default_external: false
user_default_external: false,
user_show_add_ssh_key_message: true
}
end
......
......@@ -32,6 +32,12 @@
= f.check_box :user_default_external, class: 'form-check-input'
= f.label :user_default_external, class: 'form-check-label' do
Newly registered users will by default be external
.form-group
= f.label :user_show_add_ssh_key_message, 'Prompt users to upload SSH keys', class: 'label-bold'
.form-check
= f.check_box :user_show_add_ssh_key_message, class: 'form-check-input'
= 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
- if ::Gitlab.dev_env_or_com?
.form-group
......
= form_for runner, url: runner_form_url do |f|
= form_errors(runner)
.form-group.row
= label :active, "Active", class: 'col-form-label col-sm-2'
= label :active, _("Active"), class: 'col-form-label col-sm-2'
.col-sm-10
.form-check
= f.check_box :active, { class: 'form-check-input' }
%span.light Paused Runners don't accept new jobs
%label.light{ for: :runner_active }= _("Paused Runners don't accept new jobs")
.form-group.row
= label :protected, "Protected", class: 'col-form-label col-sm-2'
= label :protected, _("Protected"), class: 'col-form-label col-sm-2'
.col-sm-10
.form-check
= f.check_box :access_level, { class: 'form-check-input' }, 'ref_protected', 'not_protected'
%span.light This runner will only run on pipelines triggered on protected branches
%label.light{ for: :runner_access_level }= _('This runner will only run on pipelines triggered on protected branches')
.form-group.row
= label :run_untagged, 'Run untagged jobs', class: 'col-form-label col-sm-2'
= label :run_untagged, _('Run untagged jobs'), class: 'col-form-label col-sm-2'
.col-sm-10
.form-check
= f.check_box :run_untagged, { class: 'form-check-input' }
%span.light Indicates whether this runner can pick jobs without tags
%label.light{ for: :runner_run_untagged }= _('Indicates whether this runner can pick jobs without tags')
- unless runner.group_type?
.form-group.row
= label :locked, _('Lock to current projects'), class: 'col-form-label col-sm-2'
.col-sm-10
.form-check
= f.check_box :locked, { class: 'form-check-input' }
%span.light= _('When a runner is locked, it cannot be assigned to other projects')
%label.light{ for: :runner_locked }= _('When a runner is locked, it cannot be assigned to other projects')
.form-group.row
= label_tag :token, class: 'col-form-label col-sm-2' do
Token
= _('Token')
.col-sm-10
= f.text_field :token, class: 'form-control', readonly: true
.form-group.row
= label_tag :ip_address, class: 'col-form-label col-sm-2' do
IP Address
= _('IP Address')
.col-sm-10
= f.text_field :ip_address, class: 'form-control', readonly: true
.form-group.row
= label_tag :description, class: 'col-form-label col-sm-2' do
Description
= _('Description')
.col-sm-10
= f.text_field :description, class: 'form-control'
.form-group.row
= label_tag :maximum_timeout_human_readable, class: 'col-form-label col-sm-2' do
Maximum job timeout
= _('Maximum job timeout')
.col-sm-10
= f.text_field :maximum_timeout_human_readable, class: 'form-control'
.form-text.text-muted This timeout will take precedence when lower than Project-defined timeout
.form-text.text-muted= _('This timeout will take precedence when lower than Project-defined timeout')
.form-group.row
= label_tag :tag_list, class: 'col-form-label col-sm-2' do
Tags
= _('Tags')
.col-sm-10
= f.text_field :tag_list, value: runner.tag_list.sort.join(', '), class: 'form-control'
.form-text.text-muted You can setup jobs to only use Runners with specific tags. Separate tags with commas.
.form-text.text-muted= _('You can setup jobs to only use Runners with specific tags. Separate tags with commas.')
.form-actions
= f.submit 'Save changes', class: 'btn btn-save'
= f.submit _('Save changes'), class: 'btn btn-success'
......@@ -35,7 +35,9 @@ parser.parse!
abort("Missing options. Use #{$0} --help to see the list of options available".red) if options.values.include?(nil)
abort("Wrong version format #{options[:version].bold}".red) unless options[:version] =~ /\A\d*\-\d*\Z/
branch = [BRANCH_PREFIX, options[:branch], options[:version]].join('-').freeze
branch = "#{options[:branch]}-#{options[:version]}"
branch.prepend("#{BRANCH_PREFIX}-") unless branch.start_with?("#{BRANCH_PREFIX}-")
branch = branch.freeze
stable_branch = "#{BRANCH_PREFIX}-#{options[:version]}".freeze
command = "git fetch #{REMOTE} #{stable_branch} && git checkout #{stable_branch} && git pull #{REMOTE} #{stable_branch} && git checkout -B #{branch} && git cherry-pick #{options[:sha]} && git push #{REMOTE} #{branch}"
......
---
title: Fix checkboxes on runner admin settings - The labels are now clickable
merge_request:
author:
type: fixed
---
title: Add ability to suppress the global "You won't be able to use SSH" message
merge_request: 21027
author: Ævar Arnfjörð Bjarmason
type: added
---
title: Creates Vue component for artifacts block on job page
merge_request:
author:
type: other
---
title: Fix broken JavaScript in IE11
merge_request: 21214
author:
type: fixed
---
title: 'Auto-DevOps.gitlab-ci.yml: update glibc package to 2.28'
merge_request: 21191
author: sgerrand
type: fixed
---
title: Add Czech as an available language.
merge_request: 21201
author:
type: added
---
title: Fix bin/secpick error and security branch prefixing
merge_request: 21210
author:
type: fixed
title: Incremental rendering with Vue on merge request page
merge_request: 21063
author:
type: performance
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class AddUserShowAddSshKeyMessageToApplicationSettings < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
# Set this constant to true if this migration requires downtime.
DOWNTIME = false
disable_ddl_transaction!
def up
add_column_with_default :application_settings, :user_show_add_ssh_key_message, :boolean, default: true, allow_null: false
end
def down
remove_column :application_settings, :user_show_add_ssh_key_message
end
end
......@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20180807153545) do
ActiveRecord::Schema.define(version: 20180808162000) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
......@@ -214,6 +214,7 @@ ActiveRecord::Schema.define(version: 20180807153545) do
t.string "snowplow_cookie_domain"
t.boolean "instance_statistics_visibility_private", default: false, null: false
t.boolean "web_ide_clientside_preview_enabled", default: false, null: false
<<<<<<< HEAD
t.integer "custom_project_templates_group_id"
end
......@@ -243,6 +244,9 @@ ActiveRecord::Schema.define(version: 20180807153545) do
t.integer "user_id", null: false
t.datetime "created_at"
t.datetime "updated_at"
=======
t.boolean "user_show_add_ssh_key_message", default: true, null: false
>>>>>>> upstream/master
end
add_index "approvers", ["target_id", "target_type"], name: "index_approvers_on_target_id_and_target_type", using: :btree
......
......@@ -148,12 +148,15 @@ scales to run your tests faster.
- [Review Apps](ci/review_apps/index.md): Preview changes to your app right from a merge request.
- [Pipeline Graphs](ci/pipelines.md#pipeline-graphs)
- [JUnit test reports](ci/junit_test_reports.md)
<<<<<<< HEAD
- [Multi-project pipelines](ci/multi_project_pipelines.md) **[PREMIUM]**
- [Code Quality reports](user/project/merge_requests/code_quality.md) **[STARTER]**
- [Static Application Security Testing (SAST) reports](user/project/merge_requests/sast.md) **[ULTIMATE]**
- [Dynamic Application Security Testing (DAST)](user/project/merge_requests/dast.md) **[ULTIMATE]**
- [Dependency Scanning reports](user/project/merge_requests/dependency_scanning.md) **[ULTIMATE]**
- [Container Scanning reports](user/project/merge_requests/container_scanning.md) **[ULTIMATE]**
=======
>>>>>>> upstream/master
### Package
......
......@@ -163,3 +163,20 @@ Such a restriction can currently be hacked in by e.g. providing a
custom `AuthorizedKeysCommand` which checks if the discovered key-ID
returned from `gitlab-shell-authorized-keys-check` is a deploy key or
not (all non-deploy keys should be refused).
## Disabling the global warning about users lacking SSH keys
By default GitLab will show a "You won't be able to pull or push
project code via SSH" warning to users who have not uploaded an SSH
key to their profile.
This is counterproductive when using SSH certificates, since users
aren't expected to upload their own keys.
To disable this warning globally, go to "Application settings ->
Account and limit settings" and disable the "Show user add SSH key
message" setting.
This setting was added specifically for use with SSH certificates, but
can be turned off without using them if you'd like to hide the warning
for some other reason.
......@@ -56,7 +56,8 @@ Example response:
"enforce_terms": true,
"terms": "Hello world!",
"performance_bar_allowed_group_id": 42,
"instance_statistics_visibility_private": false
"instance_statistics_visibility_private": false,
"user_show_add_ssh_key_message": true
}
```
......@@ -187,6 +188,8 @@ PUT /application/settings
| `enforce_terms` | boolean | no | Enforce application ToS to all users |
| `terms` | text | yes (if `enforce_terms` is true) | Markdown content for the ToS |
| `instance_statistics_visibility_private` | boolean | no | When set to `true` Instance statistics will only be available to admins |
| `user_show_add_ssh_key_message` | boolean | no | When set to `false` disable the "You won't be able to pull or push
+project code via SSH" warning shown to users with no uploaded SSH key |
```bash
curl --request PUT --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/application/settings?signup_enabled=false&default_project_visibility=internal
......@@ -236,6 +239,7 @@ Example response:
"enforce_terms": true,
"terms": "Hello world!",
"performance_bar_allowed_group_id": 42,
"instance_statistics_visibility_private": false
"instance_statistics_visibility_private": false,
"user_show_add_ssh_key_message": true
}
```
......@@ -34,6 +34,7 @@ Example response:
"push_events":true,
"tag_push_events":false,
"merge_requests_events": true,
"repository_update_events": true,
"enable_ssl_verification":true
}
]
......@@ -56,6 +57,7 @@ POST /hooks
| `push_events` | boolean | no | When true, the hook will fire on push events |
| `tag_push_events` | boolean | no | When true, the hook will fire on new tags being pushed |
| `merge_requests_events` | boolean | no | Trigger hook on merge requests events |
| `repository_update_events` | boolean | no | Trigger hook on repository update events |
| `enable_ssl_verification` | boolean | no | Do SSL verification when triggering the hook |
Example request:
......@@ -75,6 +77,7 @@ Example response:
"push_events":true,
"tag_push_events":false,
"merge_requests_events": true,
"repository_update_events": true,
"enable_ssl_verification":true
}
]
......@@ -127,4 +130,4 @@ Example request:
```bash
curl --request DELETE --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/hooks/2
```
```
\ No newline at end of file
......@@ -44,6 +44,13 @@ There's also a collection of repositories with [example projects](https://gitlab
- [The `.gitlab-ci.yml` file for GitLab itself](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/.gitlab-ci.yml)
## Test Reports
<<<<<<< HEAD
=======
[Collect test reports in Verify stage](../junit_test_reports.md).
## Code Quality analysis
>>>>>>> upstream/master
[Collect test reports in Verify stage](../junit_test_reports.md).
......
......@@ -49,11 +49,17 @@ A. Consider you are a software developer working in a team:
1. You checkout a new branch, and submit your changes through a merge request
1. You gather feedback from your team
<<<<<<< HEAD
1. You work on the implementation optimizing code with [Code Quality reports](code_quality.md) **[STARTER]**
1. You verify your changes with [JUnit test reports](../../../ci/junit_test_reports.md) in GitLab CI/CD
1. You avoid using dependencies whose license is not compatible with your project with [License Management reports](license_management.md) **[ULTIMATE]**
1. You request the [approval](#merge-request-approvals) from your manager
1. Your manager pushes a commit with their final review, [approves the merge request](merge_request_approvals.md), and set it to [merge when pipeline succeeds](#merge-when-pipeline-succeeds) (Merge Request Approvals are available in GitLab Starter)
=======
1. You verify your changes with [JUnit test reports](../../../ci/junit_test_reports.md) in GitLab CI/CD
1. You request the approval from your manager
1. Your manager pushes a commit with his final review, [approves the merge request](https://docs.gitlab.com/ee/user/project/merge_requests/merge_request_approvals.html), and set it to [merge when pipeline succeeds](#merge-when-pipeline-succeeds) (Merge Request Approvals are available in GitLab Starter)
>>>>>>> upstream/master
1. Your changes get deployed to production with [manual actions](../../../ci/yaml/README.md#manual-actions) for GitLab CI/CD
1. Your implementations were successfully shipped to your customer
......
......@@ -22,7 +22,8 @@ module Gitlab
'tr_TR' => 'Türkçe',
'id_ID' => 'Bahasa Indonesia',
'fil_PH' => 'Filipino',
'pl_PL' => 'Polski'
'pl_PL' => 'Polski',
'cs_CZ' => 'Čeština'
}.freeze
def available_locales
......
......@@ -3532,7 +3532,14 @@ msgstr ""
msgid "Git version"
msgstr ""
<<<<<<< HEAD
msgid "GitHub import"
=======
msgid "IP Address"
msgstr ""
msgid "Identifier"
>>>>>>> upstream/master
msgstr ""
msgid "GitLab CI Linter has been moved"
......@@ -3978,6 +3985,9 @@ msgstr ""
msgid "Incompatible Project"
msgstr ""
msgid "Indicates whether this runner can pick jobs without tags"
msgstr ""
msgid "Inline"
msgstr ""
......@@ -4067,13 +4077,32 @@ msgstr ""
msgid "Jobs"
msgstr ""
msgid "Job|Browse"
msgstr ""
msgid "Job|Download"
msgstr ""
msgid "Job|Job artifacts"
msgstr ""
msgid "Job|Job has been erased"
msgstr ""
msgid "Job|Job has been erased by"
msgstr ""
<<<<<<< HEAD
msgid "Job|This job is stuck, because the project doesn't have any runners online assigned to it."
=======
msgid "Job|Keep"
msgstr ""
msgid "Job|The artifacts were removed"
msgstr ""
msgid "Job|The artifacts will be removed"
>>>>>>> upstream/master
msgstr ""
msgid "Jul"
......@@ -4413,6 +4442,9 @@ msgstr ""
msgid "Maximum git storage failures"
msgstr ""
msgid "Maximum job timeout"
msgstr ""
msgid "May"
msgstr ""
......@@ -5134,6 +5166,9 @@ msgstr ""
msgid "Pause"
msgstr ""
msgid "Paused Runners don't accept new jobs"
msgstr ""
msgid "Pending"
msgstr ""
......@@ -5797,6 +5832,9 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
msgid "Protected"
msgstr ""
msgid "Protip:"
msgstr ""
......@@ -6062,10 +6100,14 @@ msgstr ""
msgid "Revoke"
msgstr ""
<<<<<<< HEAD
msgid "Roadmap"
msgstr ""
msgid "Run CI/CD pipelines for external repositories"
=======
msgid "Run untagged jobs"
>>>>>>> upstream/master
msgstr ""
msgid "Runner token"
......@@ -7109,9 +7151,15 @@ msgstr ""
msgid "This repository"
msgstr ""
msgid "This runner will only run on pipelines triggered on protected branches"
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"
msgstr ""
msgid "This user has no identities"
msgstr ""
......@@ -7386,6 +7434,9 @@ msgstr ""
msgid "ToggleButton|Toggle Status: ON"
msgstr ""
msgid "Token"
msgstr ""
msgid "Too many changes to show."
msgstr ""
......@@ -7890,7 +7941,11 @@ msgstr ""
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr ""
<<<<<<< HEAD
msgid "You cannot write to a read-only secondary GitLab Geo instance. Please use %{link_to_primary_node} instead."
=======
msgid "You can setup jobs to only use Runners with specific tags. Separate tags with commas."
>>>>>>> upstream/master
msgstr ""
msgid "You cannot write to this read-only GitLab instance."
......
......@@ -28,7 +28,7 @@ describe 'Merge request > User sees MR with deleted source branch', :js do
click_on 'Changes'
wait_for_requests
expect(page).to have_selector('.diffs.tab-pane .nothing-here-block')
expect(page).to have_selector('.diffs.tab-pane .file-holder')
expect(page).to have_content('Source branch does not exist.')
end
end
......@@ -79,6 +79,18 @@ describe ButtonHelper do
end
end
context 'without an ssh key on the user and user_show_add_ssh_key_message unset' do
before do
stub_application_setting(user_show_add_ssh_key_message: false)
end
it 'there is no warning on the dropdown description' do
description = element.search('.dropdown-menu-inner-content').first
expect(description).to be_nil
end
end
context 'with an ssh key on the user' do
before do
create(:key, user: user)
......
......@@ -22,11 +22,18 @@ describe('DiffFile', () => {
expect(el.id).toEqual(fileHash);
expect(el.classList.contains('diff-file')).toEqual(true);
expect(el.querySelectorAll('.diff-content.hidden').length).toEqual(0);
expect(el.querySelector('.js-file-title')).toBeDefined();
expect(el.querySelector('.file-title-name').innerText.indexOf(filePath) > -1).toEqual(true);
expect(el.querySelector('.js-syntax-highlight')).toBeDefined();
expect(el.querySelectorAll('.line_content').length > 5).toEqual(true);
expect(vm.file.renderIt).toEqual(false);
vm.file.renderIt = true;
vm.$nextTick(() => {
expect(el.querySelectorAll('.line_content').length > 5).toEqual(true);
});
});
describe('collapsed', () => {
......@@ -34,6 +41,7 @@ describe('DiffFile', () => {
expect(vm.$el.querySelectorAll('.diff-content').length).toEqual(1);
expect(vm.file.collapsed).toEqual(false);
vm.file.collapsed = true;
vm.file.renderIt = true;
vm.$nextTick(() => {
expect(vm.$el.querySelectorAll('.diff-content').length).toEqual(0);
......
......@@ -39,6 +39,7 @@ export default {
viewPath: '/gitlab-org/gitlab-test/blob/spooky-stuff/CHANGELOG',
replacedViewPath: null,
collapsed: false,
renderIt: false,
tooLarge: false,
contextLinesPath:
'/gitlab-org/gitlab-test/blob/c48ee0d1bf3b30453f5b32250ce03134beaa6d13/CHANGELOG/diff',
......
import mutations from '~/diffs/store/mutations';
import * as types from '~/diffs/store/mutation_types';
import { INLINE_DIFF_VIEW_TYPE } from '~/diffs/constants';
import diffFileMockData from '../mock_data/diff_file';
describe('DiffsStoreMutations', () => {
describe('SET_BASE_CONFIG', () => {
......@@ -24,6 +25,23 @@ describe('DiffsStoreMutations', () => {
});
});
describe('SET_DIFF_DATA', () => {
it('should set diff data type properly', () => {
const state = {};
const diffMock = {
diff_files: [diffFileMockData],
};
mutations[types.SET_DIFF_DATA](state, diffMock);
const firstLine = state.diffFiles[0].parallelDiffLines[0];
expect(firstLine.right.text).toBeUndefined();
expect(state.diffFiles[0].renderIt).toEqual(true);
expect(state.diffFiles[0].collapsed).toEqual(false);
});
});
describe('SET_DIFF_VIEW_TYPE', () => {
it('should set diff view type properly', () => {
const state = {};
......
import Vue from 'vue';
import { getTimeago } from '~/lib/utils/datetime_utility';
import component from '~/jobs/components/artifacts_block.vue';
import mountComponent from '../helpers/vue_mount_component_helper';
describe('Artifacts block', () => {
const Component = Vue.extend(component);
let vm;
const expireAt = '2018-08-14T09:38:49.157Z';
const timeago = getTimeago();
const formatedDate = timeago.format(expireAt);
afterEach(() => {
vm.$destroy();
});
describe('with expired artifacts', () => {
it('renders expired artifact date and info', () => {
vm = mountComponent(Component, {
haveArtifactsExpired: true,
willArtifactsExpire: false,
expireAt,
});
expect(vm.$el.querySelector('.js-artifacts-removed')).not.toBeNull();
expect(vm.$el.querySelector('.js-artifacts-will-be-removed')).toBeNull();
expect(vm.$el.textContent).toContain(formatedDate);
});
});
describe('with artifacts that will expire', () => {
it('renders will expire artifact date and info', () => {
vm = mountComponent(Component, {
haveArtifactsExpired: false,
willArtifactsExpire: true,
expireAt,
});
expect(vm.$el.querySelector('.js-artifacts-removed')).toBeNull();
expect(vm.$el.querySelector('.js-artifacts-will-be-removed')).not.toBeNull();
expect(vm.$el.textContent).toContain(formatedDate);
});
});
describe('when the user can keep the artifacts', () => {
it('renders the keep button', () => {
vm = mountComponent(Component, {
haveArtifactsExpired: true,
willArtifactsExpire: false,
expireAt,
keepArtifactsPath: '/keep',
});
expect(vm.$el.querySelector('.js-keep-artifacts')).not.toBeNull();
});
});
describe('when the user can not keep the artifacts', () => {
it('does not render the keep button', () => {
vm = mountComponent(Component, {
haveArtifactsExpired: true,
willArtifactsExpire: false,
expireAt,
});
expect(vm.$el.querySelector('.js-keep-artifacts')).toBeNull();
});
});
describe('when the user can download the artifacts', () => {
it('renders the download button', () => {
vm = mountComponent(Component, {
haveArtifactsExpired: true,
willArtifactsExpire: false,
expireAt,
downloadArtifactsPath: '/download',
});
expect(vm.$el.querySelector('.js-download-artifacts')).not.toBeNull();
});
});
describe('when the user can not download the artifacts', () => {
it('does not render the keep button', () => {
vm = mountComponent(Component, {
haveArtifactsExpired: true,
willArtifactsExpire: false,
expireAt,
});
expect(vm.$el.querySelector('.js-download-artifacts')).toBeNull();
});
});
describe('when the user can browse the artifacts', () => {
it('does not render the browse button', () => {
vm = mountComponent(Component, {
haveArtifactsExpired: true,
willArtifactsExpire: false,
expireAt,
browseArtifactsPath: '/browse',
});
expect(vm.$el.querySelector('.js-browse-artifacts')).not.toBeNull();
});
});
describe('when the user can not browse the artifacts', () => {
it('does not render the browse button', () => {
vm = mountComponent(Component, {
haveArtifactsExpired: true,
willArtifactsExpire: false,
expireAt,
});
expect(vm.$el.querySelector('.js-browse-artifacts')).toBeNull();
});
});
});
......@@ -30,7 +30,7 @@ describe InternalId do
context 'with existing issues' do
before do
rand(1..10).times { create(:issue, project: project) }
create_list(:issue, 2, project: project)
described_class.delete_all
end
......@@ -54,7 +54,7 @@ describe InternalId do
end
it 'generates a strictly monotone, gapless sequence' do
seq = (0..rand(100)).map do
seq = Array.new(10).map do
described_class.generate_next(issue, scope, usage, init)
end
normalized = seq.map { |i| i - seq.min }
......
......@@ -642,9 +642,9 @@ rollout 100%:
function install_dependencies() {
apk add -U openssl curl tar gzip bash ca-certificates git
wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub
wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.23-r3/glibc-2.23-r3.apk
apk add glibc-2.23-r3.apk
rm glibc-2.23-r3.apk
wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.28-r0/glibc-2.28-r0.apk
apk add glibc-2.28-r0.apk
rm glibc-2.28-r0.apk
curl "https://kubernetes-helm.storage.googleapis.com/helm-v${HELM_VERSION}-linux-amd64.tar.gz" | tar zx
mv linux-amd64/helm /usr/bin/
......
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