Commit 1e2cacf0 authored by GitLab Bot's avatar GitLab Bot

Merge remote-tracking branch 'upstream/master' into ce-to-ee-2017-12-14

# Conflicts:
#	app/assets/images/icons.json
#	app/assets/images/icons.svg
#	app/assets/javascripts/dispatcher.js
#	app/assets/javascripts/project_find_file.js
#	app/assets/javascripts/render_gfm.js
#	app/assets/javascripts/search.js
#	app/assets/javascripts/search_autocomplete.js
#	app/assets/stylesheets/framework/variables.scss
#	app/assets/stylesheets/pages/boards.scss
#	app/assets/stylesheets/pages/merge_requests.scss
#	app/controllers/admin/groups_controller.rb
#	app/presenters/group_member_presenter.rb
#	app/presenters/member_presenter.rb
#	app/presenters/project_member_presenter.rb
#	app/views/projects/clusters/index.html.haml
#	app/views/projects/merge_requests/_mr_title.html.haml
#	app/views/shared/members/_member.html.haml
#	app/workers/all_queues.yml
#	lib/gitlab/sidekiq_config.rb
#	spec/javascripts/search_autocomplete_spec.js
#	spec/models/ci/build_spec.rb
#	spec/models/merge_request_spec.rb

[ci skip]
parents c52a313f d7c1a9d9
{"iconCount":179,"spriteSize":81882,"icons":["abuse","account","admin","angle-double-left","angle-double-right","angle-down","angle-left","angle-right","angle-up","appearance","applications","approval","arrow-right","assignee","bold","book","branch","bullhorn","calendar","cancel","chart","chevron-down","chevron-left","chevron-right","chevron-up","clock","close","code","collapse","comment-dots","comment-next","comment","comments","commit","credit-card","cut","dashboard","disk","doc_code","doc_image","doc_text","double-headed-arrow","download","duplicate","earth","ellipsis_v","emoji_slightly_smiling_face","emoji_smile","emoji_smiley","epic","external-link","eye-slash","eye","file-addition","file-deletion","file-modified","filter","folder","fork","geo-nodes","git-merge","group","history","home","hook","hourglass","image-comment-dark","import","issue-block","issue-child","issue-close","issue-duplicate","issue-new","issue-open-m","issue-open","issue-parent","issues","italic","key-2","key","label","labels","leave","level-up","license","link","list-bulleted","list-numbered","location-dot","location","lock-open","lock","log","mail","menu","merge-request-close","messages","mobile-issue-close","monitor","more","notifications-off","notifications","overview","pencil-square","pencil","pipeline","play","plus-square-o","plus-square","plus","preferences","profile","project","push-rules","question-o","question","quote","redo","remove","repeat","retry","scale","screen-full","screen-normal","scroll_down","scroll_up","search","settings","shield","slight-frown","slight-smile","smile","smiley","snippet","spam","spinner","star-o","star","status_canceled_borderless","status_canceled","status_closed","status_created_borderless","status_created","status_failed_borderless","status_failed","status_manual_borderless","status_manual","status_notfound_borderless","status_open","status_pending_borderless","status_pending","status_running_borderless","status_running","status_skipped_borderless","status_skipped","status_success_borderless","status_success_solid","status_success","status_warning_borderless","status_warning","stop","task-done","template","terminal","thumb-down","thumb-up","thumbtack","timer","todo-add","todo-done","token","unapproval","unassignee","unlink","user","users","volume-up","warning","work"]}
\ No newline at end of file
<<<<<<< HEAD
{"iconCount":179,"spriteSize":81882,"icons":["abuse","account","admin","angle-double-left","angle-double-right","angle-down","angle-left","angle-right","angle-up","appearance","applications","approval","arrow-right","assignee","bold","book","branch","bullhorn","calendar","cancel","chart","chevron-down","chevron-left","chevron-right","chevron-up","clock","close","code","collapse","comment-dots","comment-next","comment","comments","commit","credit-card","cut","dashboard","disk","doc_code","doc_image","doc_text","double-headed-arrow","download","duplicate","earth","ellipsis_v","emoji_slightly_smiling_face","emoji_smile","emoji_smiley","epic","external-link","eye-slash","eye","file-addition","file-deletion","file-modified","filter","folder","fork","geo-nodes","git-merge","group","history","home","hook","hourglass","image-comment-dark","import","issue-block","issue-child","issue-close","issue-duplicate","issue-new","issue-open-m","issue-open","issue-parent","issues","italic","key-2","key","label","labels","leave","level-up","license","link","list-bulleted","list-numbered","location-dot","location","lock-open","lock","log","mail","menu","merge-request-close","messages","mobile-issue-close","monitor","more","notifications-off","notifications","overview","pencil-square","pencil","pipeline","play","plus-square-o","plus-square","plus","preferences","profile","project","push-rules","question-o","question","quote","redo","remove","repeat","retry","scale","screen-full","screen-normal","scroll_down","scroll_up","search","settings","shield","slight-frown","slight-smile","smile","smiley","snippet","spam","spinner","star-o","star","status_canceled_borderless","status_canceled","status_closed","status_created_borderless","status_created","status_failed_borderless","status_failed","status_manual_borderless","status_manual","status_notfound_borderless","status_open","status_pending_borderless","status_pending","status_running_borderless","status_running","status_skipped_borderless","status_skipped","status_success_borderless","status_success_solid","status_success","status_warning_borderless","status_warning","stop","task-done","template","terminal","thumb-down","thumb-up","thumbtack","timer","todo-add","todo-done","token","unapproval","unassignee","unlink","user","users","volume-up","warning","work"]}
=======
{"iconCount":181,"spriteSize":81482,"icons":["abuse","account","admin","angle-double-left","angle-double-right","angle-down","angle-left","angle-right","angle-up","appearance","applications","approval","arrow-down","arrow-right","assignee","bold","book","branch","bullhorn","calendar","cancel","chart","chevron-down","chevron-left","chevron-right","chevron-up","clock","close","code","collapse","comment-dots","comment-next","comment","comments","commit","credit-card","cut","dashboard","disk","doc_code","doc_image","doc_text","double-headed-arrow","download","duplicate","earth","ellipsis_v","emoji_slightly_smiling_face","emoji_smile","emoji_smiley","epic","external-link","eye-slash","eye","file-addition","file-deletion","file-modified","filter","folder","fork","geo-nodes","git-merge","group","history","home","hook","hourglass","image-comment-dark","image-comment-light","import","issue-block","issue-child","issue-close","issue-duplicate","issue-new","issue-open-m","issue-open","issue-parent","issues","italic","key-2","key","label","labels","leave","level-up","license","link","list-bulleted","list-numbered","location-dot","location","lock-open","lock","log","mail","menu","merge-request-close","messages","mobile-issue-close","monitor","more","notifications-off","notifications","overview","pencil-square","pencil","pipeline","play","plus-square-o","plus-square","plus","preferences","profile","project","push-rules","question-o","question","quote","redo","remove","repeat","retry","scale","screen-full","screen-normal","scroll_down","scroll_up","search","settings","shield","slight-frown","slight-smile","smile","smiley","snippet","spam","spinner","star-o","star","status_canceled_borderless","status_canceled","status_closed","status_created_borderless","status_created","status_failed_borderless","status_failed","status_manual_borderless","status_manual","status_notfound_borderless","status_open","status_pending_borderless","status_pending","status_running_borderless","status_running","status_skipped_borderless","status_skipped","status_success_borderless","status_success_solid","status_success","status_warning_borderless","status_warning","stop","task-done","template","terminal","thumb-down","thumb-up","thumbtack","timer","todo-add","todo-done","token","unapproval","unassignee","unlink","user","users","volume-up","warning","work"]}
>>>>>>> upstream/master
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -24,7 +24,10 @@ import projectAvatar from './project_avatar';
/* global MergeRequest */
import Compare from './compare';
import initCompareAutocomplete from './compare_autocomplete';
<<<<<<< HEAD
/* global PathLocks */
=======
>>>>>>> upstream/master
import ProjectFindFile from './project_find_file';
import ProjectNew from './project_new';
import projectImport from './project_import';
......@@ -98,12 +101,15 @@ import ProjectLabelSubscription from './project_label_subscription';
import ProjectVariables from './project_variables';
import SearchAutocomplete from './search_autocomplete';
import Activities from './activities';
<<<<<<< HEAD
// EE-only
import ApproversSelect from './approvers_select';
import AuditLogs from './audit_logs';
import initGeoInfoModal from './init_geo_info_modal';
import initGroupAnalytics from './init_group_analytics';
=======
>>>>>>> upstream/master
(function() {
var Dispatcher;
......@@ -410,7 +416,10 @@ import initGroupAnalytics from './init_group_analytics';
if ($('#tree-slider').length) new TreeView();
if ($('.blob-viewer').length) new BlobViewer();
if ($('.project-show-activity').length) new Activities();
<<<<<<< HEAD
=======
>>>>>>> upstream/master
$('#tree-slider').waitForImages(function() {
ajaxGet(document.querySelector('.js-tree-content').dataset.logsPath);
});
......
<script>
import { s__ } from '../../locale';
import tooltip from '../../vue_shared/directives/tooltip';
import PopupDialog from '../../vue_shared/components/popup_dialog.vue';
import modal from '../../vue_shared/components/modal.vue';
import eventHub from '../event_hub';
import { COMMON_STR } from '../constants';
import Icon from '../../vue_shared/components/icon.vue';
......@@ -9,7 +9,7 @@ import Icon from '../../vue_shared/components/icon.vue';
export default {
components: {
Icon,
PopupDialog,
modal,
},
directives: {
tooltip,
......@@ -27,7 +27,7 @@ export default {
},
data() {
return {
dialogStatus: false,
modalStatus: false,
};
},
computed: {
......@@ -43,10 +43,10 @@ export default {
},
methods: {
onLeaveGroup() {
this.dialogStatus = true;
this.modalStatus = true;
},
leaveGroup(leaveConfirmed) {
this.dialogStatus = false;
this.modalStatus = false;
if (leaveConfirmed) {
eventHub.$emit('leaveGroup', this.group, this.parentGroup);
}
......@@ -82,8 +82,8 @@ export default {
class="fa fa-sign-out"
aria-hidden="true"/>
</a>
<popup-dialog
v-show="dialogStatus"
<modal
v-show="modalStatus"
:primary-button-label="__('Leave')"
kind="warning"
:title="__('Are you sure?')"
......
......@@ -48,7 +48,7 @@ export default class Issue {
})
.fail(() => new Flash(issueFailMessage))
.done((data) => {
const isClosedBadge = $('div.status-box-closed');
const isClosedBadge = $('div.status-box-issue-closed');
const isOpenBadge = $('div.status-box-open');
const projectIssuesCounter = $('.issue_counter');
......
......@@ -9,7 +9,7 @@ import titleComponent from './title.vue';
import descriptionComponent from './description.vue';
import editedComponent from './edited.vue';
import formComponent from './form.vue';
import RecaptchaDialogImplementor from '../../vue_shared/mixins/recaptcha_dialog_implementor';
import recaptchaModalImplementor from '../../vue_shared/mixins/recaptcha_modal_implementor';
export default {
props: {
......@@ -152,7 +152,7 @@ export default {
},
mixins: [
RecaptchaDialogImplementor,
recaptchaModalImplementor,
],
methods: {
......@@ -197,7 +197,7 @@ export default {
});
},
closeRecaptchaDialog() {
closeRecaptchaModal() {
this.store.setFormState({
updateLoading: false,
});
......@@ -272,10 +272,10 @@ export default {
:enable-autocomplete="enableAutocomplete"
/>
<recaptcha-dialog
<recaptcha-modal
v-show="showRecaptcha"
:html="recaptchaHTML"
@close="closeRecaptchaDialog"
@close="closeRecaptchaModal"
/>
</div>
<div v-else>
......
<script>
import animateMixin from '../mixins/animate';
import TaskList from '../../task_list';
import RecaptchaDialogImplementor from '../../vue_shared/mixins/recaptcha_dialog_implementor';
import recaptchaModalImplementor from '../../vue_shared/mixins/recaptcha_modal_implementor';
export default {
mixins: [
animateMixin,
RecaptchaDialogImplementor,
recaptchaModalImplementor,
],
props: {
......@@ -126,7 +126,7 @@
>
</textarea>
<recaptcha-dialog
<recaptcha-modal
v-show="showRecaptcha"
:html="recaptchaHTML"
@close="closeRecaptcha"
......
......@@ -47,7 +47,7 @@
<textarea
id="issue-description"
class="note-textarea js-gfm-input js-autosize markdown-area"
data-supports-quick-actionss="false"
data-supports-quick-actions="false"
aria-label="Description"
v-model="formState.description"
ref="textarea"
......
......@@ -123,9 +123,7 @@
// we need to do this to prevent noteForm inconsistent content warning
// this is something we intentionally do so we need to recover the content
this.note.note = noteText;
if (this.$refs.noteBody) {
this.$refs.noteBody.$refs.noteForm.note = noteText; // TODO: This could be better
}
this.$refs.noteBody.$refs.noteForm.note = noteText;
},
},
created() {
......
<script>
export default {
props: {
helpPagePath: {
type: String,
required: true,
export default {
props: {
helpPagePath: {
type: String,
required: true,
},
emptyStateSvgPath: {
type: String,
required: true,
},
},
emptyStateSvgPath: {
type: String,
required: true,
},
},
};
};
</script>
<template>
<div class="row empty-state js-empty-state">
<div class="col-xs-12">
<div class="svg-content">
<img :src="emptyStateSvgPath"/>
<div class="svg-content svg-250">
<img :src="emptyStateSvgPath" />
</div>
</div>
<div class="col-xs-12 text-center">
<div class="col-xs-12">
<div class="text-content">
<h4>Build with confidence</h4>
<h4 class="text-center">
{{ s__("Pipelines|Build with confidence") }}
</h4>
<p>
Continous Integration can help catch bugs by running your tests automatically,
while Continuous Deployment can help you deliver code to your product environment.
{{ s__("Pipelines|Continous Integration can help catch bugs by running your tests automatically, while Continuous Deployment can help you deliver code to your product environment.") }}
</p>
<a :href="helpPagePath" class="btn btn-info">
Get started with Pipelines
</a>
<div class="text-center">
<a
:href="helpPagePath"
class="btn btn-info"
>
{{ s__("Pipelines|Get started with Pipelines") }}
</a>
</div>
</div>
</div>
</div>
......
......@@ -59,8 +59,26 @@
},
computed: {
status() {
return this.job && this.job.status ? this.job.status : {};
},
tooltipText() {
return `${this.job.name} - ${this.job.status.label}`;
const textBuilder = [];
if (this.job.name) {
textBuilder.push(this.job.name);
}
if (this.job.name && this.status.label) {
textBuilder.push('-');
}
if (this.status.label) {
textBuilder.push(`${this.job.status.label}`);
}
return textBuilder.join(' ');
},
/**
......@@ -78,8 +96,8 @@
<div class="ci-job-component">
<a
v-tooltip
v-if="job.status.has_details"
:href="job.status.details_path"
v-if="status.has_details"
:href="status.details_path"
:title="tooltipText"
:class="cssClassJobName"
data-container="body"
......@@ -95,6 +113,7 @@
<div
v-else
v-tooltip
class="js-job-component-tooltip"
:title="tooltipText"
:class="cssClassJobName"
data-container="body"
......@@ -108,18 +127,18 @@
<action-component
v-if="hasAction && !isDropdown"
:tooltip-text="job.status.action.title"
:link="job.status.action.path"
:action-icon="job.status.action.icon"
:action-method="job.status.action.method"
:tooltip-text="status.action.title"
:link="status.action.path"
:action-icon="status.action.icon"
:action-method="status.action.method"
/>
<dropdown-action-component
v-if="hasAction && isDropdown"
:tooltip-text="job.status.action.title"
:link="job.status.action.path"
:action-icon="job.status.action.icon"
:action-method="job.status.action.method"
:tooltip-text="status.action.title"
:link="status.action.path"
:action-icon="status.action.icon"
:action-method="status.action.method"
/>
</div>
</template>
import Vue from 'vue';
import PipelinesStore from './stores/pipelines_store';
import pipelinesComponent from './components/pipelines.vue';
import Translate from '../vue_shared/translate';
Vue.use(Translate);
document.addEventListener('DOMContentLoaded', () => new Vue({
el: '#pipelines-list-vue',
......
<script>
import popupDialog from '../../../vue_shared/components/popup_dialog.vue';
import modal from '../../../vue_shared/components/modal.vue';
import { __, s__, sprintf } from '../../../locale';
import csrf from '../../../lib/utils/csrf';
......@@ -26,7 +26,7 @@
};
},
components: {
popupDialog,
modal,
},
computed: {
csrfToken() {
......@@ -89,7 +89,7 @@ Once you confirm %{deleteAccount}, it cannot be undone or recovered.`),
<template>
<div>
<popup-dialog
<modal
v-if="isOpen"
:title="s__('Profiles|Delete your account?')"
:text="text"
......@@ -134,7 +134,7 @@ Once you confirm %{deleteAccount}, it cannot be undone or recovered.`),
</form>
</template>
</popup-dialog>
</modal>
<button
type="button"
......
......@@ -28,8 +28,12 @@ const highlighter = function(element, text, matches) {
};
export default class ProjectFindFile {
<<<<<<< HEAD
constructor (element1, options) {
=======
constructor(element1, options) {
>>>>>>> upstream/master
this.element = element1;
this.options = options;
this.goToBlob = this.goToBlob.bind(this);
......@@ -71,7 +75,11 @@ export default class ProjectFindFile {
// find file
}
<<<<<<< HEAD
// files pathes load
=======
// files pathes load
>>>>>>> upstream/master
load(url) {
return $.ajax({
url: url,
......
import renderMath from './render_math';
import renderMermaid from './render_mermaid';
import syntaxHighlight from './syntax_highlight';
<<<<<<< HEAD
=======
>>>>>>> upstream/master
// Render Gitlab flavoured Markdown
//
// Delegates to syntax highlight and render math & mermaid diagrams.
......
<script>
import { mapActions } from 'vuex';
import { __ } from '../../../locale';
import popupDialog from '../../../vue_shared/components/popup_dialog.vue';
import modal from '../../../vue_shared/components/modal.vue';
export default {
props: {
......@@ -20,7 +20,7 @@
};
},
components: {
popupDialog,
modal,
},
methods: {
...mapActions([
......@@ -68,7 +68,7 @@
</script>
<template>
<popup-dialog
<modal
:title="modalTitle"
:primary-button-label="buttonLabel"
kind="success"
......@@ -94,5 +94,5 @@
</div>
</fieldset>
</form>
</popup-dialog>
</modal>
</template>
......@@ -2,12 +2,12 @@
import { mapGetters, mapState, mapActions } from 'vuex';
import tooltip from '../../vue_shared/directives/tooltip';
import icon from '../../vue_shared/components/icon.vue';
import PopupDialog from '../../vue_shared/components/popup_dialog.vue';
import modal from '../../vue_shared/components/modal.vue';
import commitFilesList from './commit_sidebar/list.vue';
export default {
components: {
PopupDialog,
modal,
icon,
commitFilesList,
},
......@@ -16,7 +16,7 @@ export default {
},
data() {
return {
showNewBranchDialog: false,
showNewBranchModal: false,
submitCommitsLoading: false,
startNewMR: false,
commitMessage: '',
......@@ -58,7 +58,7 @@ export default {
start_branch: createNewBranch ? this.currentBranch : undefined,
};
this.showNewBranchDialog = false;
this.showNewBranchModal = false;
this.submitCommitsLoading = true;
this.commitChanges({ payload, newMr: this.startNewMR })
......@@ -76,7 +76,7 @@ export default {
this.checkCommitStatus()
.then((branchChanged) => {
if (branchChanged) {
this.showNewBranchDialog = true;
this.showNewBranchModal = true;
} else {
this.makeCommit();
}
......@@ -99,13 +99,13 @@ export default {
'is-collapsed': collapsed,
}"
>
<popup-dialog
v-if="showNewBranchDialog"
<modal
v-if="showNewBranchModal"
:primary-button-label="__('Create new branch')"
kind="primary"
:title="__('Branch has changed')"
:text="__('This branch has changed since you started editing. Would you like to create a new branch?')"
@toggle="showNewBranchDialog = false"
@toggle="showNewBranchModal = false"
@submit="makeCommit(true)"
/>
<button
......
<script>
import { mapGetters, mapActions, mapState } from 'vuex';
import popupDialog from '../../vue_shared/components/popup_dialog.vue';
import modal from '../../vue_shared/components/modal.vue';
export default {
components: {
popupDialog,
modal,
},
computed: {
...mapState([
......@@ -43,7 +43,7 @@ export default {
{{buttonLabel}}
</span>
</button>
<popup-dialog
<modal
v-if="discardPopupOpen"
class="text-left"
:primary-button-label="__('Discard changes')"
......
......@@ -79,7 +79,11 @@ export default class Search {
.on('keyup', this.searchInput, this.searchKeyUp);
$(document)
.off('click', this.searchClear)
<<<<<<< HEAD
.on('click', this.searchClear, this.clearSearchField);
=======
.on('click', this.searchClear, this.clearSearchField.bind(this));
>>>>>>> upstream/master
}
static submitSearch() {
......
<script>
export default {
name: 'popup-dialog',
name: 'modal',
props: {
title: {
......@@ -75,7 +75,7 @@ export default {
<template>
<div class="modal-open">
<div
class="modal popup-dialog"
class="modal show"
role="dialog"
tabindex="-1"
>
......
<script>
import PopupDialog from './popup_dialog.vue';
import modal from './modal.vue';
export default {
name: 'recaptcha-dialog',
name: 'recaptcha-modal',
props: {
html: {
......@@ -20,7 +20,7 @@ export default {
},
components: {
PopupDialog,
modal,
},
methods: {
......@@ -65,9 +65,9 @@ export default {
</script>
<template>
<popup-dialog
<modal
kind="warning"
class="recaptcha-dialog js-recaptcha-dialog"
class="recaptcha-modal js-recaptcha-modal"
:hide-footer="true"
:title="__('Please solve the reCAPTCHA')"
@toggle="close"
......@@ -81,5 +81,5 @@ export default {
v-html="html"
></div>
</div>
</popup-dialog>
</modal>
</template>
import RecaptchaDialog from '../components/recaptcha_dialog.vue';
import recaptchaModal from '../components/recaptcha_modal.vue';
export default {
data() {
......@@ -9,7 +9,7 @@ export default {
},
components: {
RecaptchaDialog,
recaptchaModal,
},
methods: {
......
......@@ -19,6 +19,13 @@
max-width: 425px;
width: 100%;
}
&.svg-250 {
img,
svg {
width: 250px;
}
}
}
@mixin svg-size($size) {
......
......@@ -24,10 +24,14 @@
font-size: $gl-font-size;
line-height: 25px;
&.status-box-closed {
&.status-box-mr-closed {
background-color: $gl-danger;
}
&.status-box-issue-closed {
background-color: $gl-primary;
}
&.status-box-merged {
background-color: $gl-primary;
}
......
......@@ -44,11 +44,18 @@ body.modal-open {
}
}
.modal.popup-dialog {
display: block;
.modal {
background-color: $black-transparent;
z-index: 2100;
@media (min-width: $screen-md-min) {
.modal-dialog {
margin: 30px auto;
}
}
}
.recaptcha-dialog .recaptcha-form {
.recaptcha-modal .recaptcha-form {
display: inline-block;
.recaptcha {
......
......@@ -741,6 +741,7 @@ Image Commenting cursor
*/
$image-comment-cursor-left-offset: 12;
$image-comment-cursor-top-offset: 12;
<<<<<<< HEAD
/*
Add GitLab Slack Application
......@@ -752,6 +753,8 @@ $add-to-slack-logo-size: 100px;
$double-headed-arrow-width: 100px;
$double-headed-arrow-height: 25px;
$right-arrow-size: 16px;
=======
>>>>>>> upstream/master
/*
Popup
......
......@@ -458,6 +458,7 @@
margin: 5px;
}
<<<<<<< HEAD
.boards-title-holder {
padding: 25px 13px $gl-padding;
......@@ -482,6 +483,8 @@
border-top: 1px solid $border-color;
}
=======
>>>>>>> upstream/master
.page-with-contextual-sidebar.layout-page .issue-boards-sidebar {
.issuable-sidebar-header {
position: relative;
......
......@@ -610,11 +610,19 @@
}
.issuable-status-box {
float: none;
display: inline-block;
align-self: stretch;
display: flex;
justify-content: center;
align-items: center;
margin-top: 0;
height: auto;
align-self: center;
padding-left: 9px;
padding-right: 9px;
@media (min-width: $screen-sm-min) {
display: inline-block;
height: auto;
align-self: center;
}
}
.issuable-gutter-toggle {
......
......@@ -773,6 +773,7 @@
font-size: 16px;
}
}
<<<<<<< HEAD
.mr-widget-icon {
font-size: 22px;
......@@ -824,3 +825,5 @@
}
}
}
=======
>>>>>>> upstream/master
.modal.popup-dialog {
display: block;
background-color: $black-transparent;
z-index: 2100;
@media (min-width: $screen-md-min) {
.modal-dialog {
width: 600px;
margin: 30px auto;
}
}
}
.project-refs-form,
.project-refs-target-form {
display: inline-block;
......
class Admin::GroupsController < Admin::ApplicationController
include MembersPresentation
<<<<<<< HEAD
prepend EE::Admin::GroupsController
=======
>>>>>>> upstream/master
before_action :group, only: [:edit, :update, :destroy, :project_update, :members_update]
......
......@@ -6,6 +6,7 @@ module WithPerformanceBar
end
def peek_enabled?
return true if Rails.env.development?
return false unless Gitlab::PerformanceBar.enabled?(current_user)
if RequestStore.active?
......
......@@ -118,20 +118,24 @@ module BlobHelper
icon("#{file_type_icon_class('file', mode, name)} fw")
end
def blob_raw_path
def blob_raw_url(only_path: false)
if @build && @entry
raw_project_job_artifacts_path(@project, @build, path: @entry.path)
raw_project_job_artifacts_url(@project, @build, path: @entry.path, only_path: only_path)
elsif @snippet
if @snippet.project_id
raw_project_snippet_path(@project, @snippet)
raw_project_snippet_url(@project, @snippet, only_path: only_path)
else
raw_snippet_path(@snippet)
raw_snippet_url(@snippet, only_path: only_path)
end
elsif @blob
project_raw_path(@project, @id)
project_raw_url(@project, @id, only_path: only_path)
end
end
def blob_raw_path
blob_raw_url(only_path: true)
end
# SVGs can contain malicious JavaScript; only include whitelisted
# elements and attributes. Note that this whitelist is by no means complete
# and may omit some elements.
......
......@@ -104,15 +104,23 @@ module DiffHelper
].join(' ').html_safe
end
def diff_file_blob_raw_path(diff_file)
project_raw_path(@project, tree_join(diff_file.content_sha, diff_file.file_path))
def diff_file_blob_raw_url(diff_file, only_path: false)
project_raw_url(@project, tree_join(diff_file.content_sha, diff_file.file_path), only_path: only_path)
end
def diff_file_old_blob_raw_path(diff_file)
def diff_file_old_blob_raw_url(diff_file, only_path: false)
sha = diff_file.old_content_sha
return unless sha
project_raw_path(@project, tree_join(diff_file.old_content_sha, diff_file.old_path))
project_raw_url(@project, tree_join(diff_file.old_content_sha, diff_file.old_path), only_path: only_path)
end
def diff_file_blob_raw_path(diff_file)
diff_file_blob_raw_url(diff_file, only_path: true)
end
def diff_file_old_blob_raw_path(diff_file)
diff_file_old_blob_raw_url(diff_file, only_path: true)
end
def diff_file_html_data(project, diff_file_path, diff_commit_id)
......
......@@ -76,7 +76,7 @@ module IssuesHelper
elsif item.try(:merged?)
'status-box-merged'
elsif item.closed?
'status-box-closed'
'status-box-mr-closed'
elsif item.try(:upcoming?)
'status-box-upcoming'
else
......
module LabelsHelper
include ActionView::Helpers::TagHelper
def show_label_issuables_link?(label, issuables_type, current_user: nil, project: nil)
return true if label.is_a?(GroupLabel)
return true unless project
project.feature_available?(issuables_type, current_user)
end
# Link to a Label
#
# label - Label object to link to
......
......@@ -5,7 +5,7 @@ module Emails
@commit = @note.noteable
@target_url = project_commit_url(*note_target_url_options)
mail_answer_thread(@commit, note_thread_options(recipient_id))
mail_answer_note_thread(@commit, @note, note_thread_options(recipient_id))
end
def note_issue_email(recipient_id, note_id)
......@@ -13,7 +13,7 @@ module Emails
@issue = @note.noteable
@target_url = project_issue_url(*note_target_url_options)
mail_answer_thread(@issue, note_thread_options(recipient_id))
mail_answer_note_thread(@issue, @note, note_thread_options(recipient_id))
end
def note_merge_request_email(recipient_id, note_id)
......@@ -21,7 +21,7 @@ module Emails
@merge_request = @note.noteable
@target_url = project_merge_request_url(*note_target_url_options)
mail_answer_thread(@merge_request, note_thread_options(recipient_id))
mail_answer_note_thread(@merge_request, @note, note_thread_options(recipient_id))
end
def note_snippet_email(recipient_id, note_id)
......@@ -29,7 +29,7 @@ module Emails
@snippet = @note.noteable
@target_url = project_snippet_url(*note_target_url_options)
mail_answer_thread(@snippet, note_thread_options(recipient_id))
mail_answer_note_thread(@snippet, @note, note_thread_options(recipient_id))
end
def note_personal_snippet_email(recipient_id, note_id)
......@@ -37,7 +37,7 @@ module Emails
@snippet = @note.noteable
@target_url = snippet_url(@note.noteable)
mail_answer_thread(@snippet, note_thread_options(recipient_id))
mail_answer_note_thread(@snippet, @note, note_thread_options(recipient_id))
end
private
......
......@@ -123,8 +123,8 @@ class Notify < BaseMailer
headers['Reply-To'] = address
fallback_reply_message_id = "<reply-#{reply_key}@#{Gitlab.config.gitlab.host}>".freeze
headers['References'] ||= ''
headers['References'] << ' ' << fallback_reply_message_id
headers['References'] ||= []
headers['References'] << fallback_reply_message_id
@reply_by_email = true
end
......@@ -160,6 +160,18 @@ class Notify < BaseMailer
mail_thread(model, headers)
end
def mail_answer_note_thread(model, note, headers = {})
headers['Message-ID'] = message_id(note)
headers['In-Reply-To'] = message_id(note.references.last)
headers['References'] = note.references.map { |ref| message_id(ref) }
headers['X-GitLab-Discussion-ID'] = note.discussion.id if note.part_of_discussion?
headers[:subject]&.prepend('Re: ')
mail_thread(model, headers)
end
def reply_key
@reply_key ||= SentNotification.reply_key
end
......
......@@ -501,7 +501,6 @@ module Ci
end
def valid_dependency?
return false unless complete?
return false if artifacts_expired?
return false if erased?
......
......@@ -52,6 +52,20 @@ class Commit
diffs.reduce(0) { |sum, d| sum + Gitlab::Git::Util.count_lines(d.diff) }
end
def order_by(collection:, order_by:, sort:)
return collection unless %w[email name commits].include?(order_by)
return collection unless %w[asc desc].include?(sort)
collection.sort do |a, b|
operands = [a, b].tap { |o| o.reverse! if sort == 'desc' }
attr1, attr2 = operands.first.public_send(order_by), operands.second.public_send(order_by) # rubocop:disable PublicSend
# use case insensitive comparison for string values
order_by.in?(%w[email name]) ? attr1.casecmp(attr2) : attr1 <=> attr2
end
end
# Truncate sha to 8 characters
def truncate_sha(sha)
sha[0..MIN_SHA_LENGTH]
......
......@@ -85,8 +85,7 @@ module CacheMarkdownField
def cached_html_up_to_date?(markdown_field)
html_field = cached_markdown_fields.html_field(markdown_field)
cached = cached_html_for(markdown_field).present? && __send__(markdown_field).present? # rubocop:disable GitlabSecurity/PublicSend
return false unless cached
return false if cached_html_for(markdown_field).nil? && !__send__(markdown_field).nil? # rubocop:disable GitlabSecurity/PublicSend
markdown_changed = attribute_changed?(markdown_field) || false
html_changed = attribute_changed?(html_field) || false
......
......@@ -16,7 +16,7 @@ class Issue < ActiveRecord::Base
include ThrottledTouch
include IgnorableColumn
ignore_column :assignee_id
ignore_column :assignee_id, :branch_name
WEIGHT_RANGE = 1..9
WEIGHT_ALL = 'Everything'.freeze
......
......@@ -913,11 +913,11 @@ class MergeRequest < ActiveRecord::Base
def state_icon_name
if merged?
"check"
"git-merge"
elsif closed?
"times"
"close"
else
"circle-o"
"issue-open-m"
end
end
......
......@@ -368,6 +368,16 @@ class Note < ActiveRecord::Base
end
end
def references
refs = [noteable]
if part_of_discussion?
refs += discussion.notes.take_while { |n| n.id < id }
end
refs
end
def expire_etag_cache
return unless noteable&.discussions_rendered_on_frontend?
......@@ -409,6 +419,9 @@ class Note < ActiveRecord::Base
end
noteable_object&.touch
# We return the noteable object so we can re-use it in EE for ElasticSearch.
noteable_object
end
def banzai_render_context(field)
......
......@@ -669,7 +669,8 @@ class Project < ActiveRecord::Base
end
def import_started?
import? && import_status == 'started'
# import? does SQL work so only run it if it looks like there's an import running
import_status == 'started' && import?
end
def import_scheduled?
......@@ -1157,7 +1158,7 @@ class Project < ActiveRecord::Base
def change_head(branch)
if repository.branch_exists?(branch)
repository.before_change_head
repository.write_ref('HEAD', "refs/heads/#{branch}")
repository.write_ref('HEAD', "refs/heads/#{branch}", force: true)
repository.copy_gitattributes(branch)
repository.after_change_head
reload_default_branch
......
......@@ -24,6 +24,7 @@ class Repository
attr_accessor :full_path, :disk_path, :project, :is_wiki
delegate :ref_name_for_sha, to: :raw_repository
delegate :write_ref, to: :raw_repository
CreateTreeError = Class.new(StandardError)
......@@ -244,11 +245,10 @@ class Repository
# This will still fail if the file is corrupted (e.g. 0 bytes)
begin
write_ref(keep_around_ref_name(sha), sha)
rescue Rugged::ReferenceError => ex
Rails.logger.error "Unable to create #{REF_KEEP_AROUND} reference for repository #{path}: #{ex}"
rescue Rugged::OSError => ex
raise unless ex.message =~ /Failed to create locked file/ && ex.message =~ /File exists/
write_ref(keep_around_ref_name(sha), sha, force: true)
rescue Gitlab::Git::Repository::GitError => ex
# Necessary because https://gitlab.com/gitlab-org/gitlab-ce/issues/20156
return true if ex.message =~ /Failed to create locked file/ && ex.message =~ /File exists/
Rails.logger.error "Unable to create #{REF_KEEP_AROUND} reference for repository #{path}: #{ex}"
end
......@@ -258,10 +258,6 @@ class Repository
ref_exists?(keep_around_ref_name(sha))
end
def write_ref(ref_path, sha)
rugged.references.create(ref_path, sha, force: true)
end
def diverging_commit_counts(branch)
root_ref_hash = raw_repository.commit(root_ref).id
cache.fetch(:"diverging_commit_counts_#{branch.name}") do
......@@ -697,7 +693,9 @@ class Repository
def tags_sorted_by(value)
case value
when 'name'
when 'name_asc'
VersionSorter.sort(tags) { |tag| tag.name }
when 'name_desc'
VersionSorter.rsort(tags) { |tag| tag.name }
when 'updated_desc'
tags_sorted_by_committed_date.reverse
......@@ -708,10 +706,14 @@ class Repository
end
end
def contributors
# Params:
#
# order_by: name|email|commits
# sort: asc|desc default: 'asc'
def contributors(order_by: nil, sort: 'asc')
commits = self.commits(nil, limit: 2000, offset: 0, skip_merges: true)
commits.group_by(&:author_email).map do |email, commits|
commits = commits.group_by(&:author_email).map do |email, commits|
contributor = Gitlab::Contributor.new
contributor.email = email
......@@ -725,6 +727,7 @@ class Repository
contributor
end
Commit.order_by(collection: commits, order_by: order_by, sort: sort)
end
def refs_contains_sha(ref_type, sha)
......@@ -1043,7 +1046,7 @@ class Repository
end
def create_ref(ref, ref_path)
raw_repository.write_ref(ref_path, ref)
write_ref(ref_path, ref)
end
def ls_files(ref)
......
class GroupMemberPresenter < MemberPresenter
<<<<<<< HEAD
prepend EE::GroupMemberPresenter
=======
>>>>>>> upstream/master
private
def admin_member_permission
......
class MemberPresenter < Gitlab::View::Presenter::Delegated
<<<<<<< HEAD
prepend EE::MemberPresenter
=======
>>>>>>> upstream/master
presents :member
def access_level_roles
......
class ProjectMemberPresenter < MemberPresenter
<<<<<<< HEAD
prepend EE::ProjectMemberPresenter
=======
>>>>>>> upstream/master
private
def admin_member_permission
......
......@@ -39,11 +39,15 @@ module Ci
begin
# In case when 2 runners try to assign the same build, second runner will be declined
# with StateMachines::InvalidTransition or StaleObjectError when doing run! or save method.
build.runner_id = runner.id
build.run!
register_success(build)
return Result.new(build, true)
begin
build.runner_id = runner.id
build.run!
register_success(build)
return Result.new(build, true)
rescue Ci::Build::MissingDependenciesError
build.drop!(:missing_dependency_failure)
end
rescue StateMachines::InvalidTransition, ActiveRecord::StaleObjectError
# We are looping to find another build that is not conflicting
# It also indicates that this build can be picked and passed to runner.
......@@ -55,9 +59,6 @@ module Ci
# we still have to return 409 in the end,
# to make sure that this is properly handled by runner.
valid = false
rescue Ci::Build::MissingDependenciesError
build.drop!(:missing_dependency_failure)
valid = false
end
end
......
......@@ -108,12 +108,14 @@ class IssuableBaseService < BaseService
end
def merge_quick_actions_into_params!(issuable)
original_description = params.fetch(:description, issuable.description)
description, command_params =
QuickActions::InterpretService.new(project, current_user)
.execute(params[:description], issuable)
.execute(original_description, issuable)
# Avoid a description already set on an issuable to be overwritten by a nil
params[:description] = description if params.key?(:description)
params[:description] = description if description
params.merge!(command_params)
end
......
......@@ -83,12 +83,12 @@
You're all done!
- elsif current_user.todos.any?
.todos-all-done
.svg-content
.svg-content.svg-250
= image_tag 'illustrations/todos_all_done.svg'
- if todos_filter_empty?
%h4.text-center
= Gitlab.config.gitlab.no_todos_messages.sample
%p.text-center
%p
Are you looking for things to do? Take a look at
= succeed "," do
= link_to "the opened issues", issues_dashboard_path
......@@ -104,7 +104,7 @@
= image_tag 'illustrations/todos_empty.svg'
.todos-empty-content
%h4
Todos let you see what you should do next.
Todos let you see what you should do next
%p
When an issue or merge request is assigned to you, or when you
%strong
......
- project_meta = { id: @project.id, name: @project.name, namespace: @project.name_with_namespace, web_url: @project.web_url, avatar_url: @project.avatar_url } if @project&.persisted?
- project_meta = { id: @project.id, name: @project.name, namespace: @project.name_with_namespace, web_url: project_path(@project), avatar_url: @project.avatar_url } if @project&.persisted?
.projects-dropdown-container
.project-dropdown-sidebar
%ul
......
.file-content.image_file
= image_tag(blob_raw_path, alt: viewer.blob.name)
-# Uses the full URL rather than the path, to prevent it from getting prefixed with the asset host.
= image_tag(blob_raw_url, alt: viewer.blob.name)
.row.empty-state
.col-xs-12
.svg-content= image_tag 'illustrations/clusters_empty.svg'
.col-xs-12.text-center
.col-xs-12
.text-content
%h4= s_('ClusterIntegration|Integrate cluster automation')
%h4.text-center= s_('ClusterIntegration|Integrate cluster automation')
- link_to_help_page = link_to(s_('ClusterIntegration|Learn more about Clusters'), help_page_path('user/project/clusters/index'), target: '_blank', rel: 'noopener noreferrer')
%p= s_('ClusterIntegration|Clusters allow you to use review apps, deploy your applications, run your pipelines, and much more in an easy way. %{link_to_help_page}').html_safe % { link_to_help_page: link_to_help_page}
%p
.text-center
= link_to s_('ClusterIntegration|Add cluster'), new_project_cluster_path(@project), class: 'btn btn-success'
......@@ -8,7 +8,11 @@
.top-area.adjust
.nav-text
= s_("ClusterIntegration|Clusters can be used to deploy applications and to provide Review Apps for this project")
<<<<<<< HEAD
= render 'projects/ee/clusters/buttons', project: @project
=======
.ci-table.js-clusters-list
>>>>>>> upstream/master
.gl-responsive-table-row.table-row-header{ role: "row" }
.table-section.section-30{ role: "rowheader" }
= s_("ClusterIntegration|Cluster")
......
- blob = diff_file.blob
- old_blob = diff_file.old_blob
- blob_raw_path = diff_file_blob_raw_path(diff_file)
- old_blob_raw_path = diff_file_old_blob_raw_path(diff_file)
- blob_raw_url = diff_file_blob_raw_url(diff_file)
- old_blob_raw_url = diff_file_old_blob_raw_url(diff_file)
- click_to_comment = local_assigns.fetch(:click_to_comment, true)
- diff_view_data = local_assigns.fetch(:diff_view_data, '')
- class_name = ''
......@@ -13,7 +13,7 @@
.two-up.view
.wrap
.frame.deleted
= image_tag(old_blob_raw_path, alt: diff_file.old_path, lazy: false)
= image_tag(old_blob_raw_url, alt: diff_file.old_path, lazy: false)
%p.image-info.hide
%span.meta-filesize= number_to_human_size(old_blob.size)
|
......@@ -23,7 +23,7 @@
%strong H:
%span.meta-height
.wrap
= render partial: "projects/diffs/image_diff_frame", locals: { class_name: "added js-image-frame #{class_name}", position: position, note_type: DiffNote.name, image_path: blob_raw_path, alt: diff_file.new_path }
= render partial: "projects/diffs/image_diff_frame", locals: { class_name: "added js-image-frame #{class_name}", position: position, note_type: DiffNote.name, image_path: blob_raw_url, alt: diff_file.new_path }
%p.image-info.hide
%span.meta-filesize= number_to_human_size(blob.size)
|
......@@ -36,9 +36,9 @@
.swipe.view.hide
.swipe-frame
.frame.deleted
= image_tag(old_blob_raw_path, alt: diff_file.old_path, lazy: false)
= image_tag(old_blob_raw_url, alt: diff_file.old_path, lazy: false)
.swipe-wrap
= render partial: "projects/diffs/image_diff_frame", locals: { class_name: "added js-image-frame #{class_name}", position: position, note_type: DiffNote.name, image_path: blob_raw_path, alt: diff_file.new_path }
= render partial: "projects/diffs/image_diff_frame", locals: { class_name: "added js-image-frame #{class_name}", position: position, note_type: DiffNote.name, image_path: blob_raw_url, alt: diff_file.new_path }
%span.swipe-bar
%span.top-handle
%span.bottom-handle
......@@ -46,8 +46,8 @@
.onion-skin.view.hide
.onion-skin-frame
.frame.deleted
= image_tag(old_blob_raw_path, alt: diff_file.old_path, lazy: false)
= render partial: "projects/diffs/image_diff_frame", locals: { class_name: "added js-image-frame #{class_name}", position: position, note_type: DiffNote.name, image_path: blob_raw_path, alt: diff_file.new_path }
= image_tag(old_blob_raw_url, alt: diff_file.old_path, lazy: false)
= render partial: "projects/diffs/image_diff_frame", locals: { class_name: "added js-image-frame #{class_name}", position: position, note_type: DiffNote.name, image_path: blob_raw_url, alt: diff_file.new_path }
.controls
.transparent
.drag-track
......
- blob = diff_file.blob
- old_blob = diff_file.old_blob
- blob_raw_path = diff_file_blob_raw_path(diff_file)
- old_blob_raw_path = diff_file_old_blob_raw_path(diff_file)
- blob_raw_url = diff_file_blob_raw_url(diff_file)
- old_blob_raw_url = diff_file_old_blob_raw_url(diff_file)
- click_to_comment = local_assigns.fetch(:click_to_comment, true)
- diff_view_data = local_assigns.fetch(:diff_view_data, '')
- class_name = ''
......@@ -12,5 +12,5 @@
.image.js-single-image{ data: diff_view_data }
.wrap
- single_class_name = diff_file.deleted_file? ? 'deleted' : 'added'
= render partial: "projects/diffs/image_diff_frame", locals: { class_name: "#{single_class_name} #{class_name} js-image-frame", position: position, note_type: DiffNote.name, image_path: blob_raw_path, alt: diff_file.file_path }
= render partial: "projects/diffs/image_diff_frame", locals: { class_name: "#{single_class_name} #{class_name} js-image-frame", position: position, note_type: DiffNote.name, image_path: blob_raw_url, alt: diff_file.file_path }
%p.image-info= number_to_human_size(blob.size)
......@@ -17,12 +17,12 @@
.detail-page-header
.detail-page-header-body
.issuable-status-box.status-box.status-box-closed{ class: issue_button_visibility(@issue, false) }
= icon('check', class: "hidden-sm hidden-md hidden-lg")
.issuable-status-box.status-box.status-box-issue-closed{ class: issue_button_visibility(@issue, false) }
= sprite_icon('mobile-issue-close', size: 16, css_class: 'hidden-sm hidden-md hidden-lg')
%span.hidden-xs
Closed
.issuable-status-box.status-box.status-box-open{ class: issue_button_visibility(@issue, true) }
= icon('circle-o', class: "hidden-sm hidden-md hidden-lg")
= sprite_icon('issue-open-m', size: 16, css_class: 'hidden-sm hidden-md hidden-lg')
%span.hidden-xs Open
.issuable-meta
......
......@@ -7,7 +7,7 @@
.detail-page-header
.detail-page-header-body
.issuable-status-box.status-box{ class: status_box_class(@merge_request) }
= icon(@merge_request.state_icon_name, class: "hidden-sm hidden-md hidden-lg")
= sprite_icon(@merge_request.state_icon_name, size: 16, css_class: 'hidden-sm hidden-md hidden-lg')
%span.hidden-xs
= @merge_request.state_human_name
......@@ -27,7 +27,11 @@
.dropdown-menu.dropdown-menu-align-right.hidden-lg
%ul
- if can_update_merge_request
<<<<<<< HEAD
%li= link_to 'Edit', edit_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), class: 'js-issuable-edit'
=======
%li= link_to 'Edit', edit_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)
>>>>>>> upstream/master
- unless current_user == @merge_request.author
%li= link_to 'Report abuse', new_abuse_report_path(user_id: @merge_request.author.id, ref_url: merge_request_url(@merge_request))
- if can_update_merge_request
......
......@@ -14,7 +14,7 @@
.form-group
= label_tag :tag_name, nil, class: 'control-label'
.col-sm-10
= text_field_tag :tag_name, params[:tag_name], required: true, tabindex: 1, autofocus: true, class: 'form-control'
= text_field_tag :tag_name, params[:tag_name], required: true, autofocus: true, class: 'form-control'
.form-group
= label_tag :ref, 'Create from', class: 'control-label'
.col-sm-10.create-from
......@@ -28,7 +28,7 @@
.form-group
= label_tag :message, nil, class: 'control-label'
.col-sm-10
= text_area_tag :message, @message, required: false, tabindex: 3, class: 'form-control', rows: 5
= text_area_tag :message, @message, required: false, class: 'form-control', rows: 5
.help-block
= s_('TagsPage|Optionally, add a message to the tag.')
%hr
......@@ -41,6 +41,6 @@
.help-block
= s_('TagsPage|Optionally, add release notes to the tag. They will be stored in the GitLab database and displayed on the tags page.')
.form-actions
= button_tag s_('TagsPage|Create tag'), class: 'btn btn-create', tabindex: 3
= button_tag s_('TagsPage|Create tag'), class: 'btn btn-create'
= link_to s_('TagsPage|Cancel'), project_tags_path(@project), class: 'btn btn-cancel'
%script#availableRefs{ type: "application/json" }= @project.repository.ref_names.to_json.html_safe
......@@ -2,6 +2,8 @@
- status = label_subscription_status(label, @project).inquiry if current_user
- subject = local_assigns[:subject]
- toggle_subscription_path = toggle_subscription_label_path(label, @project) if current_user
- show_label_merge_requests_link = show_label_issuables_link?(label, :merge_requests, project: @project)
- show_label_issues_link = show_label_issuables_link?(label, :issues, project: @project)
%li{ id: label_css_id, data: { id: label.id } }
= render "shared/label_row", label: label
......@@ -12,12 +14,14 @@
= icon('caret-down')
.dropdown-menu.dropdown-menu-align-right
%ul
%li
= link_to_label(label, subject: subject, type: :merge_request) do
View merge requests
%li
= link_to_label(label, subject: subject) do
View open issues
- if show_label_merge_requests_link
%li
= link_to_label(label, subject: subject, type: :merge_request) do
View merge requests
- if show_label_issues_link
%li
= link_to_label(label, subject: subject) do
View open issues
- if current_user
%li.label-subscription
- if can_subscribe_to_label_in_different_levels?(label)
......@@ -43,10 +47,12 @@
class: 'text-danger'
.pull-right.hidden-xs.hidden-sm.hidden-md
= link_to_label(label, subject: subject, type: :merge_request, css_class: 'btn btn-transparent btn-action btn-link') do
view merge requests
= link_to_label(label, subject: subject, css_class: 'btn btn-transparent btn-action btn-link') do
view open issues
- if show_label_merge_requests_link
= link_to_label(label, subject: subject, type: :merge_request, css_class: 'btn btn-transparent btn-action btn-link') do
view merge requests
- if show_label_issues_link
= link_to_label(label, subject: subject, css_class: 'btn btn-transparent btn-action btn-link') do
view open issues
- if current_user
.label-subscription.inline
......
......@@ -6,18 +6,21 @@
.col-xs-12
.svg-content
= image_tag 'illustrations/issues.svg'
.col-xs-12.text-center
.col-xs-12
.text-content
- if has_button && current_user
%h4
The Issue Tracker is the place to add things that need to be improved or solved in a project
= _("The Issue Tracker is the place to add things that need to be improved or solved in a project")
%p
Issues can be bugs, tasks or ideas to be discussed.
Also, issues are searchable and filterable.
- if project_select_button
= render 'shared/new_project_item_select', path: 'issues/new', label: 'New issue', type: :issues
- else
= link_to 'New issue', button_path, class: 'btn btn-new', title: 'New issue', id: 'new_issue_link'
= _("Issues can be bugs, tasks or ideas to be discussed. Also, issues are searchable and filterable.")
.text-center
- if project_select_button
= render 'shared/new_project_item_select', path: 'issues/new', label: 'New issue', type: :issues
- else
= link_to 'New issue', button_path, class: 'btn btn-success', title: 'New issue', id: 'new_issue_link'
- else
%h4.text-center= _("There are no issues to show")
%p
= _("The Issue Tracker is the place to add things that need to be improved or solved in a project. You can register or sign in to create issues for this project.")
.text-center
%h4 There are no issues to show.
= link_to _('Register / Sign In'), new_user_session_path, class: 'btn btn-success'
......@@ -2,10 +2,10 @@
.col-xs-12
.svg-content
= image_tag 'illustrations/labels.svg'
.col-xs-12.text-center
.col-xs-12
.text-content
%h4 Labels can be applied to issues and merge requests to categorize them.
%p You can also star a label to make it a priority label.
%h4= _("Labels can be applied to issues and merge requests to categorize them.")
%p= _("You can also star a label to make it a priority label.")
- if can?(current_user, :admin_label, @project)
= link_to 'New label', new_project_label_path(@project), class: 'btn btn-new', title: 'New label', id: 'new_label_link'
= link_to 'Generate a default set of labels', generate_project_labels_path(@project), method: :post, class: 'btn btn-success btn-inverted', title: 'Generate a default set of labels', id: 'generate_labels_link'
= link_to _('New label'), new_project_label_path(@project), class: 'btn btn-new', title: _('New label'), id: 'new_label_link'
= link_to _('Generate a default set of labels'), generate_project_labels_path(@project), method: :post, class: 'btn btn-success btn-inverted', title: _('Generate a default set of labels'), id: 'generate_labels_link'
......@@ -6,17 +6,18 @@
.col-xs-12
.svg-content
= image_tag 'illustrations/merge_requests.svg'
.col-xs-12.text-center
.col-xs-12
.text-content
- if has_button
%h4
Merge requests are a place to propose changes you've made to a project and discuss those changes with others.
= _("Merge requests are a place to propose changes you've made to a project and discuss those changes with others")
%p
Interested parties can even contribute by pushing commits if they want to.
- if project_select_button
= render 'shared/new_project_item_select', path: 'merge_requests/new', label: 'New merge request', type: :merge_requests
- else
= link_to 'New merge request', button_path, class: 'btn btn-new', title: 'New merge request', id: 'new_merge_request_link'
= _("Interested parties can even contribute by pushing commits if they want to.")
.text-center
- if project_select_button
= render 'shared/new_project_item_select', path: 'merge_requests/new', label: _('New merge request'), type: :merge_requests
- else
= link_to _('New merge request'), button_path, class: 'btn btn-new', title: _('New merge request'), id: 'new_merge_request_link'
- else
%h4.text-center
There are no merge requests to show.
= _("There are no merge requests to show")
......@@ -62,7 +62,10 @@
= f.hidden_field :access_level
.member-form-control.dropdown.append-right-5
%button.dropdown-menu-toggle.js-member-permissions-dropdown{ type: "button",
<<<<<<< HEAD
disabled: member.can_override?,
=======
>>>>>>> upstream/master
data: { toggle: "dropdown", field_name: "#{f.object_name}[access_level]" } }
%span.dropdown-toggle-text
= member.human_access
......@@ -82,7 +85,10 @@
can_override: member.can_override?
.prepend-left-5.clearable-input.member-form-control
= f.text_field :expires_at,
<<<<<<< HEAD
disabled: member.can_override?,
=======
>>>>>>> upstream/master
class: 'form-control js-access-expiration-date js-member-update-control',
placeholder: 'Expiration date',
id: "member_expires_at_#{member.id}",
......
......@@ -96,6 +96,7 @@
- update_user_activity
- upload_checksum
- web_hook
<<<<<<< HEAD
# EE-specific queues
- cronjob:clear_shared_runners_minutes
......@@ -130,3 +131,5 @@
- rebase
- repository_update_mirror
- repository_update_remote_mirror
=======
>>>>>>> upstream/master
---
title: Adds ordering to projects contributors in API
merge_request: 15469
author: Jacopo Beschi @jacopo-beschi
type: added
---
title: Update issuable status icons
merge_request: 15898
author:
type: changed
---
title: Fix broken illustration images for monitoring page empty states
merge_request: 15889
author:
type: fixed
---
title: add support for sorting in tags api
merge_request: 15772
author: haseebeqx
type: added
---
title: Use relative URL for projects to avoid storing domains
merge_request: 15876
author:
type: fixed
---
title: Add a gitlab:tcp_check rake task
merge_request: 15759
author:
type: added
---
title: Use app host instead of asset host when rendering image blob or diff
merge_request:
author:
type: fixed
---
title: Execute quick actions (if present) when creating MR from issue
merge_request: 15810
author:
type: fixed
---
title: Fixed typo for issue description field declaration
merge_request:
author: Marcus Amargi
type: fixed
---
title: Treat empty markdown and html strings as valid cached text, not missing cache
that needs to be updated
merge_request:
author:
type: performance
---
title: check the import_status field before doing SQL operations to check the import
url
merge_request:
author:
type: performance
---
title: removed tabindexes from tag form
merge_request:
author: Marcus Amargi
type: changed
---
title: Hide link to issues/MRs from labels list if issues/MRs are disabled.
merge_request: 15863
author: Sophie Herold
type: fixed
---
title: Make mail notifications of discussion notes In-Reply-To of each other
merge_request: 14289
author:
type: changed
......@@ -3,9 +3,9 @@
#
# If you come up with a fun one, please feel free to contribute it to GitLab!
# https://about.gitlab.com/contributing/
---
- Good job! Looks like you don't have any todos left.
---
- Good job! Looks like you don't have any todos left
- Isn't an empty todo list beautiful?
- Give yourself a pat on the back!
- Nothing left to do, high five!
- Henceforth you shall be known as "Todo Destroyer".
- Henceforth you shall be known as "Todo Destroyer"
......@@ -4,6 +4,12 @@ class AddNewProjectGuidelinesToAppearances < ActiveRecord::Migration
DOWNTIME = false
def change
# Clears the current Appearance cache otherwise it breaks since
# new_project_guidelines_html would be missing. See
# https://gitlab.com/gitlab-org/gitlab-ce/issues/41041
# We're not using Appearance#flush_redis_cache on purpose here.
Rails.cache.delete('current_appearance')
change_table :appearances do |t|
t.text :new_project_guidelines
t.text :new_project_guidelines_html
......
......@@ -23,6 +23,7 @@ Learn how to install, configure, update, and maintain your GitLab instance.
- **(EEP)** [GitLab GEO](../gitlab-geo/README.md): Replicate your GitLab instance to other geographical locations as a read-only fully operational version.
- **(EEP)** [Pivotal Tile](../install/pivotal/index.md): Deploy GitLab as a pre-configured appliance using Ops Manager (BOSH) for Pivotal Cloud Foundry.
- [High Availability](high_availability/README.md): Configure multiple servers for scaling or high availability.
- [High Availability on AWS](../university/high-availability/aws/README.md): Set up GitLab HA on Amazon AWS.
### Configuring GitLab
......@@ -44,6 +45,13 @@ Learn how to install, configure, update, and maintain your GitLab instance.
- [Welcome message](../customization/welcome_message.md): Add a custom welcome message to the sign-in page.
- ["New Project" page](../customization/new_project_page.md): Customize the text to be displayed on the page that opens whenever your users create a new project.
#### Customizing GitLab's appearance
- [Header logo](../customization/branded_page_and_email_header.md): Change the logo on all pages and email headers.
- [Branded login page](../customization/branded_login_page.md): Customize the login page with your own logo, title, and description.
- [Welcome message](../customization/welcome_message.md): Add a custom welcome message to the sign-in page.
- ["New Project" page](../customization/new_project_page.md): Customize the text to be displayed on the page that opens whenever your users create a new project.
### Maintaining GitLab
- [Raketasks](../raketasks/README.md): Perform various tasks for maintenance, backups, automatic webhooks setup, etc.
......@@ -123,20 +131,22 @@ server with IMAP authentication on Ubuntu, to be used with Reply by email.
## Monitoring GitLab
- [Monitoring uptime](../user/admin_area/monitoring/health_check.md): Check the server status using the health check endpoint.
- [IP whitelist](monitoring/ip_whitelist.md): Monitor endpoints that provide health check information when probed.
- [Monitoring GitHub imports](monitoring/github_imports.md): GitLab's GitHub Importer displays Prometheus metrics to monitor the health and progress of the importer.
- [Monitoring GitLab](monitoring/index.md):
- [Monitoring uptime](../user/admin_area/monitoring/health_check.md): Check the server status using the health check endpoint.
- [IP whitelist](monitoring/ip_whitelist.md): Monitor endpoints that provide health check information when probed.
- [Monitoring GitHub imports](monitoring/github_imports.md): GitLab's GitHub Importer displays Prometheus metrics to monitor the health and progress of the importer.
- [Conversational Development (ConvDev) Index](../user/admin_area/monitoring/convdev.md): Provides an overview of your entire instance's feature usage.
### Performance Monitoring
- [GitLab Performance Monitoring](monitoring/performance/gitlab_configuration.md): Enable GitLab Performance Monitoring.
- [GitLab performance monitoring with InfluxDB](monitoring/performance/introduction.md): Configure GitLab and InfluxDB for measuring performance metrics.
- [InfluxDB Schema](monitoring/performance/influxdb_schema.md): Measurements stored in InfluxDB.
- [GitLab performance monitoring with Prometheus](monitoring/prometheus/index.md): Configure GitLab and Prometheus for measuring performance metrics.
- [GitLab performance monitoring with Grafana](monitoring/prometheus/index.md): Configure GitLab to visualize time series metrics through graphs and dashboards.
- [Request Profiling](monitoring/performance/request_profiling.md): Get a detailed profile on slow requests.
- [Performance Bar](monitoring/performance/performance_bar.md): Get performance information for the current page.
- [GitLab Performance Monitoring](monitoring/performance/index.md):
- [Enable Performance Monitoring](monitoring/performance/gitlab_configuration.md): Enable GitLab Performance Monitoring.
- [GitLab performance monitoring with InfluxDB](monitoring/performance/influxdb_configuration.md): Configure GitLab and InfluxDB for measuring performance metrics.
- [InfluxDB Schema](monitoring/performance/influxdb_schema.md): Measurements stored in InfluxDB.
- [GitLab performance monitoring with Prometheus](monitoring/prometheus/index.md): Configure GitLab and Prometheus for measuring performance metrics.
- [GitLab performance monitoring with Grafana](monitoring/performance/grafana_configuration.md): Configure GitLab to visualize time series metrics through graphs and dashboards.
- [Request Profiling](monitoring/performance/request_profiling.md): Get a detailed profile on slow requests.
- [Performance Bar](monitoring/performance/performance_bar.md): Get performance information for the current page.
## Troubleshooting
......
# Monitoring GitLab
Explore our features to monitor your GitLab instance:
- [Performance monitoring](performance/index.md): GitLab Performance Monitoring makes it possible to measure a wide variety of statistics of your instance.
- [Prometheus](prometheus/index.md): Prometheus is a powerful time-series monitoring service, providing a flexible platform for monitoring GitLab and other software products.
- [GitHub imports](github_imports.md): Monitor the health and progress of GitLab's GitHub importer with various Prometheus metrics.
- [Monitoring uptime](../user/admin_area/monitoring/health_check.md): Check the server status using the health check endpoint.
- [IP whitelists](ip_whitelist.md): Configure GitLab for monitoring endpoints that provide health check information when probed.
# GitLab Performance Monitoring
GitLab comes with its own application performance measuring system as of GitLab
8.4, simply called "GitLab Performance Monitoring". GitLab Performance Monitoring is available in both the
Community and Enterprise editions.
Apart from this introduction, you are advised to read through the following
documents in order to understand and properly configure GitLab Performance Monitoring:
- [GitLab Configuration](gitlab_configuration.md)
- [InfluxDB Install/Configuration](influxdb_configuration.md)
- [InfluxDB Schema](influxdb_schema.md)
- [Grafana Install/Configuration](grafana_configuration.md)
- [Performance bar](performance_bar.md)
- [Request profiling](request_profiling.md)
>**Note:**
Omnibus GitLab 8.16 includes Prometheus as an additional tool to collect
metrics. It will eventually replace InfluxDB when their metrics collection is
on par. Read more in the [Prometheus documentation](../prometheus/index.md).
## Introduction to GitLab Performance Monitoring
GitLab Performance Monitoring makes it possible to measure a wide variety of statistics
including (but not limited to):
- The time it took to complete a transaction (a web request or Sidekiq job).
- The time spent in running SQL queries and rendering HAML views.
- The time spent executing (instrumented) Ruby methods.
- Ruby object allocations, and retained objects in particular.
- System statistics such as the process' memory usage and open file descriptors.
- Ruby garbage collection statistics.
Metrics data is written to [InfluxDB][influxdb] over [UDP][influxdb-udp]. Stored
data can be visualized using [Grafana][grafana] or any other application that
supports reading data from InfluxDB. Alternatively data can be queried using the
InfluxDB CLI.
## Metric Types
Two types of metrics are collected:
1. Transaction specific metrics.
1. Sampled metrics, collected at a certain interval in a separate thread.
### Transaction Metrics
Transaction metrics are metrics that can be associated with a single
transaction. This includes statistics such as the transaction duration, timings
of any executed SQL queries, time spent rendering HAML views, etc. These metrics
are collected for every Rack request and Sidekiq job processed.
### Sampled Metrics
Sampled metrics are metrics that can't be associated with a single transaction.
Examples include garbage collection statistics and retained Ruby objects. These
metrics are collected at a regular interval. This interval is made up out of two
parts:
1. A user defined interval.
1. A randomly generated offset added on top of the interval, the same offset
can't be used twice in a row.
The actual interval can be anywhere between a half of the defined interval and a
half above the interval. For example, for a user defined interval of 15 seconds
the actual interval can be anywhere between 7.5 and 22.5. The interval is
re-generated for every sampling run instead of being generated once and re-used
for the duration of the process' lifetime.
[influxdb]: https://influxdata.com/time-series-platform/influxdb/
[influxdb-udp]: https://docs.influxdata.com/influxdb/v0.9/write_protocols/udp/
[grafana]: http://grafana.org/
# GitLab Performance Monitoring
GitLab comes with its own application performance measuring system as of GitLab
8.4, simply called "GitLab Performance Monitoring". GitLab Performance Monitoring is available in both the
Community and Enterprise editions.
Apart from this introduction, you are advised to read through the following
documents in order to understand and properly configure GitLab Performance Monitoring:
- [GitLab Configuration](gitlab_configuration.md)
- [InfluxDB Install/Configuration](influxdb_configuration.md)
- [InfluxDB Schema](influxdb_schema.md)
- [Grafana Install/Configuration](grafana_configuration.md)
>**Note:**
Omnibus GitLab 8.16 includes Prometheus as an additional tool to collect
metrics. It will eventually replace InfluxDB when their metrics collection is
on par. Read more in the [Prometheus documentation](../prometheus/index.md).
## Introduction to GitLab Performance Monitoring
GitLab Performance Monitoring makes it possible to measure a wide variety of statistics
including (but not limited to):
- The time it took to complete a transaction (a web request or Sidekiq job).
- The time spent in running SQL queries and rendering HAML views.
- The time spent executing (instrumented) Ruby methods.
- Ruby object allocations, and retained objects in particular.
- System statistics such as the process' memory usage and open file descriptors.
- Ruby garbage collection statistics.
Metrics data is written to [InfluxDB][influxdb] over [UDP][influxdb-udp]. Stored
data can be visualized using [Grafana][grafana] or any other application that
supports reading data from InfluxDB. Alternatively data can be queried using the
InfluxDB CLI.
## Metric Types
Two types of metrics are collected:
1. Transaction specific metrics.
1. Sampled metrics, collected at a certain interval in a separate thread.
### Transaction Metrics
Transaction metrics are metrics that can be associated with a single
transaction. This includes statistics such as the transaction duration, timings
of any executed SQL queries, time spent rendering HAML views, etc. These metrics
are collected for every Rack request and Sidekiq job processed.
### Sampled Metrics
Sampled metrics are metrics that can't be associated with a single transaction.
Examples include garbage collection statistics and retained Ruby objects. These
metrics are collected at a regular interval. This interval is made up out of two
parts:
1. A user defined interval.
1. A randomly generated offset added on top of the interval, the same offset
can't be used twice in a row.
The actual interval can be anywhere between a half of the defined interval and a
half above the interval. For example, for a user defined interval of 15 seconds
the actual interval can be anywhere between 7.5 and 22.5. The interval is
re-generated for every sampling run instead of being generated once and re-used
for the duration of the process' lifetime.
[influxdb]: https://influxdata.com/time-series-platform/influxdb/
[influxdb-udp]: https://docs.influxdata.com/influxdb/v0.9/write_protocols/udp/
[grafana]: http://grafana.org/
This document was moved to [another location](index.md).
......@@ -221,3 +221,22 @@ sudo gitlab-rake gitlab:shell:create_hooks
cd /home/git/gitlab
sudo -u git -H bundle exec rake gitlab:shell:create_hooks RAILS_ENV=production
```
## Check TCP connectivity to a remote site
Sometimes you need to know if your GitLab installation can connect to a TCP
service on another machine - perhaps a PostgreSQL or HTTPS server. A rake task
is included to help you with this:
**Omnibus Installation**
```
sudo gitlab-rake gitlab:tcp_check[example.com,80]
```
**Source Installation**
```
cd /home/git/gitlab
sudo -u git -H bundle exec rake gitlab:tcp_check[example.com,80] RAILS_ENV=production
```
......@@ -89,9 +89,11 @@ email address in order to sign up.
If you also host a public-facing GitLab instance at `hooli.com` and set your
incoming email domain to `hooli.com`, an attacker could abuse the "Create new
issue by email" feature by using a project's unique address as the email when
signing up for Slack, which would send a confirmation email, which would create
a new issue on the project owned by the attacker, allowing them to click the
issue by email" or
"[Create new merge request by email](../user/project/merge_requests/index.md#create-new-merge-requests-by-email)"
features by using a project's unique address as the email when signing up for
Slack, which would send a confirmation email, which would create a new issue or
merge request on the project owned by the attacker, allowing them to click the
confirmation link and validate their account on your company's private Slack
instance.
......
......@@ -520,9 +520,9 @@ PUT /projects/:id/issues/:issue_iid
| `title` | string | no | The title of an issue |
| `description` | string | no | The description of an issue |
| `confidential` | boolean | no | Updates an issue to be confidential |
| `assignee_ids` | Array[integer] | no | The ID of the users to assign the issue to |
| `milestone_id` | integer | no | The ID of a milestone to assign the issue to |
| `labels` | string | no | Comma-separated label names for an issue |
| `assignee_ids` | Array[integer] | no | The ID of the user(s) to assign the issue to. Set to `0` or provide an empty value to unassign all assignees. |
| `milestone_id` | integer | no | The ID of a milestone to assign the issue to. Set to `0` or provide an empty value to unassign a milestone.|
| `labels` | string | no | Comma-separated label names for an issue. Set to an empty string to unassign all labels. |
| `state_event` | string | no | The state event of an issue. Set `close` to close the issue and `reopen` to reopen it |
| `updated_at` | string | no | Date time string, ISO 8601 formatted, e.g. `2016-03-11T03:45:40Z` (requires admin or project owner rights) |
| `due_date` | string | no | Date time string in the format YEAR-MONTH-DAY, e.g. `2016-03-11` |
......
......@@ -543,15 +543,15 @@ PUT /projects/:id/merge_requests/:merge_request_iid
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `merge_request_iid` | integer | yes | The ID of a merge request |
| `target_branch` | string | no | The target branch |
| `title` | string | no | Title of MR |
| `assignee_id` | integer | no | Assignee user ID |
| `assignee_id` | integer | no | The ID of the user to assign the merge request to. Set to `0` or provide an empty value to unassign all assignees. |
| `milestone_id` | integer | no | The ID of a milestone to assign the merge request to. Set to `0` or provide an empty value to unassign a milestone.|
| `labels` | string | no | Comma-separated label names for an merge request. Set to an empty string to unassign all labels. |
| `description` | string | no | Description of MR |
| `state_event` | string | no | New state (close/reopen) |
| `labels` | string | no | Labels for MR as a comma-separated list |
| `milestone_id` | integer | no | The ID of a milestone |
| `remove_source_branch` | boolean | no | Flag indicating if a merge request should remove the source branch when merging |
| `squash` | boolean| no | Squash commits into a single commit when merging |
| `discussion_locked` | boolean | no | Flag indicating if the merge request's discussion is locked. If the discussion is locked only project members can add, edit or resolve comments. |
......
......@@ -182,6 +182,8 @@ GET /projects/:id/repository/contributors
Parameters:
- `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `order_by` (optional) - Return contributors ordered by `name`, `email`, or `commits` fields. If not given contributors are ordered by commit date.
- `sort` (optional) - Return contributors sorted in `asc` or `desc` order. Default is `asc`
Response:
......
......@@ -12,7 +12,11 @@ GET /projects/:id/repository/tags
Parameters:
- `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `id` | integer/string| yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user|
| `order_by` | string | no | Return tags ordered by `name` or `updated` fields. Default is `updated` |
| `sort` | string | no | Return tags sorted in `asc` or `desc` order. Default is `desc` |
```json
[
......
......@@ -319,45 +319,62 @@ As you can see, the syntax of `command` is similar to [Dockerfile's `CMD`][cmd].
> Introduced in GitLab and GitLab Runner 9.4. Read more about the [extended
configuration options](#extended-docker-configuration-options).
Before showing the available entrypoint override methods, let's describe shortly
how the Runner starts and uses a Docker image for the containers used in the
CI jobs:
1. The Runner starts a Docker container using the defined entrypoint (default
from `Dockerfile` that may be overridden in `.gitlab-ci.yml`)
1. The Runner attaches itself to a running container.
1. The Runner prepares a script (the combination of
[`before_script`](../yaml/README.md#before_script),
[`script`](../yaml/README.md#script),
and [`after_script`](../yaml/README.md#after_script)).
1. The Runner sends the script to the container's shell STDIN and receives the
output.
To override the entrypoint of a Docker image, the recommended solution is to
define an empty `entrypoint` in `.gitlab-ci.yml`, so the Runner doesn't start
a useless shell layer. However, that will not work for all Docker versions, and
you should check which one your Runner is using. Specifically:
- If Docker 17.06 or later is used, the `entrypoint` can be set to an empty value.
- If Docker 17.03 or previous versions are used, the `entrypoint` can be set to
`/bin/sh -c`, `/bin/bash -c` or an equivalent shell available in the image.
The syntax of `image:entrypoint` is similar to [Dockerfile's `ENTRYPOINT`][entrypoint].
----
Let's assume you have a `super/sql:experimental` image with some SQL database
inside it and you would like to use it as a base image for your job because you
want to execute some tests with this database binary. Let's also assume that
this image is configured with `/usr/bin/super-sql run` as an entrypoint. That
means, that when starting the container without additional options, it will run
means that when starting the container without additional options, it will run
the database's process, while Runner expects that the image will have no
entrypoint or at least will start with a shell as its entrypoint.
Before the new extended Docker configuration options, you would need to create
your own image based on the `super/sql:experimental` image, set the entrypoint
to a shell and then use it in job's configuration, like:
entrypoint or that the entrypoint is prepared to start a shell command.
```Dockerfile
# my-super-sql:experimental image's Dockerfile
With the extended Docker configuration options, instead of creating your
own image based on `super/sql:experimental`, setting the `ENTRYPOINT`
to a shell, and then using the new image in your CI job, you can now simply
define an `entrypoint` in `.gitlab-ci.yml`.
FROM super/sql:experimental
ENTRYPOINT ["/bin/sh"]
```
**For Docker 17.06+:**
```yaml
# .gitlab-ci.yml
image: my-super-sql:experimental
image:
name: super/sql:experimental
entrypoint: [""]
```
After the new extended Docker configuration options, you can now simply
set an `entrypoint` in `.gitlab-ci.yml`, like:
**For Docker =< 17.03:**
```yaml
# .gitlab-ci.yml
image:
name: super/sql:experimental
entrypoint: ["/bin/sh"]
entrypoint: ["/bin/sh", "-c"]
```
As you can see the syntax of `entrypoint` is similar to
[Dockerfile's `ENTRYPOINT`][entrypoint].
## Define image and services in `config.toml`
Look for the `[runners.docker]` section:
......
This diff is collapsed.
......@@ -232,14 +232,15 @@ An example project service that defines deployment variables is
## Debug tracing
> Introduced in GitLab Runner 1.7.
>
> **WARNING:** Enabling debug tracing can have severe security implications. The
output **will** contain the content of all your secret variables and any other
secrets! The output **will** be uploaded to the GitLab server and made visible
in job traces!
CAUTION: **Warning:**
Enabling debug tracing can have severe security implications. The
output **will** contain the content of all your secret variables and any other
secrets! The output **will** be uploaded to the GitLab server and made visible
in job traces!
By default, GitLab Runner hides most of the details of what it is doing when
processing a job. This behaviour keeps job traces short, and prevents secrets
processing a job. This behavior keeps job traces short, and prevents secrets
from being leaked into the trace unless your script writes them to the screen.
If a job isn't working as expected, this can make the problem difficult to
......
......@@ -215,6 +215,9 @@ There is also and alternative method to [translate messages from validation erro
sprintf(__('Hello %{username}'), { username: 'Joe' }) => 'Hello Joe'
```
The placeholders should match the code style of the respective source file.
For example use `%{created_at}` in Ruby but `%{createdAt}` in JavaScript.
### Plurals
- In Ruby/HAML:
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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