Commit 5b7abbac authored by Rémy Coutable's avatar Rémy Coutable

Merge branch 'ce-to-ee-2017-11-22' into 'master'

CE upstream - Wednesday

Closes #4100, gitlab-com/gitlab-docs#142, #3711, gitaly#758, gitlab-ce#40283, gitlab-ce#40295, gitlab-com/infrastructure#3240, gitaly#742, gitlab-ce#39821, gitlab-qa#102, gitaly#740, gitlab-ce#31825 et gitlab-ce#39497

See merge request gitlab-org/gitlab-ee!3522
parents 8a72b78b cf9c8834
......@@ -216,7 +216,7 @@ review-docs-deploy:
name: review-docs/$CI_COMMIT_REF_NAME
# DOCS_REVIEW_APPS_DOMAIN and DOCS_GITLAB_REPO_SUFFIX are secret variables
# Discussion: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/14236/diffs#note_40140693
url: http://preview-$CI_COMMIT_REF_SLUG.$DOCS_REVIEW_APPS_DOMAIN/$DOCS_GITLAB_REPO_SUFFIX
url: http://$DOCS_GITLAB_REPO_SUFFIX-$CI_COMMIT_REF_SLUG.$DOCS_REVIEW_APPS_DOMAIN/$DOCS_GITLAB_REPO_SUFFIX
on_stop: review-docs-cleanup
script:
- ./trigger-build-docs deploy
......@@ -279,7 +279,7 @@ flaky-examples-check:
USE_BUNDLE_INSTALL: "false"
NEW_FLAKY_SPECS_REPORT: rspec_flaky/report-new.json
stage: post-test
allow_failure: yes
allow_failure: true
retry: 0
only:
- branches
......@@ -441,7 +441,6 @@ ee_compat_check:
- /^[\d-]+-stable(-ee)?/
- branches@gitlab-org/gitlab-ee
- branches@gitlab/gitlab-ee
allow_failure: no
retry: 0
artifacts:
name: "${CI_JOB_NAME}_${CI_COMIT_REF_NAME}_${CI_COMMIT_SHA}"
......
Please read this!
Before opening a new issue, make sure to search for keywords in the issues
filtered by the "feature proposal" label:
For the Community Edition issue tracker:
- https://gitlab.com/gitlab-org/gitlab-ce/issues?label_name%5B%5D=feature+proposal
For the Enterprise Edition issue tracker:
- https://gitlab.com/gitlab-org/gitlab-ee/issues?label_name%5B%5D=feature+proposal
and verify the issue you're about to submit isn't a duplicate.
Please remove this notice if you're confident your issue isn't a duplicate.
------
### Description
(Include problem, use cases, benefits, and/or goals)
......@@ -25,26 +6,4 @@ Please remove this notice if you're confident your issue isn't a duplicate.
### Links / references
### Documentation blurb
#### Overview
What is it?
Why should someone use this feature?
What is the underlying (business) problem?
How do you use this feature?
#### Use cases
Who is this for? Provide one or more use cases.
### Feature checklist
Make sure these are completed before closing the issue,
with a link to the relevant commit.
- [ ] [Feature assurance](https://about.gitlab.com/handbook/product/#feature-assurance)
- [ ] Documentation
- [ ] Added to [features.yml](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/features.yml)
/label ~"feature proposal"
\ No newline at end of file
/label ~"feature proposal"
Remove this section and replace it with a description of your MR. Also follow the
checklist below and check off any tasks that are done. If a certain task can not
be done you should explain so in the MR body. You are free to remove any
sections that do not apply to your MR.
When gathering statistics (e.g. the output of `EXPLAIN ANALYZE`) you should make
sure your database has enough data. Having around 10 000 rows in the tables
being queries should provide a reasonable estimate of how a query will behave.
Also make sure that PostgreSQL uses the following settings:
* `random_page_cost`: `1`
* `work_mem`: `16MB`
* `maintenance_work_mem`: at least `64MB`
* `shared_buffers`: at least `256MB`
If you have access to GitLab.com's staging environment you should also run your
measurements there, and include the results in this MR.
Add a description of your merge request here. Merge requests without an adequate
description will not be reviewed until one is added.
## Database Checklist
......@@ -23,34 +8,23 @@ When adding migrations:
- [ ] Updated `db/schema.rb`
- [ ] Added a `down` method so the migration can be reverted
- [ ] Added the output of the migration(s) to the MR body
- [ ] Added the execution time of the migration(s) to the MR body
- [ ] Added tests for the migration in `spec/migrations` if necessary (e.g. when
migrating data)
- [ ] Made sure the migration won't interfere with a running GitLab cluster,
for example by disabling transactions for long running migrations
- [ ] Added tests for the migration in `spec/migrations` if necessary (e.g. when migrating data)
When adding or modifying queries to improve performance:
- [ ] Included the raw SQL queries of the relevant queries
- [ ] Included the output of `EXPLAIN ANALYZE` and execution timings of the
relevant queries
- [ ] Added tests for the relevant changes
When adding indexes:
- [ ] Described the need for these indexes in the MR body
- [ ] Made sure existing indexes can not be reused instead
- [ ] Included data that shows the performance improvement, preferably in the form of a benchmark
- [ ] Included the output of `EXPLAIN (ANALYZE, BUFFERS)` of the relevant queries
When adding foreign keys to existing tables:
- [ ] Included a migration to remove orphaned rows in the source table
- [ ] Included a migration to remove orphaned rows in the source table before adding the foreign key
- [ ] Removed any instances of `dependent: ...` that may no longer be necessary
When adding tables:
- [ ] Ordered columns based on their type sizes in descending order
- [ ] Added foreign keys if necessary
- [ ] Added indexes if necessary
- [ ] Ordered columns based on the [Ordering Table Columns](https://docs.gitlab.com/ee/development/ordering_table_columns.html#ordering-table-columns) guidelines
- [ ] Added foreign keys to any columns pointing to data in other tables
- [ ] Added indexes for fields that are used in statements such as WHERE, ORDER BY, GROUP BY, and JOINs
When removing columns, tables, indexes or other structures:
......@@ -64,8 +38,6 @@ When removing columns, tables, indexes or other structures:
- [ ] API support added
- [ ] Tests added for this feature/bug
- Review
- [ ] Has been reviewed by UX
- [ ] Has been reviewed by Frontend
- [ ] Has been reviewed by Backend
- [ ] Has been reviewed by Database
- [ ] Conform by the [merge request performance guides](http://docs.gitlab.com/ce/development/merge_request_performance_guidelines.html)
......
......@@ -37,8 +37,9 @@ Please view this file on the master branch, on stable branches it's out of date.
- Reduce the quiet times between scheduler runs on Geo secondaries. !3185
### Added (19 changes, 1 of them is from the community)
### Added (20 changes, 1 of them is from the community)
- Add new push rule to enforce that only the author of a commit can push to the repository. !3086
- Make the maximum capacity of Geo backfill operations configurable. !3107
- Mirrors can now hard fail, keeping them from being retried until a project admin takes action. !3117
- View/edit epic at group level. !3126
......
......@@ -69,6 +69,7 @@ entry.
- Update container repository path reference and allow using double underscore. !15417
- Fix crash when navigating to second page of the group dashbaord when there are projects and groups on the first page. !15456
- Fix flash errors showing up on a non configured prometheus integration. !35652
- Fix timezone bug in Pikaday and upgrade Pikaday version.
- Fix arguments Import/Export error importing project merge requests.
- Moves mini graph of pipeline to the end of sentence in MR widget. Cleans HTML and tests.
- Fix user autocomplete in subgroups.
......@@ -102,7 +103,6 @@ entry.
- Only set Auto-Submitted header once for emails on push.
- Fix overlap of right-sidebar and main content when creating a Wiki page.
- Enables scroll to bottom once user has scrolled back to bottom in job log.
- Fix timezone bug in Pikaday and upgrade Pikaday version.
### Changed (21 changes, 7 of them are from the community)
......@@ -145,9 +145,8 @@ entry.
- Optimise getting the pipeline status of commits.
- Improve performance of commits list by fully using DB index when getting commit note counts.
### Added (27 changes, 10 of them are from the community)
### Added (26 changes, 10 of them are from the community)
- Add new push rule to enforce that only the author of a commit can push to the repository. !3086
- Expose duration in Job entity. !13644 (Mehdi Lahmam (@mehlah))
- Prevent git push when LFS objects are missing. !13837
- Automatic configuration settings page. !13850 (Francisco Lopez)
......
......@@ -544,6 +544,7 @@ When having your code reviewed and when reviewing merge requests please take the
etc.), they should conform to our [Licensing guidelines][license-finder-doc].
See the instructions in that document for help if your MR fails the
"license-finder" test with a "Dependencies that need approval" error.
1. The merge request meets the [definition of done](#definition-of-done).
## Definition of done
......
......@@ -275,6 +275,8 @@ gem 'gettext_i18n_rails', '~> 1.8.0'
gem 'gettext_i18n_rails_js', '~> 1.2.0'
gem 'gettext', '~> 3.2.2', require: false, group: :development
gem 'batch-loader'
# Perf bar
gem 'peek', '~> 1.0.1'
gem 'peek-gc', '~> 0.0.2'
......@@ -414,7 +416,7 @@ group :ed25519 do
end
# Gitaly GRPC client
gem 'gitaly-proto', '~> 0.52.0', require: 'gitaly'
gem 'gitaly-proto', '~> 0.54.0', require: 'gitaly'
gem 'toml-rb', '~> 0.3.15', require: false
......
......@@ -81,6 +81,7 @@ GEM
thread_safe (~> 0.3, >= 0.3.1)
babosa (1.0.2)
base32 (0.3.2)
batch-loader (1.1.1)
bcrypt (3.1.11)
bcrypt_pbkdf (1.0.0)
benchmark-ips (2.3.0)
......@@ -299,7 +300,7 @@ GEM
po_to_json (>= 1.0.0)
rails (>= 3.2.0)
gherkin-ruby (0.3.2)
gitaly-proto (0.52.0)
gitaly-proto (0.54.0)
google-protobuf (~> 3.1)
grpc (~> 1.0)
github-linguist (4.7.6)
......@@ -1013,6 +1014,7 @@ DEPENDENCIES
aws-sdk
babosa (~> 1.0.2)
base32 (~> 0.3.0)
batch-loader
bcrypt_pbkdf (~> 1.0)
benchmark-ips (~> 2.3.0)
better_errors (~> 2.1.0)
......@@ -1069,7 +1071,7 @@ DEPENDENCIES
gettext (~> 3.2.2)
gettext_i18n_rails (~> 1.8.0)
gettext_i18n_rails_js (~> 1.2.0)
gitaly-proto (~> 0.52.0)
gitaly-proto (~> 0.54.0)
github-linguist (~> 4.7.0)
gitlab-flowdock-git-hook (~> 1.0.1)
gitlab-license (~> 1.0)
......
10.2.0-pre
10.3.0-pre
......@@ -345,7 +345,6 @@ import initGroupAnalytics from './init_group_analytics';
break;
case 'projects:merge_requests:show':
new Diff();
shortcut_handler = new ShortcutsIssuable(true);
new ZenMode();
initIssuableSidebar();
......@@ -355,6 +354,8 @@ import initGroupAnalytics from './init_group_analytics';
window.mergeRequest = new MergeRequest({
action: mrShowNode.dataset.mrAction,
});
shortcut_handler = new ShortcutsIssuable(true);
break;
case 'dashboard:activity':
new gl.Activities();
......
......@@ -21,6 +21,7 @@ import tabs from '../../vue_shared/components/navigation_tabs.vue';
import container from '../components/container.vue';
export default {
components: {
environmentTable,
container,
......@@ -57,6 +58,7 @@ export default {
}
});
},
/**
* Handles URL and query parameter changes.
* When the user uses the pagination or the tabs,
......
......@@ -4,9 +4,11 @@ import tooltip from '../../vue_shared/directives/tooltip';
import PopupDialog from '../../vue_shared/components/popup_dialog.vue';
import eventHub from '../event_hub';
import { COMMON_STR } from '../constants';
import Icon from '../../vue_shared/components/icon.vue';
export default {
components: {
Icon,
PopupDialog,
},
directives: {
......@@ -63,9 +65,9 @@ export default {
:aria-label="editBtnTitle"
data-container="body"
class="edit-group btn no-expand">
<i
class="fa fa-cogs"
aria-hidden="true"/>
<icon
name="settings">
</icon>
</a>
<a
v-tooltip
......
......@@ -34,11 +34,6 @@ export default {
required: false,
default: true,
},
canAttachFile: {
type: Boolean,
required: false,
default: true,
},
issuableRef: {
type: String,
required: true,
......@@ -107,6 +102,11 @@ export default {
required: false,
default: 'issue',
},
canAttachFile: {
type: Boolean,
required: false,
default: true,
},
},
data() {
const store = new Store({
......
......@@ -29,7 +29,6 @@ import './commit/image_file';
// lib/utils
import { handleLocationHash } from './lib/utils/common_utils';
import './lib/utils/datetime_utility';
import './lib/utils/pretty_time';
import './lib/utils/url_utility';
// behaviors
......
import Vue from 'vue';
import VueResource from 'vue-resource';
import axios from '../../lib/utils/axios_utils';
import statusCodes from '../../lib/utils/http_status';
import { backOff } from '../../lib/utils/common_utils';
Vue.use(VueResource);
const MAX_REQUESTS = 3;
function backOffRequest(makeRequestCallback) {
......@@ -32,8 +29,8 @@ export default class MonitoringService {
}
getGraphsData() {
return backOffRequest(() => Vue.http.get(this.metricsEndpoint))
.then(resp => resp.json())
return backOffRequest(() => axios.get(this.metricsEndpoint))
.then(resp => resp.data)
.then((response) => {
if (!response || !response.data) {
throw new Error('Unexpected metrics data response from prometheus endpoint');
......@@ -43,8 +40,8 @@ export default class MonitoringService {
}
getDeploymentData() {
return backOffRequest(() => Vue.http.get(this.deploymentEndpoint))
.then(resp => resp.json())
return backOffRequest(() => axios.get(this.deploymentEndpoint))
.then(resp => resp.data)
.then((response) => {
if (!response || !response.deployments) {
throw new Error('Unexpected deployment data response from prometheus endpoint');
......
......@@ -171,6 +171,7 @@
*/
updateContent(parameters) {
this.updateInternalState(parameters);
// fetch new data
return this.service.getPipelines(this.requestData)
.then((response) => {
......@@ -245,9 +246,11 @@
/>
<div
class="blank-state blank-state-no-icon"
class="blank-state-row"
v-if="shouldRenderNoPipelinesMessage">
<h2 class="blank-state-title js-blank-state-title">No pipelines to show.</h2>
<div class="blank-state-center">
<h2 class="blank-state-title js-blank-state-title">No pipelines to show.</h2>
</div>
</div>
<div
......
import renderMath from './render_math';
import renderMermaid from './render_mermaid';
// Render Gitlab flavoured Markdown
//
// Delegates to syntax highlight and render math
// Delegates to syntax highlight and render math & mermaid diagrams.
//
$.fn.renderGFM = function renderGFM() {
this.find('.js-syntax-highlight').syntaxHighlight();
renderMath(this.find('.js-render-math'));
renderMermaid(this.find('.js-render-mermaid'));
return this;
};
......
// Renders diagrams and flowcharts from text using Mermaid in any element with the
// `js-render-mermaid` class.
//
// Example markup:
//
// <pre class="js-render-mermaid">
// graph TD;
// A-- > B;
// A-- > C;
// B-- > D;
// C-- > D;
// </pre>
//
import Flash from './flash';
export default function renderMermaid($els) {
if (!$els.length) return;
import(/* webpackChunkName: 'mermaid' */ 'blackst0ne-mermaid').then((mermaid) => {
mermaid.initialize({
loadOnStart: false,
theme: 'neutral',
});
$els.each((i, el) => {
mermaid.init(undefined, el);
});
}).catch((err) => {
Flash(`Can't load mermaid module: ${err}`);
});
}
import Flash from './flash';
import { __, s__ } from './locale';
import { spriteIcon } from './lib/utils/common_utils';
export default class Star {
constructor() {
......@@ -7,16 +8,18 @@ export default class Star {
.on('ajax:success', function handleSuccess(e, data) {
const $this = $(this);
const $starSpan = $this.find('span');
const $starIcon = $this.find('i');
const $startIcon = $this.find('svg');
function toggleStar(isStarred) {
$this.parent().find('.star-count').text(data.star_count);
if (isStarred) {
$starSpan.removeClass('starred').text(s__('StarProject|Star'));
$starIcon.removeClass('fa-star').addClass('fa-star-o');
$startIcon.remove();
$this.prepend(spriteIcon('star-o'));
} else {
$starSpan.addClass('starred').text(__('Unstar'));
$starIcon.removeClass('fa-star-o').addClass('fa-star');
$startIcon.remove();
$this.prepend(spriteIcon('star'));
}
}
......
......@@ -14,7 +14,7 @@ export default {
statusObj() {
return {
group: this.status,
icon: `icon_status_${this.status}`,
icon: `status_${this.status}`,
};
},
},
......
......@@ -50,7 +50,9 @@
<template>
<div class="md-header">
<ul class="nav-links clearfix">
<li :class="{ active: !previewMarkdown }">
<li
class="md-header-tab"
:class="{ active: !previewMarkdown }">
<a
class="js-write-link"
href="#md-write-holder"
......@@ -59,7 +61,9 @@
Write
</a>
</li>
<li :class="{ active: previewMarkdown }">
<li
class="md-header-tab"
:class="{ active: previewMarkdown }">
<a
class="js-preview-link"
href="#md-preview-holder"
......@@ -68,56 +72,52 @@
Preview
</a>
</li>
<li class="pull-right">
<div class="toolbar-group">
<toolbar-button
tag="**"
button-title="Add bold text"
icon="bold" />
<toolbar-button
tag="*"
button-title="Add italic text"
icon="italic" />
<toolbar-button
tag="> "
:prepend="true"
button-title="Insert a quote"
icon="quote" />
<toolbar-button
tag="`"
tag-block="```"
button-title="Insert code"
icon="code" />
<toolbar-button
tag="* "
:prepend="true"
button-title="Add a bullet list"
icon="list-bulleted" />
<toolbar-button
tag="1. "
:prepend="true"
button-title="Add a numbered list"
icon="list-numbered" />
<toolbar-button
tag="* [ ] "
:prepend="true"
button-title="Add a task list"
icon="task-done" />
</div>
<div class="toolbar-group">
<button
v-tooltip
aria-label="Go full screen"
class="toolbar-btn js-zen-enter"
data-container="body"
tabindex="-1"
title="Go full screen"
type="button">
<icon
name="screen-full">
</icon>
</button>
</div>
<li class="md-header-toolbar">
<toolbar-button
tag="**"
button-title="Add bold text"
icon="bold" />
<toolbar-button
tag="*"
button-title="Add italic text"
icon="italic" />
<toolbar-button
tag="> "
:prepend="true"
button-title="Insert a quote"
icon="quote" />
<toolbar-button
tag="`"
tag-block="```"
button-title="Insert code"
icon="code" />
<toolbar-button
tag="* "
:prepend="true"
button-title="Add a bullet list"
icon="list-bulleted" />
<toolbar-button
tag="1. "
:prepend="true"
button-title="Add a numbered list"
icon="list-numbered" />
<toolbar-button
tag="* [ ] "
:prepend="true"
button-title="Add a task list"
icon="task-done" />
<button
v-tooltip
aria-label="Go full screen"
class="toolbar-btn toolbar-fullscreen-btn js-zen-enter"
data-container="body"
tabindex="-1"
title="Go full screen"
type="button">
<icon
name="screen-full">
</icon>
</button>
</li>
</ul>
</div>
......
......@@ -40,7 +40,7 @@
<button
v-tooltip
type="button"
class="toolbar-btn js-md hidden-xs"
class="toolbar-btn js-md"
tabindex="-1"
data-container="body"
:data-md-tag="tag"
......
......@@ -56,6 +56,12 @@
}
}
.blank-state-center {
padding-top: 20px;
padding-bottom: 20px;
text-align: center;
}
.blank-state {
padding: 20px;
border: 1px solid $border-color;
......@@ -67,7 +73,10 @@
align-items: center;
padding: 50px 30px;
}
}
.blank-state,
.blank-state-center {
.blank-state-icon {
svg {
display: block;
......
......@@ -438,6 +438,7 @@ img.emoji {
/** COMMON CLASSES **/
.prepend-top-0 { margin-top: 0; }
.prepend-top-5 { margin-top: 5px; }
.prepend-top-8 { margin-top: $grid-size; }
.prepend-top-10 { margin-top: 10px; }
.prepend-top-15 { margin-top: 15px; }
.prepend-top-default { margin-top: $gl-padding !important; }
......
......@@ -40,12 +40,6 @@
a:hover {
background-color: $link-hover-background;
color: $gl-text-color;
.settings-avatar {
svg {
fill: $gl-text-color;
}
}
}
.avatar-container {
......@@ -138,10 +132,6 @@
color: $gl-text-color-secondary;
}
svg {
fill: $gl-text-color-secondary;
}
.nav-item-name {
flex: 1;
}
......@@ -224,10 +214,6 @@
&:hover {
color: $gl-text-color;
svg {
fill: $gl-text-color;
}
}
}
......@@ -338,7 +324,6 @@
align-items: center;
svg {
fill: $gl-text-color-secondary;
margin-right: 8px;
}
......@@ -349,10 +334,6 @@
&:hover {
background-color: $border-color;
color: $gl-text-color;
svg {
fill: $gl-text-color;
}
}
}
......
......@@ -364,6 +364,18 @@ span.idiff {
float: none;
}
}
@media (max-width: $screen-xs-max) {
display: block;
.file-actions {
white-space: normal;
.btn-group {
padding-top: 5px;
}
}
}
}
.is-stl-loading {
......
......@@ -305,16 +305,11 @@
color: $gl-text-color;
border-color: $dropdown-input-focus-border;
outline: none;
svg {
fill: $gl-text-color;
}
}
svg {
height: 14px;
width: 14px;
fill: $gl-text-color-secondary;
vertical-align: middle;
}
......
......@@ -30,10 +30,6 @@
&.dropdown.open > a {
color: $color-900;
background-color: $color-alternate;
svg {
fill: currentColor;
}
}
&.line-separator {
......@@ -51,10 +47,6 @@
color: $color-200;
> a {
svg {
fill: $color-200;
}
&.header-user-dropdown-toggle {
.header-user-avatar {
border-color: $color-200;
......
......@@ -235,10 +235,6 @@
opacity: 1;
color: $white-light;
svg {
fill: currentColor;
}
&.header-user-dropdown-toggle .header-user-avatar {
border-color: $white-light;
}
......@@ -269,14 +265,6 @@
font-size: 20px;
}
}
&.active > a,
&.dropdown.open > a {
svg {
fill: currentColor;
}
}
}
}
}
......@@ -289,10 +277,6 @@
text-decoration: none;
outline: 0;
color: $white-light;
svg {
fill: currentColor;
}
}
> a {
......@@ -307,10 +291,6 @@
border-radius: $border-radius-default;
height: 32px;
font-weight: $gl-font-weight-bold;
svg {
fill: currentColor;
}
}
&.line-separator {
......
.ci-status-icon-success,
.ci-status-icon-passed {
color: $green-500;
svg {
fill: $green-500;
}
}
.ci-status-icon-failed {
color: $gl-danger;
svg {
fill: $gl-danger;
}
}
.ci-status-icon-pending,
.ci-status-icon-failed_with_warnings,
.ci-status-icon-success_with_warnings {
color: $orange-500;
svg {
fill: $orange-500;
}
}
.ci-status-icon-running {
color: $blue-400;
svg {
fill: $blue-400;
}
}
.ci-status-icon-canceled,
.ci-status-icon-disabled,
.ci-status-icon-not-found {
color: $gl-text-color;
svg {
fill: $gl-text-color;
}
}
.ci-status-icon-created,
.ci-status-icon-skipped {
color: $gray-darkest;
svg {
fill: $gray-darkest;
}
}
.ci-status-icon-manual {
color: $gl-text-color;
svg {
fill: $gl-text-color;
}
}
.icon-link {
......
......@@ -27,6 +27,8 @@
}
svg {
fill: currentColor;
&.s8 { @include svg-size(8px); }
&.s12 { @include svg-size(12px); }
&.s16 { @include svg-size(16px); }
......
......@@ -57,6 +57,7 @@
.md-header {
.nav-links {
a {
width: 100%;
padding-top: 0;
line-height: 19px;
......@@ -72,6 +73,28 @@
}
}
.md-header-tab {
@media(max-width: $screen-xs-max) {
flex: 1;
width: 100%;
border-bottom: 1px solid $border-color;
text-align: center;
}
}
.md-header-toolbar {
margin-left: auto;
@media(max-width: $screen-xs-max) {
flex: none;
display: flex;
justify-content: center;
width: 100%;
padding-top: $gl-padding-top;
padding-bottom: $gl-padding-top;
}
}
.referenced-users {
color: $gl-text-color;
padding-top: 10px;
......@@ -126,16 +149,6 @@
}
}
.toolbar-group {
float: left;
margin-right: -5px;
margin-left: $gl-padding;
&:first-child {
margin-left: 0;
}
}
.toolbar-btn {
float: left;
padding: 0 7px;
......@@ -158,6 +171,16 @@
}
}
.toolbar-fullscreen-btn {
margin-left: $gl-padding;
margin-right: -5px;
@media(max-width: $screen-xs-max) {
margin-left: 0;
margin-right: 0;
}
}
.atwho-view {
overflow-y: auto;
overflow-x: hidden;
......
......@@ -130,14 +130,6 @@
background-color: $color-light;
color: $color-dark;
border-color: $color-dark;
svg {
fill: $color-dark;
}
}
svg {
fill: $color-main;
}
}
......
......@@ -57,15 +57,7 @@
padding: 5px;
font-size: 36px;
svg {
fill: $gl-text-color;
}
&:hover {
color: $black;
svg {
fill: $black;
}
}
}
.documentation-index {
h1 {
margin: 0;
}
h2 {
font-size: 20px;
}
li {
line-height: 24px;
color: $document-index-color;
a {
margin-right: 3px;
}
}
}
.shortcut-mappings {
font-size: 12px;
color: $help-shortcut-mapping-color;
......
......@@ -547,10 +547,6 @@ ul.notes {
width: 16px;
top: 0;
vertical-align: text-top;
path {
fill: currentColor;
}
}
.award-control-icon-positive,
......@@ -570,10 +566,6 @@ ul.notes {
.link-highlight {
color: $gl-link-color;
fill: $gl-link-color;
svg {
fill: $gl-link-color;
}
}
.award-control-icon-neutral {
......
......@@ -55,10 +55,6 @@
&:not(span):hover {
background-color: rgba($gl-text-color-secondary, .07);
}
svg {
fill: $gl-text-color-secondary;
}
}
}
......
......@@ -204,8 +204,7 @@ class ApplicationController < ActionController::Base
end
def check_password_expiration
return if session[:impersonator_id]
return unless current_user&.allow_password_authentication?
return if session[:impersonator_id] || !current_user&.allow_password_authentication?
password_expires_at = current_user&.password_expires_at
......
......@@ -152,7 +152,7 @@ module IssuableCollections
when 'MergeRequest'
[
:source_project, :target_project, :author, :assignee, :labels, :milestone,
head_pipeline: :project, target_project: :namespace, merge_request_diff: :merge_request_diff_commits
head_pipeline: :project, target_project: :namespace, latest_merge_request_diff: :merge_request_diff_commits
]
end
end
......
......@@ -8,6 +8,7 @@ module PreviewMarkdown
case controller_name
when 'wikis' then { pipeline: :wiki, project_wiki: @project_wiki, page_slug: params[:id] }
when 'snippets' then { skip_project_check: true }
when 'groups' then { group: group }
else {}
end
......
......@@ -86,7 +86,8 @@ class Groups::MilestonesController < Groups::ApplicationController
GroupMilestone.build_collection(group, group_projects, params)
end
milestones + legacy_milestones
@sort = params[:sort] || 'due_date_asc'
MilestoneArray.sort(milestones + legacy_milestones, @sort)
end
def milestone
......
......@@ -22,12 +22,7 @@ class Projects::CommitController < Projects::ApplicationController
apply_diff_view_cookie!
respond_to do |format|
format.html do
# n+1: https://gitlab.com/gitlab-org/gitlab-ce/issues/37599
Gitlab::GitalyClient.allow_n_plus_1_calls do
render
end
end
format.html { render }
format.diff { render text: @commit.to_diff }
format.patch { render text: @commit.to_patch }
end
......@@ -112,7 +107,7 @@ class Projects::CommitController < Projects::ApplicationController
end
def commit
@noteable = @commit ||= @project.commit(params[:id])
@noteable = @commit ||= @project.commit_by(oid: params[:id])
end
def define_commit_vars
......
......@@ -10,10 +10,7 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic
def show
@environment = @merge_request.environments_for(current_user).last
# n+1: https://gitlab.com/gitlab-org/gitlab-ce/issues/37431
Gitlab::GitalyClient.allow_n_plus_1_calls do
render json: { html: view_to_html_string("projects/merge_requests/diffs/_diffs") }
end
render json: { html: view_to_html_string("projects/merge_requests/diffs/_diffs") }
end
def diff_for_path
......
# :nocov:
if Rails.env.test?
class UnicornTestController < ActionController::Base
def pid
render plain: Process.pid.to_s
end
def kill
Process.kill(params[:signal], Process.pid)
render plain: 'Bye!'
end
end
end
# :nocov:
......@@ -222,7 +222,7 @@ module MarkupHelper
data = options[:data].merge({ container: 'body' })
content_tag :button,
type: 'button',
class: 'toolbar-btn js-md has-tooltip hidden-xs',
class: 'toolbar-btn js-md has-tooltip',
tabindex: -1,
data: data,
title: options[:title],
......
......@@ -150,7 +150,8 @@ module SearchHelper
placeholder: 'Search or filter results...',
data: {
'username-params' => @users.to_json(only: [:id, :username])
}
},
autocomplete: 'off'
}
if @project.present?
......
......@@ -76,12 +76,24 @@ class Blob < SimpleDelegator
new(blob, project)
end
def self.lazy(project, commit_id, path)
BatchLoader.for(commit_id: commit_id, path: path).batch do |items, loader|
project.repository.blobs_at(items.map(&:values)).each do |blob|
loader.call({ commit_id: blob.commit_id, path: blob.path }, blob) if blob
end
end
end
def initialize(blob, project = nil)
@project = project
super(blob)
end
def inspect
"#<#{self.class.name} oid:#{id[0..8]} commit:#{commit_id[0..8]} path:#{path}>"
end
# Returns the data of the blob.
#
# If the blob is a text based blob the content is converted to UTF-8 and any
......@@ -95,7 +107,10 @@ class Blob < SimpleDelegator
end
def load_all_data!
super(project.repository) if project
# Endpoint needed: gitlab-org/gitaly#756
Gitlab::GitalyClient.allow_n_plus_1_calls do
super(project.repository) if project
end
end
def no_highlighting?
......
......@@ -247,7 +247,7 @@ module Ci
@merge_request ||=
begin
merge_requests = MergeRequest.includes(:merge_request_diff)
merge_requests = MergeRequest.includes(:latest_merge_request_diff)
.where(source_branch: ref,
source_project: pipeline.project)
.reorder(iid: :desc)
......
......@@ -520,7 +520,10 @@ module Ci
end
def latest_builds_with_artifacts
@latest_builds_with_artifacts ||= builds.latest.with_artifacts
# We purposely cast the builds to an Array here. Because we always use the
# rows if there are more than 0 this prevents us from having to run two
# queries: one to get the count and one to get the rows.
@latest_builds_with_artifacts ||= builds.latest.with_artifacts.to_a
end
private
......
......@@ -84,7 +84,7 @@ class Commit
end
def id
@raw.id
raw.id
end
def ==(other)
......@@ -109,12 +109,12 @@ class Commit
@link_reference_pattern ||= super("commit", /(?<commit>#{COMMIT_SHA_PATTERN})/)
end
def to_reference(from_project = nil, full: false)
commit_reference(from_project, id, full: full)
def to_reference(from = nil, full: false)
commit_reference(from, id, full: full)
end
def reference_link_text(from_project = nil, full: false)
commit_reference(from_project, short_id, full: full)
def reference_link_text(from = nil, full: false)
commit_reference(from, short_id, full: full)
end
def diff_line_count
......@@ -361,7 +361,7 @@ class Commit
@deltas ||= raw.deltas
end
def diffs(diff_options = nil)
def diffs(diff_options = {})
Gitlab::Diff::FileCollection::Commit.new(self, diff_options: diff_options)
end
......@@ -381,8 +381,8 @@ class Commit
private
def commit_reference(from_project, referable_commit_id, full: false)
reference = project.to_reference(from_project, full: full)
def commit_reference(from, referable_commit_id, full: false)
reference = project.to_reference(from, full: full)
if reference.present?
"#{reference}#{self.class.reference_prefix}#{referable_commit_id}"
......
......@@ -89,8 +89,8 @@ class CommitRange
alias_method :id, :to_s
def to_reference(from_project = nil, full: false)
project_reference = project.to_reference(from_project, full: full)
def to_reference(from = nil, full: false)
project_reference = project.to_reference(from, full: full)
if project_reference.present?
project_reference + self.class.reference_prefix + self.id
......@@ -99,8 +99,8 @@ class CommitRange
end
end
def reference_link_text(from_project = nil)
project_reference = project.to_reference(from_project)
def reference_link_text(from = nil)
project_reference = project.to_reference(from)
reference = ref_from + notation + ref_to
if project_reference.present?
......
module ManualInverseAssociation
extend ActiveSupport::Concern
module ClassMethods
def manual_inverse_association(association, inverse)
define_method(association) do |*args|
super(*args).tap do |value|
next unless value
child_association = value.association(inverse)
child_association.set_inverse_instance(self)
child_association.target = self
end
end
end
end
end
......@@ -31,11 +31,11 @@ module Mentionable
#
# By default this will be the class name and the result of calling
# `to_reference` on the object.
def gfm_reference(from_project = nil)
def gfm_reference(from = nil)
# "MergeRequest" > "merge_request" > "Merge request" > "merge request"
friendly_name = self.class.to_s.underscore.humanize.downcase
"#{friendly_name} #{to_reference(from_project)}"
"#{friendly_name} #{to_reference(from)}"
end
# The GFM reference to this Mentionable, which shouldn't be included in its #references.
......
......@@ -7,7 +7,7 @@ module Referable
# Returns the String necessary to reference this object in Markdown
#
# from_project - Refering Project object
# from - Referring parent object
#
# This should be overridden by the including class.
#
......@@ -17,12 +17,12 @@ module Referable
# Issue.last.to_reference(other_project) # => "cross-project#1"
#
# Returns a String
def to_reference(_from_project = nil, full:)
def to_reference(_from = nil, full:)
''
end
def reference_link_text(from_project = nil)
to_reference(from_project)
def reference_link_text(from = nil)
to_reference(from)
end
included do
......
......@@ -38,11 +38,11 @@ class ExternalIssue
@project.id
end
def to_reference(_from_project = nil, full: nil)
def to_reference(_from = nil, full: nil)
id
end
def reference_link_text(from_project = nil)
def reference_link_text(from = nil)
return "##{id}" if id =~ /^\d+$/
id
......
......@@ -115,7 +115,7 @@ class Group < Namespace
end
end
def to_reference(_from_project = nil, full: nil)
def to_reference(_from = nil, full: nil)
"#{self.class.reference_prefix}#{full_path}"
end
......
......@@ -168,12 +168,12 @@ class Label < ActiveRecord::Base
#
# Returns a String
#
def to_reference(from_project = nil, target_project: nil, format: :id, full: false)
def to_reference(from = nil, target_project: nil, format: :id, full: false)
format_reference = label_format_reference(format)
reference = "#{self.class.reference_prefix}#{format_reference}"
if from_project
"#{from_project.to_reference(target_project, full: full)}#{reference}"
if from
"#{from.to_reference(target_project, full: full)}#{reference}"
else
reference
end
......
......@@ -6,6 +6,8 @@ class MergeRequest < ActiveRecord::Base
include Elastic::MergeRequestsSearch
include IgnorableColumn
include TimeTrackable
include ManualInverseAssociation
include EachBatch
ignore_column :locked_at,
:ref_fetched
......@@ -18,9 +20,28 @@ class MergeRequest < ActiveRecord::Base
belongs_to :merge_user, class_name: "User"
has_many :merge_request_diffs
has_one :merge_request_diff,
-> { order('merge_request_diffs.id DESC') }, inverse_of: :merge_request
belongs_to :latest_merge_request_diff, class_name: 'MergeRequestDiff'
manual_inverse_association :latest_merge_request_diff, :merge_request
# This is the same as latest_merge_request_diff unless:
# 1. There are arguments - in which case we might be trying to force-reload.
# 2. This association is already loaded.
# 3. The latest diff does not exist.
#
# The second one in particular is important - MergeRequestDiff#merge_request
# is the inverse of MergeRequest#merge_request_diff, which means it may not be
# the latest diff, because we could have loaded any diff from this particular
# MR. If we haven't already loaded a diff, then it's fine to load the latest.
def merge_request_diff(*args)
fallback = latest_merge_request_diff if args.empty? && !association(:merge_request_diff).loaded?
fallback || super
end
belongs_to :head_pipeline, foreign_key: "head_pipeline_id", class_name: "Ci::Pipeline"
has_many :events, as: :target, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
......@@ -172,6 +193,22 @@ class MergeRequest < ActiveRecord::Base
where("merge_requests.id IN (#{union.to_sql})") # rubocop:disable GitlabSecurity/SqlInjection
end
# This is used after project import, to reset the IDs to the correct
# values. It is not intended to be called without having already scoped the
# relation.
def self.set_latest_merge_request_diff_ids!
update = '
latest_merge_request_diff_id = (
SELECT MAX(id)
FROM merge_request_diffs
WHERE merge_requests.id = merge_request_diffs.merge_request_id
)'.squish
self.each_batch do |batch|
batch.update_all(update)
end
end
WIP_REGEX = /\A\s*(\[WIP\]\s*|WIP:\s*|WIP\s+)+\s*/i.freeze
def self.work_in_progress?(title)
......
......@@ -2,6 +2,7 @@ class MergeRequestDiff < ActiveRecord::Base
include Sortable
include Importable
include Gitlab::EncodingHelper
include ManualInverseAssociation
# Prevent store of diff if commits amount more then 500
COMMITS_SAFE_SIZE = 100
......@@ -10,6 +11,8 @@ class MergeRequestDiff < ActiveRecord::Base
VALID_CLASSES = [Hash, Rugged::Patch, Rugged::Diff::Delta].freeze
belongs_to :merge_request
manual_inverse_association :merge_request, :merge_request_diff
has_many :merge_request_diff_files, -> { order(:merge_request_diff_id, :relative_order) }
has_many :merge_request_diff_commits, -> { order(:merge_request_diff_id, :relative_order) }
......@@ -194,7 +197,7 @@ class MergeRequestDiff < ActiveRecord::Base
end
def latest?
self == merge_request.merge_request_diff
self.id == merge_request.latest_merge_request_diff_id
end
def compare_with(sha)
......
......@@ -166,18 +166,18 @@ class Milestone < ActiveRecord::Base
# Milestone.first.to_reference(cross_namespace_project) # => "gitlab-org/gitlab-ce%1"
# Milestone.first.to_reference(same_namespace_project) # => "gitlab-ce%1"
#
def to_reference(from_project = nil, format: :name, full: false)
def to_reference(from = nil, format: :name, full: false)
format_reference = milestone_format_reference(format)
reference = "#{self.class.reference_prefix}#{format_reference}"
if project
"#{project.to_reference(from_project, full: full)}#{reference}"
"#{project.to_reference(from, full: full)}#{reference}"
else
reference
end
end
def reference_link_text(from_project = nil)
def reference_link_text(from = nil)
self.title
end
......
......@@ -769,10 +769,10 @@ class Project < ActiveRecord::Base
end
end
def to_human_reference(from_project = nil)
if cross_namespace_reference?(from_project)
def to_human_reference(from = nil)
if cross_namespace_reference?(from)
name_with_namespace
elsif cross_project_reference?(from_project)
elsif cross_project_reference?(from)
name
end
end
......
......@@ -224,11 +224,7 @@ class Repository
def branch_exists?(branch_name)
return false unless raw_repository
@branch_exists_memo ||= Hash.new do |hash, key|
hash[key] = raw_repository.branch_exists?(key)
end
@branch_exists_memo[branch_name]
branch_names.include?(branch_name)
end
def ref_exists?(ref)
......@@ -485,6 +481,11 @@ class Repository
nil
end
# items is an Array like: [[oid, path], [oid1, path1]]
def blobs_at(items)
raw_repository.batch_blobs(items).map { |blob| Blob.decorate(blob, project) }
end
def root_ref
if raw_repository
raw_repository.root_ref
......
......@@ -76,11 +76,11 @@ class Snippet < ActiveRecord::Base
@link_reference_pattern ||= super("snippets", /(?<snippet>\d+)/)
end
def to_reference(from_project = nil, full: false)
def to_reference(from = nil, full: false)
reference = "#{self.class.reference_prefix}#{id}"
if project.present?
"#{project.to_reference(from_project, full: full)}#{reference}"
"#{project.to_reference(from, full: full)}#{reference}"
else
reference
end
......
......@@ -456,7 +456,7 @@ class User < ActiveRecord::Base
username
end
def to_reference(_from_project = nil, target_project: nil, full: nil)
def to_reference(_from = nil, target_project: nil, full: nil)
"#{self.class.reference_prefix}#{username}"
end
......@@ -464,6 +464,10 @@ class User < ActiveRecord::Base
skip_confirmation! if bool
end
def skip_reconfirmation=(bool)
skip_reconfirmation! if bool
end
def generate_reset_token
@reset_token, enc = Devise.token_generator.generate(self.class, :reset_password_token)
......
......@@ -12,6 +12,8 @@ module MergeRequests
attr_reader :merge_request, :source
delegate :merge_jid, :state, to: :@merge_request
def execute(merge_request)
if project.merge_requests_ff_only_enabled && !self.is_a?(FfMergeService)
FfMergeService.new(project, current_user, params).execute(merge_request)
......@@ -29,6 +31,7 @@ module MergeRequests
success
end
end
log_info("Merge process finished on JID #{merge_jid} with state #{state}")
rescue MergeError => e
handle_merge_error(log_message: e.message, save_message_on_model: true)
end
......@@ -73,7 +76,9 @@ module MergeRequests
def commit
message = params[:commit_message] || merge_request.merge_commit_message
log_info("Git merge started on JID #{merge_jid}")
commit_id = repository.merge(current_user, source, merge_request, message)
log_info("Git merge finished on JID #{merge_jid} commit #{commit_id}")
raise MergeError, 'Conflicts detected during merge' unless commit_id
......@@ -87,7 +92,9 @@ module MergeRequests
end
def after_merge
log_info("Post merge started on JID #{merge_jid} with state #{state}")
MergeRequests::PostMergeService.new(project, current_user).execute(merge_request)
log_info("Post merge finished on JID #{merge_jid} with state #{state}")
if delete_source_branch?
DeleteBranchService.new(@merge_request.source_project, branch_deletion_user)
......@@ -116,6 +123,11 @@ module MergeRequests
@merge_request.update(merge_error: log_message) if save_message_on_model
end
def log_info(message)
@logger ||= Rails.logger
@logger.info("#{merge_request_info} - #{message}")
end
def merge_request_info
merge_request.to_reference(full: true)
end
......
......@@ -36,7 +36,7 @@ module MergeRequests
# target branch manually
def close_merge_requests
commit_ids = @commits.map(&:id)
merge_requests = @project.merge_requests.preload(:merge_request_diff).opened.where(target_branch: @branch_name).to_a
merge_requests = @project.merge_requests.preload(:latest_merge_request_diff).opened.where(target_branch: @branch_name).to_a
merge_requests = merge_requests.select(&:diff_head_commit)
merge_requests = merge_requests.select do |merge_request|
......
......@@ -8,14 +8,14 @@ module Milestones
check_project_milestone!(milestone)
Milestone.transaction do
# Destroy all milestones with same title across projects
destroy_old_milestones(milestone)
group_milestone = clone_project_milestone(milestone)
move_children_to_group_milestone(group_milestone)
# Just to be safe
# Destroy all milestones with same title across projects
destroy_old_milestones(milestone)
# Rollback if milestone is not valid
unless group_milestone.valid?
raise_error(group_milestone.errors.full_messages.to_sentence)
end
......@@ -37,7 +37,7 @@ module Milestones
end
def move_children_to_group_milestone(group_milestone)
milestone_ids_for_merge(group_milestone).in_groups_of(100) do |milestone_ids|
milestone_ids_for_merge(group_milestone).in_groups_of(100, false) do |milestone_ids|
update_children(group_milestone, milestone_ids)
end
end
......@@ -51,7 +51,12 @@ module Milestones
create_service = CreateService.new(group, current_user, params)
create_service.execute
milestone = create_service.execute
# milestone won't be valid here because of duplicated title
milestone.save(validate: false)
milestone
end
def update_children(group_milestone, milestone_ids)
......@@ -67,12 +72,12 @@ module Milestones
@group ||= parent.group || raise_error('Project does not belong to a group.')
end
def destroy_old_milestones(group_milestone)
Milestone.where(id: milestone_ids_for_merge(group_milestone)).destroy_all
def destroy_old_milestones(milestone)
Milestone.where(id: milestone_ids_for_merge(milestone)).destroy_all
end
def group_project_ids
@group_project_ids ||= group.projects.map(&:id)
@group_project_ids ||= group.projects.pluck(:id)
end
def raise_error(message)
......
# The protected branches API still uses the `developers_can_push` and `developers_can_merge`
# The branches#protect API still uses the `developers_can_push` and `developers_can_merge`
# flags for backward compatibility, and so performs translation between that format and the
# internal data model (separate access levels). The translation code is non-trivial, and so
# lives in this service.
module ProtectedBranches
class ApiCreateService < BaseService
class LegacyApiCreateService < BaseService
def execute
push_access_level =
if params.delete(:developers_can_push)
......
# The protected branches API still uses the `developers_can_push` and `developers_can_merge`
# The branches#protect API still uses the `developers_can_push` and `developers_can_merge`
# flags for backward compatibility, and so performs translation between that format and the
# internal data model (separate access levels). The translation code is non-trivial, and so
# lives in this service.
module ProtectedBranches
class ApiUpdateService < BaseService
class LegacyApiUpdateService < BaseService
def execute(protected_branch)
@developers_can_push = params.delete(:developers_can_push)
@developers_can_merge = params.delete(:developers_can_merge)
......
......@@ -26,11 +26,15 @@ class FileUploader < GitlabUploader
# This is used to build Upload paths dynamically based on the model's current
# namespace and path, allowing us to ignore renames or transfers.
#
# model - Object that responds to `path_with_namespace`
# model - Object that responds to `full_path` and `disk_path`
#
# Returns a String without a trailing slash
def self.dynamic_path_segment(model)
File.join(CarrierWave.root, base_dir, model.disk_path)
def self.dynamic_path_segment(project)
if project.hashed_storage?(:attachments)
File.join(CarrierWave.root, base_dir, project.disk_path)
else
File.join(CarrierWave.root, base_dir, project.full_path)
end
end
attr_accessor :model
......
......@@ -4,6 +4,7 @@
= render 'shared/milestones_filter', counts: @milestone_states
.nav-controls
= render 'shared/milestones_sort_dropdown'
- if can?(current_user, :admin_milestones, @group)
= link_to "New milestone", new_group_milestone_path(@group), class: "btn btn-new"
......
- breadcrumb_title "Milestones"
- page_title "Milestones"
- header_title group_title(@group, "Milestones", group_milestones_path(@group))
%h3.page-title
New Milestone
......
......@@ -30,7 +30,7 @@
.row.prepend-top-default
.col-md-8
.documentation-index
.documentation-index.wiki
= markdown(@help_index)
.col-md-4
.panel.panel-default
......
......@@ -10,6 +10,10 @@
body, table, td, a { -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; }
table, td { mso-table-lspace: 0pt; mso-table-rspace: 0pt; }
img { -ms-interpolation-mode: bicubic; }
.hidden {
display: none !important;
visibility: hidden !important;
}
/* iOS BLUE LINKS */
a[x-apple-data-detectors] {
......
......@@ -10,25 +10,23 @@
.md-area
.md-header
%ul.nav-links.clearfix
%li.active
%li.md-header-tab.active
%a.js-md-write-button{ href: "#md-write-holder", tabindex: -1 }
Write
%li
%li.md-header-tab
%a.js-md-preview-button{ href: "#md-preview-holder", tabindex: -1 }
Preview
%li.pull-right
.toolbar-group
= markdown_toolbar_button({ icon: "bold", data: { "md-tag" => "**" }, title: "Add bold text" })
= markdown_toolbar_button({ icon: "italic", data: { "md-tag" => "*" }, title: "Add italic text" })
= markdown_toolbar_button({ icon: "quote", data: { "md-tag" => "> ", "md-prepend" => true }, title: "Insert a quote" })
= markdown_toolbar_button({ icon: "code", data: { "md-tag" => "`", "md-block" => "```" }, title: "Insert code" })
= markdown_toolbar_button({ icon: "list-bulleted", data: { "md-tag" => "* ", "md-prepend" => true }, title: "Add a bullet list" })
= markdown_toolbar_button({ icon: "list-numbered", data: { "md-tag" => "1. ", "md-prepend" => true }, title: "Add a numbered list" })
= markdown_toolbar_button({ icon: "task-done", data: { "md-tag" => "* [ ] ", "md-prepend" => true }, title: "Add a task list" })
.toolbar-group
%button.toolbar-btn.js-zen-enter.has-tooltip{ type: "button", tabindex: -1, aria: { label: "Go full screen" }, title: "Go full screen", data: { container: "body" } }
= sprite_icon("screen-full")
%li.md-header-toolbar
= markdown_toolbar_button({ icon: "bold", data: { "md-tag" => "**" }, title: "Add bold text" })
= markdown_toolbar_button({ icon: "italic", data: { "md-tag" => "*" }, title: "Add italic text" })
= markdown_toolbar_button({ icon: "quote", data: { "md-tag" => "> ", "md-prepend" => true }, title: "Insert a quote" })
= markdown_toolbar_button({ icon: "code", data: { "md-tag" => "`", "md-block" => "```" }, title: "Insert code" })
= markdown_toolbar_button({ icon: "list-bulleted", data: { "md-tag" => "* ", "md-prepend" => true }, title: "Add a bullet list" })
= markdown_toolbar_button({ icon: "list-numbered", data: { "md-tag" => "1. ", "md-prepend" => true }, title: "Add a numbered list" })
= markdown_toolbar_button({ icon: "task-done", data: { "md-tag" => "* [ ] ", "md-prepend" => true }, title: "Add a task list" })
%button.toolbar-btn.toolbar-fullscreen-btn.js-zen-enter.has-tooltip{ type: "button", tabindex: -1, aria: { label: "Go full screen" }, title: "Go full screen", data: { container: "body" } }
= sprite_icon("screen-full")
.md-write-holder
= yield
......
......@@ -2,7 +2,7 @@
.js-file-title.file-title-flex-parent
= render 'projects/blob/header_content', blob: blob
.file-actions.hidden-xs
.file-actions
= render 'projects/blob/viewer_switcher', blob: blob unless blame
.btn-group{ role: "group" }<
......
- if current_user
= link_to toggle_star_project_path(@project), { class: 'btn star-btn toggle-star', method: :post, remote: true } do
- if current_user.starred?(@project)
= icon('star')
= sprite_icon('star')
%span.starred= _('Unstar')
- else
= icon('star-o')
= sprite_icon('star-o')
%span= s_('StarProject|Star')
.count-with-arrow
%span.arrow
......@@ -13,7 +13,7 @@
- else
= link_to new_user_session_path, class: 'btn has-tooltip star-btn', title: _('You must sign in to star a project') do
= icon('star')
= sprite_icon('star')
#{ s_('StarProject|Star') }
.count-with-arrow
%span.arrow
......
......@@ -19,14 +19,15 @@
.environments-container
- if @deployments.blank?
.blank-state.blank-state-no-icon
%h2.blank-state-title
You don't have any deployments right now.
%p.blank-state-text
Define environments in the deploy stage(s) in
%code .gitlab-ci.yml
to track deployments here.
= link_to "Read more", help_page_path("ci/environments"), class: "btn btn-success"
.blank-state-row
.blank-state-center
%h2.blank-state-title
You don't have any deployments right now.
%p.blank-state-text
Define environments in the deploy stage(s) in
%code .gitlab-ci.yml
to track deployments here.
= link_to "Read more", help_page_path("ci/environments"), class: "btn btn-success"
- else
.table-holder
.ci-table.environments{ role: 'grid' }
......
......@@ -43,7 +43,7 @@
.dropdown-menu.dropdown-menu-align-right.hidden-lg
%ul
- if can_update_issue
%li= link_to 'Edit', edit_project_issue_path(@project, @issue)
%li= link_to 'Edit', edit_project_issue_path(@project, @issue), class: 'issuable-edit'
- unless current_user == @issue.author
%li= link_to 'Report abuse', new_abuse_report_path(user_id: @issue.author.id, ref_url: issue_url(@issue))
- if can_update_issue
......
......@@ -4,7 +4,7 @@
.sidebar-container
.blocks-container
.block
%strong.prepend-top-10
%strong.inline.prepend-top-8
= @build.name
- if can?(current_user, :update_build, @build) && @build.retryable?
= link_to "Retry", retry_namespace_project_job_path(@project.namespace, @project, @build), class: 'js-retry-button pull-right btn btn-inverted-secondary btn-retry visible-md-block visible-lg-block', method: :post
......
- @no_container = true
- @sort ||= sort_value_recently_updated
- page_title _('TagsPage|Tags')
- page_title s_('TagsPage|Tags')
- add_to_breadcrumbs("Repository", project_tree_path(@project))
.flex-list{ class: container_class }
......
......@@ -11,7 +11,8 @@
%li
If your HTTP repository is not publicly accessible, add authentication information to the URL: <code>https://username:password@gitlab.company.com/group/project.git</code>.
%li
The import will time out after 15 minutes. For repositories that take longer, use a clone/push combination.
The import will time out after #{time_interval_in_words(Gitlab.config.gitlab_shell.git_timeout)}.
For repositories that take longer, use a clone/push combination.
%li
To migrate an SVN repository, check out #{link_to "this document", help_page_path('user/project/import/svn')}.
%li
......
- show_create = local_assigns.fetch(:show_create, false)
- show_new_branch_form = show_new_repo? && show_create && can?(current_user, :push_code, @project)
- dropdown_toggle_text = @ref || @project.default_branch
= form_tag switch_project_refs_path(@project), method: :get, class: "project-refs-form" do
......
......@@ -9,7 +9,7 @@
.controls.hidden-xs
- if can?(current_user, :admin_group, group)
= link_to edit_group_path(group), class: "btn" do
= icon('cogs')
= sprite_icon('settings')
= link_to leave_group_group_members_path(group), data: { confirm: leave_confirmation_message(group) }, method: :delete, class: "btn", title: s_("GroupsTree|Leave this group") do
= icon('sign-out')
......
......@@ -9,7 +9,7 @@ class PipelineScheduleWorker
pipeline = Ci::CreatePipelineService.new(schedule.project,
schedule.owner,
ref: schedule.ref)
.execute(:schedule, save_on_errors: false, schedule: schedule)
.execute(:schedule, ignore_skip_ci: true, save_on_errors: false, schedule: schedule)
schedule.deactivate! unless pipeline.persisted?
rescue => e
......
---
title: Impersonation no longer gets stuck on password change.
merge_request: 15497
author:
type: fixed
---
title: Add edit button to mobile file view
merge_request: 15199
author: Travis Miller
type: added
---
title: Disables autocomplete in filtered searc
merge_request: 15477
author: Jacopo Beschi @jacopo-beschi
type: added
---
title: Label addition/removal are not going to be redacted wrongfully in the API.
merge_request: 15080
author:
type: fixed
---
title: Add inline editing to issues on mobile
merge_request: 15438
author:
type: changed
---
title: Fix gitlab:backup rake for hashed storage based repositories
merge_request: 15400
author:
type: fixed
---
title: Add dropdown sort to group milestones
merge_request: 15230
author: George Andrinopoulos
type: added
---
title: Fix commits page throwing 500 when the multi-file editor was enabled
merge_request: 15502
author:
type: fixed
---
title: Set the default gitlab-shell timeout to 3 hours
merge_request: 15292
author:
type: fixed
---
title: Fix issue where clicking a GPG verification badge would scroll to the top of
the page
merge_request: 15407
author:
type: fixed
---
title: Removed unused rake task, 'rake gitlab:sidekiq:drop_post_receive'
merge_request: 15493
author:
type: fixed
---
title: Fix bitbucket wiki import with hashed storage enabled
merge_request: 15490
author:
type: fixed
---
title: Fix hashed storage with project transfers to another namespace
title: Fix blank states using old css
merge_request:
author:
type: fixed
---
title: Make sure NotesActions#noteable returns a Noteable in the update action
title: Align retry button with job title with new grid size
merge_request:
author:
type: fixed
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.
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