Commit 33c31950 authored by Stan Hu's avatar Stan Hu

Merge branch 'master' into sh-support-bitbucket-server-import

parents 69fe32a5 38736175
......@@ -2,6 +2,245 @@
documentation](doc/development/changelog.md) for instructions on adding your own
entry.
## 11.1.0 (2018-07-22)
### Security (6 changes)
- Fix XSS vulnerability for table of content generation.
- Update sanitize gem to 4.6.5 to fix HTML injection vulnerability.
- HTML escape branch name in project graphs page.
- HTML escape the name of the user in ProjectsHelper#link_to_member.
- Don't show events from internal projects for anonymous users in public feed.
- Fix symlink vulnerability in project import.
### Removed (1 change)
- Remove deprecated object_storage_upload queue.
### Fixed (98 changes, 52 of them are from the community)
- Keep lists ordered when copying only list items. !18522 (Jan Beckmann)
- Fix bug where maintainer would not be allowed to push to forks with merge requests that have `Allow maintainer edits` enabled. !18968
- mergeError message has been binded using v-html directive. !19058 (Murat Dogan)
- Set MR target branch to default branch if target branch is not valid. !19067
- Fix CSS for buttons not to be hidden on issues/MR title. !19176 (Takuya Noguchi)
- Use same gem versions for rails5 as for rails4 where possible. !19498 (Jasper Maes)
- Fix extra blank line at start of rendered reStructuredText code block. !19596
- Fix username validation order on signup, resolves #45575. !19610 (Jan Beckmann)
- Make quick commands case insensitive. !19614 (Jan Beckmann)
- Remove incorrect CI doc re: PowerShell. !19622 (gfyoung)
- Fixes Microsoft Teams notifications for pipeline events. !19632 (Jeff Brown)
- Fix branch name encoding for dropdown on issue page. !19634
- Rails5 fix expected `issuable.reload.updated_at` to have changed. !19733 (Jasper Maes)
- Rails5 fix stack level too deep. !19762 (Jasper Maes)
- Rails5 ActionController::ParameterMissing: param is missing or the value is empty: application_setting. !19763 (Jasper Maes)
- Invalidate cache with project details when repository is updated. !19774
- Rails5 fix no implicit conversion of Hash into String. ActionController::Parameters no longer returns an hash in Rails 5. !19792 (Jasper Maes)
- [Rails5] Fix snippets_finder arel queries. !19796 (@blackst0ne)
- Fix fields for author & assignee in MR API docs. !19798 (gfyoung)
- Remove scrollbar in Safari in repo settings page. !19809 (gfyoung)
- Omits operartions and kubernetes item from project sidebar when repository or builds are disabled. !19835
- Rails5 fix passing Group objects array into for_projects_and_groups milestone scope. !19863 (Jasper Maes)
- Fix chat service tag notifications not sending when only default branch enabled. !19864
- Only show new issue / new merge request on group page when issues / merge requests are enabled. !19869 (Jan Beckmann)
- [Rails5] Explicitly set request.format for blob_controller. !19876 (@blackst0ne)
- [Rails5] Fix optimistic lock value. !19878 (@blackst0ne)
- Rails5 fix update_attribute usage not causing a save. !19881 (Jasper Maes)
- Rails5 fix connection execute return integer instead of string. !19901 (Jasper Maes)
- Rails5 fix format in uploads actions. !19907 (Jasper Maes)
- [Rails5] Fix "-1 is not a valid data_store". !19917 (@blackst0ne)
- [Rails5] Invalid single-table inheritance type: Group is not a subclass of Namespace. !19918 (@blackst0ne)
- [Rails5] Fix pipeline_schedules_controller_spec. !19919 (@blackst0ne)
- Rails5 fix passing Group objects array into for_projects_and_groups milestone scope. !19920 (Jasper Maes)
- Rails5 update Gemfile.rails5.lock. !19921 (Jasper Maes)
- [Rails5] Fix sessions_controller_spec. !19936 (@blackst0ne)
- [Rails5] Set request.format for artifacts_controller. !19937 (@blackst0ne)
- Fix webhook error when password is not present. !19945 (Jan Beckmann)
- Fix label and milestone duplicated records and IID errors. !19961
- Rails5 fix expected: 1 time with arguments: (97, anything, {"squash"=>false}) received: 0 times. !20004 (Jasper Maes)
- Rails5 fix Projects::PagesController spec. !20007 (Jasper Maes)
- [Rails5] Fix ActionCable '/cable' mountpoint conflict. !20015 (@blackst0ne)
- Fix branches are not shown in Merge Request dropdown when preferred language is not English. !20016 (Hiroyuki Sato)
- Rails5 fix Admin::HooksController. !20017 (Jasper Maes)
- Rails5 fix expected: 0 times with any arguments received: 1 time with arguments: DashboardController. !20018 (Jasper Maes)
- [Rails5] Set request.format in commits_controller. !20023 (@blackst0ne)
- Keeps the label on an issue when the issue is moved. !20036
- Cleanup Prometheus ruby metrics. !20039 (Ben Kochie)
- Rails 5 fix Capybara::ElementNotFound: Unable to find visible css #modal-revert-commit and expected: "/bar" got: "/foo". !20044 (Jasper Maes)
- [Rails5] Force the callback run first. !20055 (@blackst0ne)
- Add readme button to non-empty project page. !20104
- Fixed bug when editing a comment in an issue,the preview mode is toggled in the main textarea. !20112 (Constance Okoghenun)
- Ignore unknown OAuth sources in ApplicationSetting. !20129
- Fix paragraph line height for emoji. !20137 (George Tsiolis)
- Fixes issue with uploading same image to Profile Avatar twice. !20161 (Chirag Bhatia)
- Rails5 fix arel from in mysql_median_datetime_sql. !20167 (Jasper Maes)
- Adds the `locked` state to the merge request API so that it can be used as a search filter. !20186
- Enable Doorkeeper option to avoid generating new tokens when users login via oauth. !20200
- Fix OAuth Application Authorization screen to appear with each access. !20216
- Rails5 fix MySQL milliseconds problem in specs. !20221 (Jasper Maes)
- Rails5 fix Mysql comparison failure caused by milliseconds problem. !20222 (Jasper Maes)
- Updated last commit link color. !20234 (Constance Okoghenun)
- Fixed Merge request changes dropdown displays incorrectly. !20237 (Constance Okoghenun)
- Show jobs from same pipeline in sidebar in job details view. !20243
- [Rails5] Fix milestone GROUP BY query. !20256 (@blackst0ne)
- Line separator to the left of the 'Admin area' wrench icon had vanished. !20282 (bitsapien)
- Check if archived trace exist before archive it. !20297
- Load Devise with Omniauth when auto_sign_in_with_provider is configured. !20302
- Fix link to job when creating a new issue from a failed job. !20328
- Fix double "in" in time to artifact deletion message. !20357 (@bbodenmiller)
- Fix wrong role badge displayed in projects dashboard. !20374
- Stop relying on migrations in the CacheableAttributes cache key and cache attributes for 1 minute instead. !20389
- Fixes toggle discussion button not expanding collapsed discussions. !20452
- Resolve compatibility issues with node 6. !20461
- Fixes base command used in Helm installations. !20471
- Fix RSS button interaction on Dashboard, Project and Group activities. !20549
- Use appropriate timeout on Gitaly server info checks, avoid error on timeout. !20552
- Remove healthchecks from prometheus endpoint. !20565
- Render MR page when diffs cannot be fetched from the database or the git repository. !20680
- Expire correct method caches after HEAD changed.
- Ensure MR diffs always exist in the PR importer.
- Fix overlapping file title and file actions in MR changes tag.
- Mark MR as merged regardless of errors when closing issues.
- Fix performance bar modal visibility in Safari.
- Prevent browser autocomplete for milestone date fields.
- Limit the action suffixes in transaction metrics.
- Add /uploads subdirectory to allowed upload paths.
- Fix cross-project label references.
- Invalidate merge request diffs cache if diff data change.
- Don't show context button for diffs of deleted files.
- Structure getters for diff Store properly and adds specs.
- Bump rugged to 0.27.2.
- Fix Bamboo CI status not showing for branch plans.
- Fixed bug that allowed to remove other wiki pages if the title had wildcard characters.
- Disabled Web IDE autocomplete suggestions for Markdown files. (Isaac Smith)
- Fix merge request diffs when created with gitaly_diff_between enabled.
- Properly detect label reference if followed by period or question mark.
- Deactivate new KubernetesService created from active template to prevent project creation from failing.
- Allow trailing whitespace on blockquote fence lines.
### Deprecated (1 change)
- Removes unused bootstrap 4 scss files. !19423
### Changed (33 changes, 16 of them are from the community)
- Change label link vertical alignment property. !18777 (George Tsiolis)
- Updated the icon for expand buttons to ellipsis. !18793 (Constance Okoghenun)
- Create new or add existing Kubernetes cluster from a single page. !18963
- Use object storage as the first class persistable store for new live trace architecture. !19515
- Hide project name if searching against a project. !19595
- Allows you to create another deploy token dimmediately after creating one. !19639
- Removes the environment scope field for users that cannot edit it. !19643
- Don't hash user ID in OIDC subject claim. !19784 (Markus Koller)
- Milestone page list redesign. !19832 (Constance Okoghenun)
- Add environment dropdown for the metrics page. !19833
- Allow querying a single merge request within a project. !19853
- Update WebIDE to show file in tree on load. !19887
- Remove small container width. !19893 (George Tsiolis)
- Improve U2F workflow when using unsupported browsers. !19938 (Jan Beckmann)
- Update Web IDE file tree styles. !19969
- Highlight cluster settings message. !19996 (George Tsiolis)
- Fade uneditable area in Web IDE. !20008
- Update pipeline icon in web ide sidebar. !20058 (George Tsiolis)
- Revert merge request discussion buttons padding. !20060 (George Tsiolis)
- Fix boards issue highlight. !20063 (George Tsiolis)
- Update external link icon in header user dropdown. !20150 (George Tsiolis)
- Update external link icon in merge request widget. !20154 (George Tsiolis)
- Update environments nav controls icons. !20199 (George Tsiolis)
- Update integrations external link icons. !20205 (George Tsiolis)
- Fixes an issue where migrations instead of schema loading were run. !20227
- Add title placeholder for new issues. !20271 (George Tsiolis)
- Close revoke deploy token modal on escape keypress. !20347 (George Tsiolis)
- Change environment scope text depending on number of project clusters. Update form to only include form-groups.
- Improve Web IDE commit flow.
- Add machine type and pricing documentation links, add class to labels to make bold.
- Remove remaining traces of the Allocations Gem.
- Use one column form layout on Admin Area Settings page.
- Add back copy for existing gcp accounts within offer banner.
### Performance (16 changes, 4 of them are from the community)
- Fully migrate pipeline stages position. !19369
- Use Tooltip component in MrWidgetAuthorTime vue comonent. !19635 (George Tsiolis)
- Move boards modal EmptyState vue component. !20068 (George Tsiolis)
- Bump carrierwave gem verion to 1.2.3. !20287
- Remove redundant query when removing trace. !20324
- Improves performance of mr code, by fixing the state being mutated outside of the store in the util function trimFirstCharOfLineContent and in map operations. Avoids map operation in an empty array. Adds specs to the trimFirstCharOfLineContent function. !20380 (filipa)
- Reduce the number of queries when searching for groups. !20398
- Improve render performance of large wiki pages. !20465 (Peter Leitzen)
- Improves performance on Merge Request diff tab by removing the scroll event listeners being added to every file.
- Remove the ci_job_request_with_tags_matcher.
- Updated Gitaly fail-fast timeout values.
- Add index on deployable_type/id for deployments.
- Eliminate N+1 queries in LFS file locks checks during a push.
- Fix performance problem of accessing tag list for projects api endpoints.
- Improve performance of listing users without projects.
- Fixed pagination of web hook logs.
### Added (29 changes, 9 of them are from the community)
- Add dropdown to Groups link in top bar. !18280
- Web IDE supports now Image + Download Diff Viewing. !18768
- Use CommonMark syntax and rendering for new Markdown content. !19331
- Add SHA256 and HEAD on File API. !19439 (ahmet2mir)
- Add filename filtering to code search. !19509
- Add CI_PIPELINE_URL and CI_JOB_URL. !19618
- Expose visibility via Snippets API. !19620 (Jan Beckmann)
- Fixed pagination of groups API. !19665 (Marko, Peter)
- Added id sorting option to GET groups and subgroups API. !19665 (Marko, Peter)
- Add a link to the contributing page in the user dropdown. !19708
- Add Object Storage to project export. !20105
- Change avatar image in the header when user updates their avatar. !20119 (Jamie Schembri)
- Allow straight diff in Compare API. !20120 (Maciej Nowak)
- Add transfer project API endpoint. !20122 (Aram Visser)
- Expose permissions of the current user on resources in GraphQL. !20152
- Run repository checks in parallel for each shard. !20179
- Add pipeline lists to GraphQL. !20249
- Add option to add README when creating a project. !20335
- Add option to hide third party offers in admin application settings. !20379
- Add /confidential quick action. (Jan Beckmann)
- Support direct_upload for generic uploads.
- Display merge request title & description in Web IDE.
- Prune web hook logs older than 90 days.
- Add Web Terminal for Ci Builds. (Vicky Chijwani)
- Expose whether current user can push into a branch on branches API.
- Present state indication on GFM preview.
- migrate backup rake task to gitaly.
- Add Gitlab::SQL:CTE for easily building CTE statements.
- Added with_statsoption for GET /projects/:id/repository/commits.
### Other (28 changes, 11 of them are from the community)
- Move some Gitaly RPC's to opt-out. !19591
- Bump grape-path-helpers to 1.0.5. !19604 (@blackst0ne)
- Add CI job to check Gemfile.rails5.lock. !19605 (@blackst0ne)
- Move Gitaly branch/tag/ref RPC's to opt-out. !19644
- CE port gitlab-ee!6112. !19714
- Enable no-multi-assignment in JS files. !19808 (gfyoung)
- Enable no-restricted globals in JS files. !19877 (gfyoung)
- Improve no-multi-assignment fixes after enabling rule. !19915 (gfyoung)
- Enable prefer-structuring in JS files. !19943 (gfyoung)
- Enable frozen string in app/workers/*.rb. !19944 (gfyoung)
- Uses long sha version of the merged commit in MR widget copy to clipboard button. !19955
- Update new group page to better explain what groups are. !19991
- Update new SSH key page to improve copy. !19994
- Update new SSH key page to improve key input validation. !19997
- Gitaly metrics check for read/writeability. !20022
- Add ellispsis to web ide commit button. !20030
- Minor style changes to personal access token form and scope checkboxes. !20052
- Finish enabling frozen string for app/workers/*.rb. !20197 (gfyoung)
- Allows settings sections to expand by default when linking to them. !20211
- Enable frozen string in apps/validators/*.rb. !20220 (gfyoung)
- update bcrypt to also support libxcrypt. !20260 (muhammadn)
- Enable frozen string in apps/validators/*.rb. !20382 (gfyoung)
- Removes unused vuex code in mr refactor and removes unneeded dependencies. !20499
- Delete non-latest merge request diff files upon merge.
- Schedule workers to delete non-latest diffs in post-migration.
- Remove the use of `is_shared` of `Ci::Runner`.
- Add more detailed logging to githost.log when rebasing.
- Use monospaced font for MR diff commit link ref on GFM.
## 11.0.4 (2018-07-17)
### Security (1 change)
......
......@@ -133,7 +133,7 @@ Most issues will have labels for at least one of the following:
- Type: ~"feature proposal", ~bug, ~customer, etc.
- Subject: ~wiki, ~"container registry", ~ldap, ~api, ~frontend, etc.
- Team: ~"CI/CD", ~Discussion, ~Quality, ~Platform, etc.
- Team: ~"CI/CD", ~Plan, ~Quality, ~Platform, etc.
- Release Scoping: ~Deliverable, ~Stretch, ~"Next Patch Release"
- Priority: ~P1, ~P2, ~P3, ~P4
- Severity: ~S1, ~S2, ~S3, ~S4
......@@ -187,12 +187,13 @@ The current team labels are:
- ~Configuration
- ~"CI/CD"
- ~Discussion
- ~Create
- ~Distribution
- ~Documentation
- ~Geo
- ~Gitaly
- ~Monitoring
- ~Plan
- ~Platform
- ~Quality
- ~Release
......
......@@ -323,6 +323,7 @@ group :development do
end
group :development, :test do
gem 'bootsnap', '~> 1.3'
gem 'bullet', '~> 5.5.0', require: !!ENV['ENABLE_BULLET']
gem 'pry-byebug', '~> 3.4.1', platform: :mri
gem 'pry-rails', '~> 0.3.4'
......
......@@ -87,6 +87,8 @@ GEM
binding_of_caller (0.7.2)
debug_inspector (>= 0.0.1)
blankslate (2.1.2.4)
bootsnap (1.3.1)
msgpack (~> 1.0)
bootstrap_form (2.7.0)
brakeman (4.2.1)
browser (2.2.0)
......@@ -500,6 +502,7 @@ GEM
mini_portile2 (2.3.0)
minitest (5.7.0)
mousetrap-rails (1.4.6)
msgpack (1.2.4)
multi_json (1.13.1)
multi_xml (0.6.0)
multipart-post (2.0.0)
......@@ -986,6 +989,7 @@ DEPENDENCIES
benchmark-ips (~> 2.3.0)
better_errors (~> 2.1.0)
binding_of_caller (~> 0.7.2)
bootsnap (~> 1.3)
bootstrap_form (~> 2.7.0)
brakeman (~> 4.2)
browser (~> 2.2)
......
......@@ -90,6 +90,8 @@ GEM
binding_of_caller (0.7.2)
debug_inspector (>= 0.0.1)
blankslate (2.1.2.4)
bootsnap (1.3.1)
msgpack (~> 1.0)
bootstrap_form (2.7.0)
brakeman (4.2.1)
browser (2.2.0)
......@@ -503,6 +505,7 @@ GEM
mini_portile2 (2.3.0)
minitest (5.7.0)
mousetrap-rails (1.4.6)
msgpack (1.2.4)
multi_json (1.13.1)
multi_xml (0.6.0)
multipart-post (2.0.0)
......@@ -996,6 +999,7 @@ DEPENDENCIES
benchmark-ips (~> 2.3.0)
better_errors (~> 2.1.0)
binding_of_caller (~> 0.7.2)
bootsnap (~> 1.3)
bootstrap_form (~> 2.7.0)
brakeman (~> 4.2)
browser (~> 2.2)
......
11.1.0-pre
11.2.0-pre
......@@ -105,7 +105,7 @@ export default {
</div>
<label
:for="list.id + '-title'"
class="label-light"
class="label-bold"
>
Title
</label>
......
......@@ -68,7 +68,7 @@ export default {
<template>
<div>
<label class="label-light prepend-top-10">
<label class="label-bold prepend-top-10">
Project
</label>
<div
......
......@@ -14,6 +14,7 @@ import 'core-js/es6/weak-map';
// Browser polyfills
import 'classlist-polyfill';
import 'formdata-polyfill';
import './polyfills/custom_event';
import './polyfills/element';
import './polyfills/event';
......
......@@ -30,6 +30,7 @@ export default {
:render-header="false"
:render-diff-file="false"
:always-expanded="true"
:discussions-by-diff-order="true"
/>
</ul>
</div>
......
......@@ -66,7 +66,7 @@ export default {
<div
class="form-group row"
>
<label class="label-light col-form-label col-sm-3">
<label class="label-bold col-form-label col-sm-3">
{{ __('Name') }}
</label>
<div class="col-sm-9">
......
import Vue from 'vue';
import VueRouter from 'vue-router';
import { join as joinPath } from 'path';
import flash from '~/flash';
import store from './stores';
import { activityBarViews } from './constants';
......@@ -37,17 +38,29 @@ const router = new VueRouter({
base: `${gon.relative_url_root}/-/ide/`,
routes: [
{
path: '/project/:namespace/:project+',
path: '/project/:namespace+/:project',
component: EmptyRouterComponent,
children: [
{
path: ':targetmode(edit|tree|blob)/*',
path: ':targetmode(edit|tree|blob)/:branchid+/-/*',
component: EmptyRouterComponent,
},
{
path: ':targetmode(edit|tree|blob)/:branchid+/',
redirect: to => joinPath(to.path, '/-/'),
},
{
path: ':targetmode(edit|tree|blob)',
redirect: to => joinPath(to.path, '/master/-/'),
},
{
path: 'merge_requests/:mrid',
component: EmptyRouterComponent,
},
{
path: '',
redirect: to => joinPath(to.path, '/edit/master/-/'),
},
],
},
],
......@@ -63,11 +76,10 @@ router.beforeEach((to, from, next) => {
.then(() => {
const fullProjectId = `${to.params.namespace}/${to.params.project}`;
const baseSplit = (to.params[0] && to.params[0].split('/-/')) || [''];
const branchId = baseSplit[0].slice(-1) === '/' ? baseSplit[0].slice(0, -1) : baseSplit[0];
const branchId = to.params.branchid;
if (branchId) {
const basePath = baseSplit.length > 1 ? baseSplit[1] : '';
const basePath = to.params[0] || '';
store.dispatch('setCurrentBranchId', branchId);
......
......@@ -5,19 +5,20 @@ import resolvedSvg from 'icons/_icon_status_success_solid.svg';
import mrIssueSvg from 'icons/_icon_mr_issue.svg';
import nextDiscussionSvg from 'icons/_next_discussion.svg';
import { pluralize } from '../../lib/utils/text_utility';
import { scrollToElement } from '../../lib/utils/common_utils';
import discussionNavigation from '../mixins/discussion_navigation';
import tooltip from '../../vue_shared/directives/tooltip';
export default {
directives: {
tooltip,
},
mixins: [discussionNavigation],
computed: {
...mapGetters([
'getUserData',
'getNoteableData',
'discussionCount',
'unresolvedDiscussions',
'firstUnresolvedDiscussionId',
'resolvedDiscussionCount',
]),
isLoggedIn() {
......@@ -35,11 +36,6 @@ export default {
resolveAllDiscussionsIssuePath() {
return this.getNoteableData.create_issue_to_resolve_discussions_path;
},
firstUnresolvedDiscussionId() {
const item = this.unresolvedDiscussions[0] || {};
return item.id;
},
},
created() {
this.resolveSvg = resolveSvg;
......@@ -50,22 +46,10 @@ export default {
methods: {
...mapActions(['expandDiscussion']),
jumpToFirstUnresolvedDiscussion() {
const discussionId = this.firstUnresolvedDiscussionId;
if (!discussionId) {
return;
}
const el = document.querySelector(`[data-discussion-id="${discussionId}"]`);
const activeTab = window.mrTabs.currentAction;
if (activeTab === 'commits' || activeTab === 'pipelines') {
window.mrTabs.activateTab('show');
}
const diffTab = window.mrTabs.currentAction === 'diffs';
const discussionId = this.firstUnresolvedDiscussionId(diffTab);
if (el) {
this.expandDiscussion({ discussionId });
scrollToElement(el);
}
this.jumpToDiscussion(discussionId);
},
},
};
......
<script>
import _ from 'underscore';
import { mapActions, mapGetters } from 'vuex';
import resolveDiscussionsSvg from 'icons/_icon_mr_issue.svg';
import nextDiscussionsSvg from 'icons/_next_discussion.svg';
import { convertObjectPropsToCamelCase, scrollToElement } from '~/lib/utils/common_utils';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { truncateSha } from '~/lib/utils/text_utility';
import systemNote from '~/vue_shared/components/notes/system_note.vue';
import { s__ } from '~/locale';
......@@ -21,6 +20,7 @@ import placeholderSystemNote from '../../vue_shared/components/notes/placeholder
import autosave from '../mixins/autosave';
import noteable from '../mixins/noteable';
import resolvable from '../mixins/resolvable';
import discussionNavigation from '../mixins/discussion_navigation';
import tooltip from '../../vue_shared/directives/tooltip';
export default {
......@@ -40,7 +40,7 @@ export default {
directives: {
tooltip,
},
mixins: [autosave, noteable, resolvable],
mixins: [autosave, noteable, resolvable, discussionNavigation],
props: {
discussion: {
type: Object,
......@@ -61,6 +61,11 @@ export default {
required: false,
default: false,
},
discussionsByDiffOrder: {
type: Boolean,
required: false,
default: false,
},
},
data() {
return {
......@@ -75,7 +80,12 @@ export default {
'discussionCount',
'resolvedDiscussionCount',
'allDiscussions',
'unresolvedDiscussionsIdsByDiff',
'unresolvedDiscussionsIdsByDate',
'unresolvedDiscussions',
'unresolvedDiscussionsIdsOrdered',
'nextUnresolvedDiscussionId',
'isLastUnresolvedDiscussion',
]),
transformedDiscussion() {
return {
......@@ -126,6 +136,10 @@ export default {
hasMultipleUnresolvedDiscussions() {
return this.unresolvedDiscussions.length > 1;
},
showJumpToNextDiscussion() {
return this.hasMultipleUnresolvedDiscussions &&
!this.isLastUnresolvedDiscussion(this.discussion.id, this.discussionsByDiffOrder);
},
shouldRenderDiffs() {
const { diffDiscussion, diffFile } = this.transformedDiscussion;
......@@ -242,21 +256,10 @@ Please check your network connection and try again.`;
});
},
jumpToNextDiscussion() {
const discussionIds = this.allDiscussions.map(d => d.id);
const unresolvedIds = this.unresolvedDiscussions.map(d => d.id);
const currentIndex = discussionIds.indexOf(this.discussion.id);
const remainingAfterCurrent = discussionIds.slice(currentIndex + 1);
const nextIndex = _.findIndex(remainingAfterCurrent, id => unresolvedIds.indexOf(id) > -1);
if (nextIndex > -1) {
const nextId = remainingAfterCurrent[nextIndex];
const el = document.querySelector(`[data-discussion-id="${nextId}"]`);
const nextId =
this.nextUnresolvedDiscussionId(this.discussion.id, this.discussionsByDiffOrder);
if (el) {
this.expandDiscussion({ discussionId: nextId });
scrollToElement(el);
}
}
this.jumpToDiscussion(nextId);
},
},
};
......@@ -398,7 +401,7 @@ Please check your network connection and try again.`;
</a>
</div>
<div
v-if="hasMultipleUnresolvedDiscussions"
v-if="showJumpToNextDiscussion"
class="btn-group"
role="group">
<button
......
import { scrollToElement } from '~/lib/utils/common_utils';
export default {
methods: {
jumpToDiscussion(id) {
if (id) {
const activeTab = window.mrTabs.currentAction;
const selector =
activeTab === 'diffs'
? `ul.notes[data-discussion-id="${id}"]`
: `div.discussion[data-discussion-id="${id}"]`;
const el = document.querySelector(selector);
if (activeTab === 'commits' || activeTab === 'pipelines') {
window.mrTabs.activateTab('show');
}
if (el) {
this.expandDiscussion({ discussionId: id });
scrollToElement(el);
return true;
}
}
return false;
},
},
};
......@@ -70,6 +70,9 @@ export const allDiscussions = (state, getters) => {
return Object.values(resolved).concat(unresolved);
};
export const allResolvableDiscussions = (state, getters) =>
getters.allDiscussions.filter(d => !d.individual_note && d.resolvable);
export const resolvedDiscussionsById = state => {
const map = {};
......@@ -86,6 +89,51 @@ export const resolvedDiscussionsById = state => {
return map;
};
// Gets Discussions IDs ordered by the date of their initial note
export const unresolvedDiscussionsIdsByDate = (state, getters) =>
getters.allResolvableDiscussions
.filter(d => !d.resolved)
.sort((a, b) => {
const aDate = new Date(a.notes[0].created_at);
const bDate = new Date(b.notes[0].created_at);
if (aDate < bDate) {
return -1;
}
return aDate === bDate ? 0 : 1;
})
.map(d => d.id);
// Gets Discussions IDs ordered by their position in the diff
//
// Sorts the array of resolvable yet unresolved discussions by
// comparing file names first. If file names are the same, compares
// line numbers.
export const unresolvedDiscussionsIdsByDiff = (state, getters) =>
getters.allResolvableDiscussions
.filter(d => !d.resolved)
.sort((a, b) => {
if (!a.diff_file || !b.diff_file) {
return 0;
}
// Get file names comparison result
const filenameComparison = a.diff_file.file_path.localeCompare(b.diff_file.file_path);
// Get the line numbers, to compare within the same file
const aLines = [a.position.formatter.new_line, a.position.formatter.old_line];
const bLines = [b.position.formatter.new_line, b.position.formatter.old_line];
return filenameComparison < 0 ||
(filenameComparison === 0 &&
// .max() because one of them might be zero (if removed/added)
Math.max(aLines[0], aLines[1]) < Math.max(bLines[0], bLines[1]))
? -1
: 1;
})
.map(d => d.id);
export const resolvedDiscussionCount = (state, getters) => {
const resolvedMap = getters.resolvedDiscussionsById;
......@@ -102,5 +150,42 @@ export const discussionTabCounter = state => {
return all.length;
};
// Returns the list of discussion IDs ordered according to given parameter
// @param {Boolean} diffOrder - is ordered by diff?
export const unresolvedDiscussionsIdsOrdered = (state, getters) => diffOrder => {
if (diffOrder) {
return getters.unresolvedDiscussionsIdsByDiff;
}
return getters.unresolvedDiscussionsIdsByDate;
};
// Checks if a given discussion is the last in the current order (diff or date)
// @param {Boolean} discussionId - id of the discussion
// @param {Boolean} diffOrder - is ordered by diff?
export const isLastUnresolvedDiscussion = (state, getters) => (discussionId, diffOrder) => {
const idsOrdered = getters.unresolvedDiscussionsIdsOrdered(diffOrder);
const lastDiscussionId = idsOrdered[idsOrdered.length - 1];
return lastDiscussionId === discussionId;
};
// Gets the ID of the discussion following the one provided, respecting order (diff or date)
// @param {Boolean} discussionId - id of the current discussion
// @param {Boolean} diffOrder - is ordered by diff?
export const nextUnresolvedDiscussionId = (state, getters) => (discussionId, diffOrder) => {
const idsOrdered = getters.unresolvedDiscussionsIdsOrdered(diffOrder);
const currentIndex = idsOrdered.indexOf(discussionId);
return idsOrdered.slice(currentIndex + 1, currentIndex + 2)[0];
};
// @param {Boolean} diffOrder - is ordered by diff?
export const firstUnresolvedDiscussionId = (state, getters) => diffOrder => {
if (diffOrder) {
return getters.unresolvedDiscussionsIdsByDiff[0];
}
return getters.unresolvedDiscussionsIdsByDate[0];
};
// prevent babel-plugin-rewire from generating an invalid default during karma tests
export default () => {};
......@@ -68,7 +68,7 @@
:name="inputNameAttribute"
:value="cronInterval"
:checked="isEditable"
class="label-light"
class="label-bold"
type="radio"
@click="toggleCustomInput(true)"
/>
......@@ -93,13 +93,13 @@
v-model="cronInterval"
:name="inputNameAttribute"
:value="cronIntervalPresets.everyDay"
class="label-light"
class="label-bold"
type="radio"
@click="toggleCustomInput(false)"
/>
<label
class="label-light"
class="label-bold"
for="every-day"
>
{{ __('Every day (at 4:00am)') }}
......@@ -112,13 +112,13 @@
v-model="cronInterval"
:name="inputNameAttribute"
:value="cronIntervalPresets.everyWeek"
class="label-light"
class="label-bold"
type="radio"
@click="toggleCustomInput(false)"
/>
<label
class="label-light"
class="label-bold"
for="every-week"
>
{{ __('Every week (Sundays at 4:00am)') }}
......@@ -131,13 +131,13 @@
v-model="cronInterval"
:name="inputNameAttribute"
:value="cronIntervalPresets.everyMonth"
class="label-light"
class="label-bold"
type="radio"
@click="toggleCustomInput(false)"
/>
<label
class="label-light"
class="label-bold"
for="every-month"
>
{{ __('Every month (on the 1st at 4:00am)') }}
......
......@@ -24,7 +24,7 @@
<div class="project-feature-row">
<label
v-if="label"
class="label-light"
class="label-bold"
>
{{ label }}
<a
......
......@@ -49,13 +49,15 @@ export default class Profile {
saveForm() {
const self = this;
const formData = new FormData(this.form[0]);
const formData = new FormData(this.form.get(0));
const avatarBlob = this.avatarGlCrop.getBlob();
if (avatarBlob != null) {
formData.append('user[avatar]', avatarBlob, 'avatar.png');
}
formData.delete('user[avatar]-trigger');
axios({
method: this.form.attr('method'),
url: this.form.attr('action'),
......
......@@ -822,7 +822,7 @@ header.header-content .dropdown-menu.frequent-items-dropdown-menu {
display: flex;
flex-direction: row;
width: 500px;
height: 334px;
height: 354px;
.frequent-items-dropdown-sidebar,
.frequent-items-dropdown-content {
......@@ -868,6 +868,7 @@ header.header-content .dropdown-menu.frequent-items-dropdown-menu {
}
.frequent-items-list-container {
height: 304px;
padding: 8px 0;
overflow-y: auto;
......@@ -897,10 +898,6 @@ header.header-content .dropdown-menu.frequent-items-dropdown-menu {
margin-top: 8px;
}
.frequent-items-search-container {
height: 284px;
}
@include media-breakpoint-down(xs) {
.frequent-items-list-container {
width: auto;
......
......@@ -31,7 +31,7 @@ label {
margin: 0;
}
&.label-light {
&.label-bold {
font-weight: $gl-font-weight-bold;
}
}
......
.split-report-section {
border-bottom: 1px solid $gray-darker;
.report-block-container {
max-height: 500px;
overflow: auto;
}
.space-children,
.space-children > span {
display: flex;
align-self: center;
}
.media {
align-items: center;
padding: 10px;
line-height: 20px;
/*
This fixes the wrapping div of the icon in the report header.
Apparently the borderless status icons are half the size of the status icons with border.
This means we have to double the size of the wrapping div for borderless icons.
*/
.space-children:first-child {
width: 32px;
height: 32px;
align-items: center;
justify-content: center;
margin-right: 5px;
margin-left: 1px;
}
}
.code-text {
width: 100%;
flex: 1;
}
}
.mr-widget-grouped-section {
.report-block-container {
max-height: 170px;
overflow: auto;
}
.report-block-list-issue-parent {
padding: $gl-padding-top $gl-padding;
border-top: 1px solid $border-color;
}
.report-block-list-icon .loading-container {
position: relative;
left: -2px;
// needed to make the next element align with the
// elements below that have a svg with 16px width
.fa-spinner {
width: 16px;
}
}
}
.report-block-container {
border-top: 1px solid $border-color;
padding: $gl-padding-top;
background-color: $gray-light;
// Clean MR widget CSS
line-height: 20px;
}
.report-block-list {
list-style: none;
padding: 0 1px;
margin: 0;
.license-item {
line-height: $gl-padding-24;
.license-dependencies {
color: $gl-text-color-tertiary;
}
.btn-show-all-packages {
line-height: $gl-btn-line-height;
margin-bottom: 2px;
}
}
}
.report-block-list-icon {
display: flex;
&.failed {
color: $red-500;
}
&.success {
color: $green-500;
}
&.neutral {
color: $theme-gray-700;
}
.ci-status-icon {
svg {
width: 16px;
height: 16px;
left: -2px;
}
}
}
.report-block-list-issue {
display: flex;
align-items: flex-start;
align-content: flex-start;
}
.is-dismissed .report-block-list-issue-description,
.is-dismissed .vulnerability-name-button {
text-decoration: line-through;
}
.report-block-list-issue-description-text::after {
content: '\00a0';
}
.report-block-list-issue-description {
align-content: space-around;
align-items: flex-start;
flex-wrap: wrap;
display: flex;
align-self: center;
}
.report-block {
.break-link {
word-wrap: break-word;
word-break: break-all;
}
}
.report-block-issue-code {
width: 600px;
}
.modal-security-report-dast {
.modal-dialog {
width: $modal-lg;
max-width: $modal-lg;
}
// This is temporary till we get the new modals hooked up
&.modal-hide-footer .modal-footer {
display: none;
}
}
......@@ -10,7 +10,6 @@ class Projects::RawController < Projects::ApplicationController
def show
@blob = @repository.blob_at(@commit.id, @path)
if @blob
headers['X-Content-Type-Options'] = 'nosniff'
......@@ -19,7 +18,7 @@ class Projects::RawController < Projects::ApplicationController
if @blob.stored_externally?
send_lfs_object
else
send_git_blob @repository, @blob
send_git_blob @repository, @blob, inline: (params[:inline] != 'false')
end
else
render_404
......
......@@ -114,22 +114,22 @@ module BlobHelper
icon("#{file_type_icon_class('file', mode, name)} fw")
end
def blob_raw_url(only_path: false)
def blob_raw_url(**kwargs)
if @build && @entry
raw_project_job_artifacts_url(@project, @build, path: @entry.path, only_path: only_path)
raw_project_job_artifacts_url(@project, @build, path: @entry.path, **kwargs)
elsif @snippet
if @snippet.project_id
raw_project_snippet_url(@project, @snippet, only_path: only_path)
raw_project_snippet_url(@project, @snippet, **kwargs)
else
raw_snippet_url(@snippet, only_path: only_path)
raw_snippet_url(@snippet, **kwargs)
end
elsif @blob
project_raw_url(@project, @id, only_path: only_path)
project_raw_url(@project, @id, **kwargs)
end
end
def blob_raw_path
blob_raw_url(only_path: true)
def blob_raw_path(**kwargs)
blob_raw_url(**kwargs, only_path: true)
end
# SVGs can contain malicious JavaScript; only include whitelisted
......@@ -226,16 +226,17 @@ module BlobHelper
def open_raw_blob_button(blob)
return if blob.empty?
return if blob.raw_binary? || blob.stored_externally?
if blob.raw_binary? || blob.stored_externally?
icon = sprite_icon('download')
title = 'Download'
else
icon = icon('file-code-o')
title = 'Open raw'
end
title = 'Open raw'
link_to icon('file-code-o'), blob_raw_path, class: 'btn btn-sm has-tooltip', target: '_blank', rel: 'noopener noreferrer', title: title, data: { container: 'body' }
end
def download_blob_button(blob)
return if blob.empty?
link_to icon, blob_raw_path, class: 'btn btn-sm has-tooltip', target: '_blank', rel: 'noopener noreferrer', title: title, data: { container: 'body' }
title = 'Download'
link_to sprite_icon('download'), blob_raw_path(inline: false), download: @path, class: 'btn btn-sm has-tooltip', target: '_blank', rel: 'noopener noreferrer', title: title, data: { container: 'body' }
end
def blob_render_error_reason(viewer)
......
......@@ -2,9 +2,9 @@
# Workhorse will also serve files when using `send_file`.
module WorkhorseHelper
# Send a Git blob through Workhorse
def send_git_blob(repository, blob)
def send_git_blob(repository, blob, inline: true)
headers.store(*Gitlab::Workhorse.send_git_blob(repository, blob))
headers['Content-Disposition'] = 'inline'
headers['Content-Disposition'] = inline ? 'inline' : 'attachment'
headers['Content-Type'] = safe_content_type(blob)
render plain: ""
end
......
......@@ -67,7 +67,7 @@ module Projects
else
gitlab_shell.import_repository(project.repository_storage, project.disk_path, project.import_url)
end
rescue Gitlab::Shell::Error, Gitlab::Git::RepositoryMirroring::RemoteError => e
rescue Gitlab::Shell::Error => e
# Expire cache to prevent scenarios such as:
# 1. First import failed, but the repo was imported successfully, so +exists?+ returns true
# 2. Retried import, repo is broken or not imported but +exists?+ still returns true
......
......@@ -3,7 +3,7 @@
%fieldset
.form-group
= f.label :admin_notification_email, 'Abuse reports notification email', class: 'label-light'
= f.label :admin_notification_email, 'Abuse reports notification email', class: 'label-bold'
= f.text_field :admin_notification_email, class: 'form-control'
.form-text.text-muted
Abuse reports will be sent to this address if it is set. Abuse reports are always available in the admin area.
......
......@@ -8,23 +8,23 @@
= f.label :gravatar_enabled, class: 'form-check-label' do
Gravatar enabled
.form-group
= f.label :default_projects_limit, class: 'label-light'
= f.label :default_projects_limit, class: 'label-bold'
= f.number_field :default_projects_limit, class: 'form-control'
.form-group
= f.label :max_attachment_size, 'Maximum attachment size (MB)', class: 'label-light'
= f.label :max_attachment_size, 'Maximum attachment size (MB)', class: 'label-bold'
= f.number_field :max_attachment_size, class: 'form-control'
.form-group
= f.label :session_expire_delay, 'Session duration (minutes)', class: 'label-light'
= f.label :session_expire_delay, 'Session duration (minutes)', class: 'label-bold'
= f.number_field :session_expire_delay, class: 'form-control'
%span.form-text.text-muted#session_expire_delay_help_block GitLab restart is required to apply changes
.form-group
= f.label :user_oauth_applications, 'User OAuth applications', class: 'label-light'
= f.label :user_oauth_applications, 'User OAuth applications', class: 'label-bold'
.form-check
= f.check_box :user_oauth_applications, class: 'form-check-input'
= f.label :user_oauth_applications, class: 'form-check-label' do
Allow users to register any application to use GitLab as an OAuth provider
.form-group
= f.label :user_default_external, 'New users set to external', class: 'label-light'
= f.label :user_default_external, 'New users set to external', class: 'label-bold'
.form-check
= f.check_box :user_default_external, class: 'form-check-input'
= f.label :user_default_external, class: 'form-check-label' do
......
......@@ -14,12 +14,12 @@
.form-text.text-muted
Limit the amount of resources slow running jobs are assigned.
.form-group
= f.label :sidekiq_throttling_queues, 'Sidekiq queues to throttle', class: 'label-light'
= f.label :sidekiq_throttling_queues, 'Sidekiq queues to throttle', class: 'label-bold'
= f.select :sidekiq_throttling_queues, sidekiq_queue_options_for_select, { include_hidden: false }, multiple: true, class: 'select2 select-wide', data: { field: 'sidekiq_throttling_queues' }
.form-text.text-muted
Choose which queues you wish to throttle.
.form-group
= f.label :sidekiq_throttling_factor, 'Throttling Factor', class: 'label-light'
= f.label :sidekiq_throttling_factor, 'Throttling Factor', class: 'label-bold'
= f.number_field :sidekiq_throttling_factor, class: 'form-control', min: '0.01', max: '0.99', step: '0.01'
.form-text.text-muted
The factor by which the queues should be throttled. A value between 0.0 and 1.0, exclusive.
......
......@@ -11,7 +11,7 @@
It will automatically build, test, and deploy applications based on a predefined CI/CD configuration
= link_to icon('question-circle'), help_page_path('topics/autodevops/index.md')
.form-group
= f.label :auto_devops_domain, class: 'label-light'
= f.label :auto_devops_domain, class: 'label-bold'
= f.text_field :auto_devops_domain, class: 'form-control', placeholder: 'domain.com'
.form-text.text-muted
= s_("AdminSettings|Specify a domain to use by default for every project's Auto Review Apps and Auto Deploy stages.")
......@@ -21,17 +21,17 @@
= f.label :shared_runners_enabled, class: 'form-check-label' do
Enable shared runners for new projects
.form-group
= f.label :shared_runners_text, class: 'label-light'
= f.label :shared_runners_text, class: 'label-bold'
= f.text_area :shared_runners_text, class: 'form-control', rows: 4
.form-text.text-muted Markdown enabled
.form-group
= f.label :max_artifacts_size, 'Maximum artifacts size (MB)', class: 'label-light'
= f.label :max_artifacts_size, 'Maximum artifacts size (MB)', class: 'label-bold'
= f.number_field :max_artifacts_size, class: 'form-control'
.form-text.text-muted
Set the maximum file size for each job's artifacts
= link_to icon('question-circle'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'maximum-artifacts-size')
.form-group
= f.label :default_artifacts_expire_in, 'Default artifacts expiration', class: 'label-light'
= f.label :default_artifacts_expire_in, 'Default artifacts expiration', class: 'label-bold'
= f.text_field :default_artifacts_expire_in, class: 'form-control'
.form-text.text-muted
Set the default expiration time for each job's artifacts.
......
......@@ -3,20 +3,20 @@
%fieldset
.form-group
= f.label :gitaly_timeout_default, 'Default Timeout Period', class: 'label-light'
= f.label :gitaly_timeout_default, 'Default Timeout Period', class: 'label-bold'
= f.number_field :gitaly_timeout_default, class: 'form-control'
.form-text.text-muted
Timeout for Gitaly calls from the GitLab application (in seconds). This timeout is not enforced
for git fetch/push operations or Sidekiq jobs.
.form-group
= f.label :gitaly_timeout_fast, 'Fast Timeout Period', class: 'label-light'
= f.label :gitaly_timeout_fast, 'Fast Timeout Period', class: 'label-bold'
= f.number_field :gitaly_timeout_fast, class: 'form-control'
.form-text.text-muted
Fast operation timeout (in seconds). Some Gitaly operations are expected to be fast.
If they exceed this threshold, there may be a problem with a storage shard and 'failing fast'
can help maintain the stability of the GitLab instance.
.form-group
= f.label :gitaly_timeout_medium, 'Medium Timeout Period', class: 'label-light'
= f.label :gitaly_timeout_medium, 'Medium Timeout Period', class: 'label-bold'
= f.number_field :gitaly_timeout_medium, class: 'form-control'
.form-text.text-muted
Medium operation timeout (in seconds). This should be a value between the Fast and the Default timeout.
......
......@@ -3,7 +3,7 @@
%fieldset
.form-group
= f.label :help_page_text, class: 'label-light'
= f.label :help_page_text, class: 'label-bold'
= f.text_area :help_page_text, class: 'form-control', rows: 4
.form-text.text-muted Markdown enabled
.form-group
......@@ -12,7 +12,7 @@
= f.label :help_page_hide_commercial_content, class: 'form-check-label' do
Hide marketing-related entries from help
.form-group
= f.label :help_page_support_url, 'Support page URL', class: 'label-light'
= f.label :help_page_support_url, 'Support page URL', class: 'label-bold'
= f.text_field :help_page_support_url, class: 'form-control', placeholder: 'http://company.example.com/getting-help', :'aria-describedby' => 'support_help_block'
%span.form-text.text-muted#support_help_block Alternate support URL for help page
......
......@@ -14,10 +14,10 @@
= f.label :metrics_enabled, class: 'form-check-label' do
Enable InfluxDB Metrics
.form-group
= f.label :metrics_host, 'InfluxDB host', class: 'label-light'
= f.label :metrics_host, 'InfluxDB host', class: 'label-bold'
= f.text_field :metrics_host, class: 'form-control', placeholder: 'influxdb.example.com'
.form-group
= f.label :metrics_port, 'InfluxDB port', class: 'label-light'
= f.label :metrics_port, 'InfluxDB port', class: 'label-bold'
= f.text_field :metrics_port, class: 'form-control', placeholder: '8089'
.form-text.text-muted
The UDP port to use for connecting to InfluxDB. InfluxDB requires that
......@@ -25,7 +25,7 @@
sending messages to this port, without it metrics data will not be
saved.
.form-group
= f.label :metrics_pool_size, 'Connection pool size', class: 'label-light'
= f.label :metrics_pool_size, 'Connection pool size', class: 'label-bold'
= f.number_field :metrics_pool_size, class: 'form-control'
.form-text.text-muted
The amount of InfluxDB connections to open. Connections are opened
......@@ -33,25 +33,25 @@
enough connections are available (at minimum the amount of application
server threads).
.form-group
= f.label :metrics_timeout, 'Connection timeout', class: 'label-light'
= f.label :metrics_timeout, 'Connection timeout', class: 'label-bold'
= f.number_field :metrics_timeout, class: 'form-control'
.form-text.text-muted
The amount of seconds after which an InfluxDB connection will time
out.
.form-group
= f.label :metrics_method_call_threshold, 'Method Call Threshold (ms)', class: 'label-light'
= f.label :metrics_method_call_threshold, 'Method Call Threshold (ms)', class: 'label-bold'
= f.number_field :metrics_method_call_threshold, class: 'form-control'
.form-text.text-muted
A method call is only tracked when it takes longer to complete than
the given amount of milliseconds.
.form-group
= f.label :metrics_sample_interval, 'Sampler Interval (sec)', class: 'label-light'
= f.label :metrics_sample_interval, 'Sampler Interval (sec)', class: 'label-bold'
= f.number_field :metrics_sample_interval, class: 'form-control'
.form-text.text-muted
The sampling interval in seconds. Sampled data includes memory usage,
retained Ruby objects, file descriptors and so on.
.form-group
= f.label :metrics_packet_size, 'Metrics per packet', class: 'label-light'
= f.label :metrics_packet_size, 'Metrics per packet', class: 'label-bold'
= f.number_field :metrics_packet_size, class: 'form-control'
.form-text.text-muted
The amount of points to store in a single UDP packet. More points
......
......@@ -10,10 +10,10 @@
%span.form-text.text-muted
Helps reduce request volume (e.g. from crawlers or abusive bots)
.form-group
= f.label :throttle_unauthenticated_requests_per_period, 'Max requests per period per IP', class: 'label-light'
= f.label :throttle_unauthenticated_requests_per_period, 'Max requests per period per IP', class: 'label-bold'
= f.number_field :throttle_unauthenticated_requests_per_period, class: 'form-control'
.form-group
= f.label :throttle_unauthenticated_period_in_seconds, 'Rate limit period in seconds', class: 'label-light'
= f.label :throttle_unauthenticated_period_in_seconds, 'Rate limit period in seconds', class: 'label-bold'
= f.number_field :throttle_unauthenticated_period_in_seconds, class: 'form-control'
.form-group
.form-check
......@@ -23,10 +23,10 @@
%span.form-text.text-muted
Helps reduce request volume (e.g. from crawlers or abusive bots)
.form-group
= f.label :throttle_authenticated_api_requests_per_period, 'Max requests per period per user', class: 'label-light'
= f.label :throttle_authenticated_api_requests_per_period, 'Max requests per period per user', class: 'label-bold'
= f.number_field :throttle_authenticated_api_requests_per_period, class: 'form-control'
.form-group
= f.label :throttle_authenticated_api_period_in_seconds, 'Rate limit period in seconds', class: 'label-light'
= f.label :throttle_authenticated_api_period_in_seconds, 'Rate limit period in seconds', class: 'label-bold'
= f.number_field :throttle_authenticated_api_period_in_seconds, class: 'form-control'
.form-group
.form-check
......@@ -36,10 +36,10 @@
%span.form-text.text-muted
Helps reduce request volume (e.g. from crawlers or abusive bots)
.form-group
= f.label :throttle_authenticated_web_requests_per_period, 'Max requests per period per user', class: 'label-light'
= f.label :throttle_authenticated_web_requests_per_period, 'Max requests per period per user', class: 'label-bold'
= f.number_field :throttle_authenticated_web_requests_per_period, class: 'form-control'
.form-group
= f.label :throttle_authenticated_web_period_in_seconds, 'Rate limit period in seconds', class: 'label-light'
= f.label :throttle_authenticated_web_period_in_seconds, 'Rate limit period in seconds', class: 'label-bold'
= f.number_field :throttle_authenticated_web_period_in_seconds, class: 'form-control'
= f.submit 'Save changes', class: "btn btn-success"
......@@ -10,7 +10,7 @@
.form-text.text-muted
Koding integration has been deprecated since GitLab 10.0. If you disable your Koding integration, you will not be able to enable it again.
.form-group
= f.label :koding_url, 'Koding URL', class: 'label-light'
= f.label :koding_url, 'Koding URL', class: 'label-bold'
= f.text_field :koding_url, class: 'form-control', placeholder: 'http://gitlab.your-koding-instance.com:8090'
.form-text.text-muted
Koding has integration enabled out of the box for the
......
......@@ -13,7 +13,7 @@
%a{ href: 'https://getsentry.com', target: '_blank', rel: 'noopener noreferrer' } https://getsentry.com
.form-group
= f.label :sentry_dsn, 'Sentry DSN', class: 'label-light'
= f.label :sentry_dsn, 'Sentry DSN', class: 'label-bold'
= f.text_field :sentry_dsn, class: 'form-control'
.form-group
......@@ -26,7 +26,7 @@
%a{ href: 'https://sentry.io/for/javascript/', target: '_blank', rel: 'noopener noreferrer' } https://sentry.io/for/javascript/
.form-group
= f.label :clientside_sentry_dsn, 'Clientside Sentry DSN', class: 'label-light'
= f.label :clientside_sentry_dsn, 'Clientside Sentry DSN', class: 'label-bold'
= f.text_field :clientside_sentry_dsn, class: 'form-control'
= f.submit 'Save changes', class: "btn btn-success"
......@@ -3,7 +3,7 @@
%fieldset
.form-group
= f.label :max_pages_size, 'Maximum size of pages (MB)', class: 'label-light'
= f.label :max_pages_size, 'Maximum size of pages (MB)', class: 'label-bold'
= f.number_field :max_pages_size, class: 'form-control'
.form-text.text-muted 0 for unlimited
.form-group
......
......@@ -8,7 +8,7 @@
= f.label :performance_bar_enabled, class: 'form-check-label' do
Enable the Performance Bar
.form-group
= f.label :performance_bar_allowed_group_path, 'Allowed group', class: 'label-light'
= f.label :performance_bar_allowed_group_path, 'Allowed group', class: 'label-bold'
= f.text_field :performance_bar_allowed_group_path, class: 'form-control', placeholder: 'my-org/my-group', value: @application_setting.performance_bar_allowed_group&.full_path
= f.submit 'Save changes', class: "btn btn-success"
......@@ -8,7 +8,7 @@
= f.label :plantuml_enabled, class: 'form-check-label' do
Enable PlantUML
.form-group
= f.label :plantuml_url, 'PlantUML URL', class: 'label-light'
= f.label :plantuml_url, 'PlantUML URL', class: 'label-bold'
= f.text_field :plantuml_url, class: 'form-control', placeholder: 'http://gitlab.your-plantuml-instance.com:8080'
.form-text.text-muted
Allow rendering of
......
......@@ -3,7 +3,7 @@
%fieldset
.form-group
= f.label :polling_interval_multiplier, 'Polling interval multiplier', class: 'label-light'
= f.label :polling_interval_multiplier, 'Polling interval multiplier', class: 'label-bold'
= f.text_field :polling_interval_multiplier, class: 'form-control'
.form-text.text-muted
Change this value to influence how frequently the GitLab UI polls for updates.
......
......@@ -3,7 +3,7 @@
%fieldset
.form-group
= f.label :container_registry_token_expire_delay, 'Authorization token duration (minutes)', class: 'label-light'
= f.label :container_registry_token_expire_delay, 'Authorization token duration (minutes)', class: 'label-bold'
= f.number_field :container_registry_token_expire_delay, class: 'form-control'
= f.submit 'Save changes', class: "btn btn-success"
......@@ -38,17 +38,17 @@
Creating pack file bitmaps makes housekeeping take a little longer but
bitmaps should accelerate 'git clone' performance.
.form-group
= f.label :housekeeping_incremental_repack_period, 'Incremental repack period', class: 'label-light'
= f.label :housekeeping_incremental_repack_period, 'Incremental repack period', class: 'label-bold'
= f.number_field :housekeeping_incremental_repack_period, class: 'form-control'
.form-text.text-muted
Number of Git pushes after which an incremental 'git repack' is run.
.form-group
= f.label :housekeeping_full_repack_period, 'Full repack period', class: 'label-light'
= f.label :housekeeping_full_repack_period, 'Full repack period', class: 'label-bold'
= f.number_field :housekeeping_full_repack_period, class: 'form-control'
.form-text.text-muted
Number of Git pushes after which a full 'git repack' is run.
.form-group
= f.label :housekeeping_gc_period, 'Git GC period', class: 'label-light'
= f.label :housekeeping_gc_period, 'Git GC period', class: 'label-bold'
= f.number_field :housekeeping_gc_period, class: 'form-control'
.form-text.text-muted
Number of Git pushes after which 'git gc' is run.
......
......@@ -3,7 +3,7 @@
%fieldset
.form-group
= f.label :mirror_available, 'Enable mirror configuration', class: 'label-light'
= f.label :mirror_available, 'Enable mirror configuration', class: 'label-bold'
.form-check
= f.check_box :mirror_available, class: 'form-check-input'
= f.label :mirror_available, class: 'form-check-label' do
......
......@@ -13,7 +13,7 @@
repositories from having to be moved or renamed when the Project URL changes and may improve disk I/O performance.
%em (EXPERIMENTAL)
.form-group
= f.label :repository_storages, 'Storage paths for new projects', class: 'label-light'
= f.label :repository_storages, 'Storage paths for new projects', class: 'label-bold'
= f.select :repository_storages, repository_storages_options_for_select(@application_setting.repository_storages),
{include_hidden: false}, multiple: true, class: 'form-control'
.form-text.text-muted
......@@ -23,27 +23,27 @@
.sub-section
%h4 Circuit breaker
.form-group
= f.label :circuitbreaker_check_interval, _('Check interval'), class: 'label-light'
= f.label :circuitbreaker_check_interval, _('Check interval'), class: 'label-bold'
= f.number_field :circuitbreaker_check_interval, class: 'form-control'
.form-text.text-muted
= circuitbreaker_check_interval_help_text
.form-group
= f.label :circuitbreaker_access_retries, _('Number of access attempts'), class: 'label-light'
= f.label :circuitbreaker_access_retries, _('Number of access attempts'), class: 'label-bold'
= f.number_field :circuitbreaker_access_retries, class: 'form-control'
.form-text.text-muted
= circuitbreaker_access_retries_help_text
.form-group
= f.label :circuitbreaker_storage_timeout, _('Seconds to wait for a storage access attempt'), class: 'label-light'
= f.label :circuitbreaker_storage_timeout, _('Seconds to wait for a storage access attempt'), class: 'label-bold'
= f.number_field :circuitbreaker_storage_timeout, class: 'form-control'
.form-text.text-muted
= circuitbreaker_storage_timeout_help_text
.form-group
= f.label :circuitbreaker_failure_count_threshold, _('Maximum git storage failures'), class: 'label-light'
= f.label :circuitbreaker_failure_count_threshold, _('Maximum git storage failures'), class: 'label-bold'
= f.number_field :circuitbreaker_failure_count_threshold, class: 'form-control'
.form-text.text-muted
= circuitbreaker_failure_count_help_text
.form-group
= f.label :circuitbreaker_failure_reset_time, _('Seconds before reseting failure information'), class: 'label-light'
= f.label :circuitbreaker_failure_reset_time, _('Seconds before reseting failure information'), class: 'label-bold'
= f.number_field :circuitbreaker_failure_reset_time, class: 'form-control'
.form-text.text-muted
= circuitbreaker_failure_reset_time_help_text
......
......@@ -21,31 +21,31 @@
must be used to authenticate.
- if omniauth_enabled? && button_based_providers.any?
.form-group
= f.label :enabled_oauth_sign_in_sources, 'Enabled OAuth sign-in sources', class: 'label-light'
= f.label :enabled_oauth_sign_in_sources, 'Enabled OAuth sign-in sources', class: 'label-bold'
= hidden_field_tag 'application_setting[enabled_oauth_sign_in_sources][]'
.btn-group{ data: { toggle: 'buttons' } }
- oauth_providers_checkboxes.each do |source|
= source
.form-group
= f.label :two_factor_authentication, 'Two-factor authentication', class: 'label-light'
= f.label :two_factor_authentication, 'Two-factor authentication', class: 'label-bold'
.form-check
= f.check_box :require_two_factor_authentication, class: 'form-check-input'
= f.label :require_two_factor_authentication, class: 'form-check-label' do
Require all users to setup Two-factor authentication
.form-group
= f.label :two_factor_authentication, 'Two-factor grace period (hours)', class: 'label-light'
= f.label :two_factor_authentication, 'Two-factor grace period (hours)', class: 'label-bold'
= f.number_field :two_factor_grace_period, min: 0, class: 'form-control', placeholder: '0'
.form-text.text-muted Amount of time (in hours) that users are allowed to skip forced configuration of two-factor authentication
.form-group
= f.label :home_page_url, 'Home page URL', class: 'label-light'
= f.label :home_page_url, 'Home page URL', class: 'label-bold'
= f.text_field :home_page_url, class: 'form-control', placeholder: 'http://company.example.com', :'aria-describedby' => 'home_help_block'
%span.form-text.text-muted#home_help_block We will redirect non-logged in users to this page
.form-group
= f.label :after_sign_out_path, class: 'label-light'
= f.label :after_sign_out_path, class: 'label-bold'
= f.text_field :after_sign_out_path, class: 'form-control', placeholder: 'http://company.example.com', :'aria-describedby' => 'after_sign_out_path_help_block'
%span.form-text.text-muted#after_sign_out_path_help_block We will redirect users to this page after they sign out
.form-group
= f.label :sign_in_text, class: 'label-light'
= f.label :sign_in_text, class: 'label-bold'
= f.text_area :sign_in_text, class: 'form-control', rows: 4
.form-text.text-muted Markdown enabled
......
......@@ -13,11 +13,11 @@
= f.label :send_user_confirmation_email, class: 'form-check-label' do
Send confirmation email on sign-up
.form-group
= f.label :domain_whitelist, 'Whitelisted domains for sign-ups', class: 'label-light'
= f.label :domain_whitelist, 'Whitelisted domains for sign-ups', class: 'label-bold'
= f.text_area :domain_whitelist_raw, placeholder: 'domain.com', class: 'form-control', rows: 8
.form-text.text-muted ONLY users with e-mail addresses that match these domain(s) will be able to sign-up. Wildcards allowed. Use separate lines for multiple entries. Ex: domain.com, *.domain.com
.form-group
= f.label :domain_blacklist_enabled, 'Domain Blacklist', class: 'label-light'
= f.label :domain_blacklist_enabled, 'Domain Blacklist', class: 'label-bold'
.form-check
= f.check_box :domain_blacklist_enabled, class: 'form-check-input'
= f.label :domain_blacklist_enabled, class: 'form-check-label' do
......@@ -34,16 +34,16 @@
.option-title
Enter blacklist manually
.form-group.blacklist-file
= f.label :domain_blacklist_file, 'Blacklist file', class: 'label-light'
= f.label :domain_blacklist_file, 'Blacklist file', class: 'label-bold'
= f.file_field :domain_blacklist_file, class: 'form-control', accept: '.txt,.conf'
.form-text.text-muted Users with e-mail addresses that match these domain(s) will NOT be able to sign-up. Wildcards allowed. Use separate lines or commas for multiple entries.
.form-group.blacklist-raw
= f.label :domain_blacklist, 'Blacklisted domains for sign-ups', class: 'label-light'
= f.label :domain_blacklist, 'Blacklisted domains for sign-ups', class: 'label-bold'
= f.text_area :domain_blacklist_raw, placeholder: 'domain.com', class: 'form-control', rows: 8
.form-text.text-muted Users with e-mail addresses that match these domain(s) will NOT be able to sign-up. Wildcards allowed. Use separate lines for multiple entries. Ex: domain.com, *.domain.com
.form-group
= f.label :after_sign_up_text, class: 'label-light'
= f.label :after_sign_up_text, class: 'label-bold'
= f.text_area :after_sign_up_text, class: 'form-control', rows: 4
.form-text.text-muted Markdown enabled
......
......@@ -10,14 +10,14 @@
%span.form-text.text-muted#recaptcha_help_block Helps prevent bots from creating accounts
.form-group
= f.label :recaptcha_site_key, 'reCAPTCHA Site Key', class: 'label-light'
= f.label :recaptcha_site_key, 'reCAPTCHA Site Key', class: 'label-bold'
= f.text_field :recaptcha_site_key, class: 'form-control'
.form-text.text-muted
Generate site and private keys at
%a{ href: 'http://www.google.com/recaptcha', target: 'blank' } http://www.google.com/recaptcha
.form-group
= f.label :recaptcha_private_key, 'reCAPTCHA Private Key', class: 'label-light'
= f.label :recaptcha_private_key, 'reCAPTCHA Private Key', class: 'label-bold'
= f.text_field :recaptcha_private_key, class: 'form-control'
.form-group
......@@ -28,7 +28,7 @@
%span.form-text.text-muted#akismet_help_block Helps prevent bots from creating issues
.form-group
= f.label :akismet_api_key, 'Akismet API Key', class: 'label-light'
= f.label :akismet_api_key, 'Akismet API Key', class: 'label-bold'
= f.text_field :akismet_api_key, class: 'form-control'
.form-text.text-muted
Generate API key at
......@@ -43,13 +43,13 @@
Helps prevent malicious users hide their activity
.form-group
= f.label :unique_ips_limit_per_user, 'IPs per user', class: 'label-light'
= f.label :unique_ips_limit_per_user, 'IPs per user', class: 'label-bold'
= f.number_field :unique_ips_limit_per_user, class: 'form-control'
.form-text.text-muted
Maximum number of unique IPs per user
.form-group
= f.label :unique_ips_limit_time_window, 'IP expiration time', class: 'label-light'
= f.label :unique_ips_limit_time_window, 'IP expiration time', class: 'label-bold'
= f.number_field :unique_ips_limit_time_window, class: 'form-control'
.form-text.text-muted
How many seconds an IP will be counted towards the limit
......
......@@ -3,7 +3,7 @@
%fieldset
.form-group
= f.label :terminal_max_session_time, 'Max session time', class: 'label-light'
= f.label :terminal_max_session_time, 'Max session time', class: 'label-bold'
= f.number_field :terminal_max_session_time, class: 'form-control'
.form-text.text-muted
Maximum time for web terminal websocket connection (in seconds).
......
......@@ -3,19 +3,19 @@
%fieldset
.form-group
= f.label :default_branch_protection, class: 'label-light'
= f.label :default_branch_protection, class: 'label-bold'
= f.select :default_branch_protection, options_for_select(Gitlab::Access.protection_options, @application_setting.default_branch_protection), {}, class: 'form-control'
.form-group.visibility-level-setting
= f.label :default_project_visibility, class: 'label-light'
= f.label :default_project_visibility, class: 'label-bold'
= render('shared/visibility_radios', model_method: :default_project_visibility, form: f, selected_level: @application_setting.default_project_visibility, form_model: Project.new)
.form-group.visibility-level-setting
= f.label :default_snippet_visibility, class: 'label-light'
= f.label :default_snippet_visibility, class: 'label-bold'
= render('shared/visibility_radios', model_method: :default_snippet_visibility, form: f, selected_level: @application_setting.default_snippet_visibility, form_model: ProjectSnippet.new)
.form-group.visibility-level-setting
= f.label :default_group_visibility, class: 'label-light'
= f.label :default_group_visibility, class: 'label-bold'
= render('shared/visibility_radios', model_method: :default_group_visibility, form: f, selected_level: @application_setting.default_group_visibility, form_model: Group.new)
.form-group
= f.label :restricted_visibility_levels, class: 'label-light'
= f.label :restricted_visibility_levels, class: 'label-bold'
- checkbox_name = 'application_setting[restricted_visibility_levels][]'
= hidden_field_tag(checkbox_name)
- restricted_level_checkboxes('restricted-visibility-help', checkbox_name, class: 'form-check-input').each do |level|
......@@ -25,7 +25,7 @@
Selected levels cannot be used by non-admin users for groups, projects or snippets.
If the public level is restricted, user profiles are only visible to logged in users.
.form-group
= f.label :import_sources, class: 'label-light'
= f.label :import_sources, class: 'label-bold'
= hidden_field_tag 'application_setting[import_sources][]'
- import_sources_checkboxes('import-sources-help', class: 'form-check-input').each do |source|
.form-check= source
......@@ -44,7 +44,7 @@
Project export enabled
.form-group
%label.label-light Enabled Git access protocols
%label.label-bold Enabled Git access protocols
= select(:application_setting, :enabled_git_access_protocol, [['Both SSH and HTTP(S)', nil], ['Only SSH', 'ssh'], ['Only HTTP(S)', 'http']], {}, class: 'form-control')
%span.form-text.text-muted#clone-protocol-help
Allow only the selected protocols to be used for Git access.
......@@ -52,7 +52,7 @@
- ApplicationSetting::SUPPORTED_KEY_TYPES.each do |type|
- field_name = :"#{type}_key_restriction"
.form-group
= f.label field_name, "#{type.upcase} SSH keys", class: 'label-light'
= f.label field_name, "#{type.upcase} SSH keys", class: 'label-bold'
= f.select field_name, key_restriction_options_for_select(type), {}, class: 'form-control'
= f.submit 'Save changes', class: "btn btn-success"
= form_errors(hook)
.form-group
= form.label :url, 'URL', class: 'label-light'
= form.label :url, 'URL', class: 'label-bold'
= form.text_field :url, class: 'form-control'
.form-group
= form.label :token, 'Secret Token', class: 'label-light'
= form.label :token, 'Secret Token', class: 'label-bold'
= form.text_field :token, class: 'form-control'
%p.form-text.text-muted
Use this token to validate received payloads
.form-group
= form.label :url, 'Trigger', class: 'label-light'
= form.label :url, 'Trigger', class: 'label-bold'
%ul.list-unstyled
%li
.form-text.text-muted
......@@ -45,7 +45,7 @@
%p.light
This URL will be triggered when a merge request is created/updated/merged
.form-group
= form.label :enable_ssl_verification, 'SSL verification', class: 'label-light checkbox'
= form.label :enable_ssl_verification, 'SSL verification', class: 'label-bold checkbox'
.form-check
= form.check_box :enable_ssl_verification, class: 'form-check-input'
= form.label :enable_ssl_verification, class: 'form-check-label' do
......
......@@ -2,11 +2,11 @@
= form_errors(application)
.form-group
= f.label :name, class: 'label-light'
= f.label :name, class: 'label-bold'
= f.text_field :name, class: 'form-control', required: true
.form-group
= f.label :redirect_uri, class: 'label-light'
= f.label :redirect_uri, class: 'label-bold'
= f.text_area :redirect_uri, class: 'form-control', required: true
%span.form-text.text-muted
......@@ -16,7 +16,7 @@
= _('Use <code>%{native_redirect_uri}</code> for local tests').html_safe % { native_redirect_uri: Doorkeeper.configuration.native_redirect_uri }
.form-group
= f.label :scopes, class: 'label-light'
= f.label :scopes, class: 'label-bold'
= render 'shared/tokens/scopes_form', prefix: 'doorkeeper_application', token: application, scopes: @scopes
.prepend-top-default
......
......@@ -4,17 +4,17 @@
%fieldset
.row
.form-group.col-md-9
= f.label :name, class: 'label-light' do
= f.label :name, class: 'label-bold' do
Group name
= f.text_field :name, class: 'form-control'
.form-group.col-md-3
= f.label :id, class: 'label-light' do
= f.label :id, class: 'label-bold' do
Group ID
= f.text_field :id, class: 'form-control', readonly: true
.form-group
= f.label :description, class: 'label-light' do
= f.label :description, class: 'label-bold' do
Group description
%span.light (optional)
= f.text_area :description, class: 'form-control', rows: 3, maxlength: 250
......
......@@ -9,7 +9,7 @@
= form_tag import_gitlab_project_path, class: 'new_project', multipart: true do
.row
.form-group.col-12.col-sm-6
= label_tag :namespace_id, 'Project path', class: 'label-light'
= label_tag :namespace_id, 'Project path', class: 'label-bold'
.form-group
.input-group
- if current_user.can_select_namespace?
......@@ -24,7 +24,7 @@
#{user_url(current_user.username)}/
= hidden_field_tag :namespace_id, value: current_user.namespace_id
.form-group.col-12.col-sm-6.project-path
= label_tag :path, _('Project name'), class: 'label-light'
= label_tag :path, _('Project name'), class: 'label-bold'
= text_field_tag :path, @path, placeholder: "my-awesome-project", class: "js-path-name form-control", tabindex: 2, autofocus: true, required: true
.row
......@@ -33,7 +33,7 @@
.row
.form-group.col-sm-12
= hidden_field_tag :namespace_id, @namespace.id
= label_tag :file, _('GitLab project export'), class: 'label-light'
= label_tag :file, _('GitLab project export'), class: 'label-bold'
.form-group
= file_field_tag :file, class: ''
.row
......
= form_tag upload_import_manifest_path, multipart: true do
.form-group
= label_tag :group_id, nil, class: 'label-light' do
= label_tag :group_id, nil, class: 'label-bold' do
= _('Group')
.input-group
.input-group-prepend.has-tooltip{ title: root_url }
......@@ -11,7 +11,7 @@
= _('Choose the top-level group for your repository imports.')
.form-group
= label_tag :manifest, class: 'label-light' do
= label_tag :manifest, class: 'label-bold' do
= _('Manifest')
= file_field_tag :manifest, class: 'form-control-file', required: true
.form-text.text-muted
......
......@@ -29,7 +29,7 @@
%p
Activate signin with one of the following services
.col-lg-8
%label.label-light
%label.label-bold
Connected Accounts
%p Click on icon to activate signin with one of the following services
- button_based_providers.each do |provider|
......
......@@ -12,7 +12,7 @@
Add email address
= form_for 'email', url: profile_emails_path do |f|
.form-group
= f.label :email, class: 'label-light'
= f.label :email, class: 'label-bold'
= f.text_field :email, class: 'form-control'
.prepend-top-default
= f.submit 'Add email address', class: 'btn btn-create'
......
......@@ -3,7 +3,7 @@
= form_errors(@gpg_key)
.form-group
= f.label :key, class: 'label-light'
= f.label :key, class: 'label-bold'
= f.text_area :key, class: "form-control", rows: 8, required: true, placeholder: "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
.prepend-top-default
......
......@@ -3,11 +3,11 @@
= form_errors(@key)
.form-group
= f.label :key, class: 'label-light'
= f.label :key, class: 'label-bold'
%p= _("Paste your public SSH key, which is usually contained in the file '~/.ssh/id_rsa.pub' and begins with 'ssh-rsa'. Don't use your private SSH key.")
= f.text_area :key, class: "form-control js-add-ssh-key-validation-input", rows: 8, required: true, placeholder: s_('Profiles|Typically starts with "ssh-rsa …"')
.form-group
= f.label :title, class: 'label-light'
= f.label :title, class: 'label-bold'
= f.text_field :title, class: "form-control input-lg", required: true, placeholder: s_('Profiles|e.g. My MacBook key')
%p.form-text.text-muted= _('Name your individual key via a title')
......
......@@ -23,10 +23,10 @@
= form_for @user, url: profile_notifications_path, method: :put, html: { class: 'update-notifications prepend-top-default' } do |f|
.form-group
= f.label :notification_email, class: "label-light"
= f.label :notification_email, class: "label-bold"
= f.select :notification_email, @user.all_emails, { include_blank: false }, class: "select2"
= label_tag :global_notification_level, "Global notification level", class: "label-light"
= label_tag :global_notification_level, "Global notification level", class: "label-bold"
%br
.clearfix
.form-group.float-left.global-notification-setting
......
......@@ -18,15 +18,15 @@
- unless @user.password_automatically_set?
.form-group
= f.label :current_password, class: 'label-light'
= f.label :current_password, class: 'label-bold'
= f.password_field :current_password, required: true, class: 'form-control'
%p.form-text.text-muted
You must provide your current password in order to change it.
.form-group
= f.label :password, 'New password', class: 'label-light'
= f.label :password, 'New password', class: 'label-bold'
= f.password_field :password, required: true, class: 'form-control'
.form-group
= f.label :password_confirmation, class: 'label-light'
= f.label :password_confirmation, class: 'label-bold'
= f.password_field :password_confirmation, required: true, class: 'form-control'
.prepend-top-default.append-bottom-default
= f.submit 'Save password', class: "btn btn-create append-right-10"
......
......@@ -40,7 +40,7 @@
%p
It cannot be used to access any other data.
.col-lg-8.feed-token-reset
= label_tag :feed_token, 'Feed token', class: "label-light"
= label_tag :feed_token, 'Feed token', class: "label-bold"
= text_field_tag :feed_token, current_user.feed_token, class: 'form-control', readonly: true, onclick: 'this.select()'
%p.form-text.text-muted
Keep this token secret. Anyone who gets ahold of it can read activity and issue RSS feeds or your calendar feed as if they were you.
......@@ -59,7 +59,7 @@
%p
It cannot be used to access any other data.
.col-lg-8.incoming-email-token-reset
= label_tag :incoming_email_token, 'Incoming email token', class: "label-light"
= label_tag :incoming_email_token, 'Incoming email token', class: "label-bold"
= text_field_tag :incoming_email_token, current_user.incoming_email_token, class: 'form-control', readonly: true, onclick: 'this.select()'
%p.form-text.text-muted
Keep this token secret. Anyone who gets ahold of it can create issues as if they were you.
......
......@@ -42,17 +42,17 @@
= link_to 'Learn more', help_page_path('user/profile/preferences', anchor: 'behavior'), target: '_blank'
.col-lg-8
.form-group
= f.label :layout, class: 'label-light' do
= f.label :layout, class: 'label-bold' do
Layout width
= f.select :layout, layout_choices, {}, class: 'form-control'
.form-text.text-muted
Choose between fixed (max. 1200px) and fluid (100%) application layout.
.form-group
= f.label :dashboard, class: 'label-light' do
= f.label :dashboard, class: 'label-bold' do
Default dashboard
= f.select :dashboard, dashboard_choices, {}, class: 'form-control'
.form-group
= f.label :project_view, class: 'label-light' do
= f.label :project_view, class: 'label-bold' do
Project overview content
= f.select :project_view, project_view_choices, {}, class: 'form-control'
.form-text.text-muted
......
......@@ -49,7 +49,7 @@
.alert.alert-danger
= @error
.form-group
= label_tag :pin_code, nil, class: "label-light"
= label_tag :pin_code, nil, class: "label-bold"
= text_field_tag :pin_code, nil, class: "form-control", required: true
.prepend-top-default
= submit_tag 'Register with two-factor app', class: 'btn btn-success'
......
......@@ -2,7 +2,7 @@
- project = local_assigns.fetch(:project)
.form-group
= label_tag :merge_method_merge, class: 'label-light' do
= label_tag :merge_method_merge, class: 'label-bold' do
Merge method
.form-check
= form.radio_button :merge_method, :merge, class: "js-merge-method-radio form-check-input"
......
......@@ -4,7 +4,7 @@
.row{ id: project_name_id }
= f.hidden_field :ci_cd_only, value: ci_cd_only
.form-group.project-path.col-sm-6
= f.label :namespace_id, class: 'label-light' do
= f.label :namespace_id, class: 'label-bold' do
%span
Project path
.input-group
......@@ -20,7 +20,7 @@
#{user_url(current_user.username)}/
= f.hidden_field :namespace_id, value: current_user.namespace_id
.form-group.project-path.col-sm-6
= f.label :path, class: 'label-light' do
= f.label :path, class: 'label-bold' do
%span
Project name
= f.text_field :path, placeholder: "my-awesome-project", class: "form-control", tabindex: 2, autofocus: true, required: true
......@@ -30,12 +30,12 @@
= link_to "Create a group", new_group_path
.form-group
= f.label :description, class: 'label-light' do
= f.label :description, class: 'label-bold' do
Project description
%span (optional)
= f.text_area :description, placeholder: 'Description format', class: "form-control", rows: 3, maxlength: 250
= f.label :visibility_level, class: 'label-light' do
= f.label :visibility_level, class: 'label-bold' do
Visibility Level
= link_to icon('question-circle'), help_page_path("public_access/public_access"), aria: { label: 'Documentation for Visibility Level' }, target: '_blank', rel: 'noopener noreferrer'
= render 'shared/visibility_level', f: f, visibility_level: visibility_level.to_i, can_change_visibility_level: true, form_model: @project, with_label: false
......
......@@ -12,7 +12,7 @@
.project-fields-form
.row
.form-group.col-sm-12
%label.label-light
%label.label-bold
Template
.input-group.template-input-group
.input-group-prepend
......
......@@ -27,6 +27,6 @@
.btn-group{ role: "group" }<
= copy_blob_source_button(blob)
= open_raw_blob_button(blob)
= download_blob_button(blob)
= render 'projects/blob/content', blob: blob
......@@ -8,8 +8,8 @@
.btn-group{ role: "group" }<
= copy_blob_source_button(blob) unless blame
= open_raw_blob_button(blob)
= download_blob_button(blob)
= view_on_environment_button(@commit.sha, @path, @environment) if @environment
.btn-group{ role: "group" }<
= render_if_exists 'projects/blob/header_file_locks_link'
= edit_blob_button
......
......@@ -15,15 +15,15 @@
= form_for @gcp_cluster, html: { class: 'js-gke-cluster-creation prepend-top-20', data: { token: token_in_session } }, url: create_gcp_namespace_project_clusters_path(@project.namespace, @project), as: :cluster do |field|
= form_errors(@gcp_cluster)
.form-group
= field.label :name, s_('ClusterIntegration|Kubernetes cluster name'), class: 'label-light'
= field.label :name, s_('ClusterIntegration|Kubernetes cluster name'), class: 'label-bold'
= field.text_field :name, class: 'form-control', placeholder: s_('ClusterIntegration|Kubernetes cluster name')
.form-group
= field.label :environment_scope, s_('ClusterIntegration|Environment scope'), class: 'label-light'
= field.label :environment_scope, s_('ClusterIntegration|Environment scope'), class: 'label-bold'
= field.text_field :environment_scope, class: 'form-control', readonly: !has_multiple_clusters?(@project), placeholder: s_('ClusterIntegration|Environment scope')
= field.fields_for :provider_gcp, @gcp_cluster.provider_gcp do |provider_gcp_field|
.form-group
= provider_gcp_field.label :gcp_project_id, s_('ClusterIntegration|Google Cloud Platform project'), class: 'label-light'
= provider_gcp_field.label :gcp_project_id, s_('ClusterIntegration|Google Cloud Platform project'), class: 'label-bold'
.js-gcp-project-id-dropdown-entry-point{ data: { docsUrl: 'https://console.cloud.google.com/home/dashboard' } }
= provider_gcp_field.hidden_field :gcp_project_id
.dropdown
......@@ -34,7 +34,7 @@
%span.form-text.text-muted &nbsp;
.form-group
= provider_gcp_field.label :zone, s_('ClusterIntegration|Zone'), class: 'label-light'
= provider_gcp_field.label :zone, s_('ClusterIntegration|Zone'), class: 'label-bold'
.js-gcp-zone-dropdown-entry-point
= provider_gcp_field.hidden_field :zone
.dropdown
......@@ -46,11 +46,11 @@
= s_('ClusterIntegration|Learn more about %{help_link_start}zones%{help_link_end}.').html_safe % { help_link_start: help_link_start % { url: zones_link_url }, help_link_end: help_link_end }
.form-group
= provider_gcp_field.label :num_nodes, s_('ClusterIntegration|Number of nodes'), class: 'label-light'
= provider_gcp_field.label :num_nodes, s_('ClusterIntegration|Number of nodes'), class: 'label-bold'
= provider_gcp_field.text_field :num_nodes, class: 'form-control', placeholder: '3'
.form-group
= provider_gcp_field.label :machine_type, s_('ClusterIntegration|Machine type'), class: 'label-light'
= provider_gcp_field.label :machine_type, s_('ClusterIntegration|Machine type'), class: 'label-bold'
.js-gcp-machine-type-dropdown-entry-point
= provider_gcp_field.hidden_field :machine_type
.dropdown
......
= form_for @user_cluster, url: create_user_namespace_project_clusters_path(@project.namespace, @project), as: :cluster do |field|
= form_errors(@user_cluster)
.form-group
= field.label :name, s_('ClusterIntegration|Kubernetes cluster name'), class: 'label-light'
= field.label :name, s_('ClusterIntegration|Kubernetes cluster name'), class: 'label-bold'
= field.text_field :name, class: 'form-control', placeholder: s_('ClusterIntegration|Kubernetes cluster name')
- if has_multiple_clusters?(@project)
.form-group
= field.label :environment_scope, s_('ClusterIntegration|Environment scope'), class: 'label-light'
= field.label :environment_scope, s_('ClusterIntegration|Environment scope'), class: 'label-bold'
= field.text_field :environment_scope, class: 'form-control', placeholder: s_('ClusterIntegration|Environment scope')
= field.fields_for :platform_kubernetes, @user_cluster.platform_kubernetes do |platform_kubernetes_field|
.form-group
= platform_kubernetes_field.label :api_url, s_('ClusterIntegration|API URL'), class: 'label-light'
= platform_kubernetes_field.label :api_url, s_('ClusterIntegration|API URL'), class: 'label-bold'
= platform_kubernetes_field.text_field :api_url, class: 'form-control', placeholder: s_('ClusterIntegration|API URL')
.form-group
= platform_kubernetes_field.label :ca_cert, s_('ClusterIntegration|CA Certificate'), class: 'label-light'
= platform_kubernetes_field.label :ca_cert, s_('ClusterIntegration|CA Certificate'), class: 'label-bold'
= platform_kubernetes_field.text_area :ca_cert, class: 'form-control', placeholder: s_('ClusterIntegration|Certificate Authority bundle (PEM format)')
.form-group
= platform_kubernetes_field.label :token, s_('ClusterIntegration|Token'), class: 'label-light'
= platform_kubernetes_field.label :token, s_('ClusterIntegration|Token'), class: 'label-bold'
= platform_kubernetes_field.text_field :token, class: 'form-control', placeholder: s_('ClusterIntegration|Service token'), autocomplete: 'off'
.form-group
= platform_kubernetes_field.label :namespace, s_('ClusterIntegration|Project namespace (optional, unique)'), class: 'label-light'
= platform_kubernetes_field.label :namespace, s_('ClusterIntegration|Project namespace (optional, unique)'), class: 'label-bold'
= platform_kubernetes_field.text_field :namespace, class: 'form-control', placeholder: s_('ClusterIntegration|Project namespace')
.form-group
......
= form_for @cluster, url: namespace_project_cluster_path(@project.namespace, @project, @cluster), as: :cluster do |field|
= form_errors(@cluster)
.form-group
= field.label :name, s_('ClusterIntegration|Kubernetes cluster name'), class: 'label-light'
= field.label :name, s_('ClusterIntegration|Kubernetes cluster name'), class: 'label-bold'
= field.text_field :name, class: 'form-control', placeholder: s_('ClusterIntegration|Kubernetes cluster name')
= field.fields_for :platform_kubernetes, @cluster.platform_kubernetes do |platform_kubernetes_field|
.form-group
= platform_kubernetes_field.label :api_url, s_('ClusterIntegration|API URL'), class: 'label-light'
= platform_kubernetes_field.label :api_url, s_('ClusterIntegration|API URL'), class: 'label-bold'
= platform_kubernetes_field.text_field :api_url, class: 'form-control', placeholder: s_('ClusterIntegration|API URL')
.form-group
= platform_kubernetes_field.label :ca_cert, s_('ClusterIntegration|CA Certificate'), class: 'label-light'
= platform_kubernetes_field.label :ca_cert, s_('ClusterIntegration|CA Certificate'), class: 'label-bold'
= platform_kubernetes_field.text_area :ca_cert, class: 'form-control', placeholder: s_('ClusterIntegration|Certificate Authority bundle (PEM format)')
.form-group
= platform_kubernetes_field.label :token, s_('ClusterIntegration|Token'), class: 'label-light'
= platform_kubernetes_field.label :token, s_('ClusterIntegration|Token'), class: 'label-bold'
.input-group
= platform_kubernetes_field.text_field :token, class: 'form-control js-cluster-token', type: 'password', placeholder: s_('ClusterIntegration|Token'), autocomplete: 'off'
%span.input-group-append.clipboard-addon
......@@ -23,7 +23,7 @@
= s_('ClusterIntegration|Show')
.form-group
= platform_kubernetes_field.label :namespace, s_('ClusterIntegration|Project namespace (optional, unique)'), class: 'label-light'
= platform_kubernetes_field.label :namespace, s_('ClusterIntegration|Project namespace (optional, unique)'), class: 'label-bold'
= platform_kubernetes_field.text_field :namespace, class: 'form-control', placeholder: s_('ClusterIntegration|Project namespace')
.form-group
......
......@@ -23,7 +23,7 @@
%p= description
= form_tag [type.underscore, @project.namespace.becomes(Namespace), @project, commit], method: :post, remote: false, class: "js-#{type}-form js-requires-input" do
.form-group.branch
= label_tag 'start_branch', branch_label, class: 'label-light'
= label_tag 'start_branch', branch_label, class: 'label-bold'
= hidden_field_tag :start_branch, @project.default_branch, id: 'start_branch'
= dropdown_tag(@project.default_branch, options: { title: s_("BranchSwitcherTitle|Switch branch"), filter: true, placeholder: s_("BranchSwitcherPlaceholder|Search branches"), toggle_class: 'js-project-refs-dropdown dynamic', dropdown_class: 'dropdown-menu-selectable', data: { field_name: "start_branch", selected: @project.default_branch, start_branch: @project.default_branch, refs_url: project_branches_path(@project), submit_form_on_click: false } })
......
= form_for [@project.namespace.becomes(Namespace), @project, @deploy_keys.new_key], url: namespace_project_deploy_keys_path, html: { class: "js-requires-input container" } do |f|
= form_errors(@deploy_keys.new_key)
.form-group.row
= f.label :title, class: "label-light"
= f.label :title, class: "label-bold"
= f.text_field :title, class: 'form-control', required: true
.form-group.row
= f.label :key, class: "label-light"
= f.label :key, class: "label-bold"
= f.text_area :key, class: "form-control", rows: 5, required: true
.form-group.row
%p.light.append-bottom-0
......
......@@ -5,24 +5,24 @@
= form_errors(token)
.form-group
= f.label :name, class: 'label-light'
= f.label :name, class: 'label-bold'
= f.text_field :name, class: 'form-control', required: true
.form-group
= f.label :expires_at, class: 'label-light'
= f.label :expires_at, class: 'label-bold'
= f.text_field :expires_at, class: 'datepicker form-control', value: f.object.expires_at
.form-group
= f.label :scopes, class: 'label-light'
= f.label :scopes, class: 'label-bold'
%fieldset.form-group.form-check
= f.check_box :read_repository, class: 'form-check-input'
= label_tag ("deploy_token_read_repository"), 'read_repository', class: 'label-light form-check-label'
= label_tag ("deploy_token_read_repository"), 'read_repository', class: 'label-bold form-check-label'
.text-secondary= s_('DeployTokens|Allows read-only access to the repository')
- if container_registry_enabled?(project)
%fieldset.form-group.form-check
= f.check_box :read_registry, class: 'form-check-input'
= label_tag ("deploy_token_read_registry"), 'read_registry', class: 'label-light form-check-label'
= label_tag ("deploy_token_read_registry"), 'read_registry', class: 'label-bold form-check-label'
.text-secondary= s_('DeployTokens|Allows read-only access to the registry images')
.prepend-top-default
......
......@@ -18,17 +18,17 @@
%fieldset
.row
.form-group.col-md-9
= f.label :name, class: 'label-light', for: 'project_name_edit' do
= f.label :name, class: 'label-bold', for: 'project_name_edit' do
Project name
= f.text_field :name, class: "form-control", id: "project_name_edit"
.form-group.col-md-3
= f.label :id, class: 'label-light' do
= f.label :id, class: 'label-bold' do
Project ID
= f.text_field :id, class: 'form-control', readonly: true
.form-group
= f.label :description, class: 'label-light' do
= f.label :description, class: 'label-bold' do
Project description
%span.light (optional)
= f.text_area :description, class: "form-control", rows: 3, maxlength: 250
......@@ -37,13 +37,13 @@
- unless @project.empty_repo?
.form-group
= f.label :default_branch, "Default Branch", class: 'label-light'
= f.label :default_branch, "Default Branch", class: 'label-bold'
= f.select(:default_branch, @project.repository.branch_names, {}, {class: 'select2 select-wide'})
= render_if_exists 'shared/repository_size_limit_setting', form: f, type: :project
.form-group
= f.label :tag_list, "Tags", class: 'label-light'
= f.label :tag_list, "Tags", class: 'label-bold'
= f.text_field :tag_list, value: @project.tag_list.sort.join(', '), maxlength: 2000, class: "form-control"
%p.form-text.text-muted Separate tags with commas.
%fieldset.features
......@@ -144,12 +144,12 @@
= render 'projects/errors'
= form_for([@project.namespace.becomes(Namespace), @project]) do |f|
.form-group.project_name_holder
= f.label :name, class: 'label-light' do
= f.label :name, class: 'label-bold' do
Project name
.form-group
= f.text_field :name, class: "form-control"
.form-group
= f.label :path, class: 'label-light' do
= f.label :path, class: 'label-bold' do
%span Path
.form-group
.input-group
......@@ -169,7 +169,7 @@
Transfer project
= form_for([@project.namespace.becomes(Namespace), @project], url: transfer_project_path(@project), method: :put, remote: true, html: { class: 'js-project-transfer-form' } ) do |f|
.form-group
= label_tag :new_namespace_id, nil, class: 'label-light' do
= label_tag :new_namespace_id, nil, class: 'label-bold' do
%span Select a new namespace
.form-group
= select_tag :new_namespace_id, namespaces_options(nil), include_blank: true, class: 'select2'
......
......@@ -11,10 +11,10 @@
= form_errors(@environment)
.form-group
= f.label :name, 'Name', class: 'label-light'
= f.label :name, 'Name', class: 'label-bold'
= f.text_field :name, required: true, class: 'form-control'
.form-group
= f.label :external_url, 'External URL', class: 'label-light'
= f.label :external_url, 'External URL', class: 'label-bold'
= f.url_field :external_url, class: 'form-control'
.form-actions
......
......@@ -9,7 +9,7 @@
.resolve-info
= translation.html_safe
.col-md-8
%label.label-light{ "for" => "commit-message" }
%label.label-bold{ "for" => "commit-message" }
#{ _('Commit message') }
.commit-message-container
.max-width-marker
......
......@@ -32,11 +32,11 @@
.form-group
= rm_form.check_box :enabled, class: "float-left"
.prepend-left-20
= rm_form.label :enabled, "Remote mirror repository", class: "label-light append-bottom-0"
= rm_form.label :enabled, "Remote mirror repository", class: "label-bold append-bottom-0"
%p.light.append-bottom-0
Automatically update the remote mirror's branches, tags, and commits from this repository every time someone pushes to it.
.form-group.has-feedback
= rm_form.label :url, "Git repository URL", class: "label-light"
= rm_form.label :url, "Git repository URL", class: "label-bold"
= rm_form.text_field :url, class: "form-control", placeholder: 'https://username:password@gitlab.company.com/group/project.git'
= render "projects/mirrors/instructions"
......@@ -44,7 +44,7 @@
.form-group
= rm_form.check_box :only_protected_branches, class: 'float-left'
.prepend-left-20
= rm_form.label :only_protected_branches, class: 'label-light'
= rm_form.label :only_protected_branches, class: 'label-bold'
= link_to icon('question-circle'), help_page_path('user/project/protected_branches')
= f.submit 'Save changes', class: 'btn btn-create', name: 'update_remote_mirror'
......@@ -2,25 +2,25 @@
= form_errors(@schedule)
.form-group.row
.col-md-9
= f.label :description, _('Description'), class: 'label-light'
= f.label :description, _('Description'), class: 'label-bold'
= f.text_field :description, class: 'form-control', required: true, autofocus: true, placeholder: s_('PipelineSchedules|Provide a short description for this pipeline')
.form-group.row
.col-md-9
= f.label :cron, _('Interval Pattern'), class: 'label-light'
= f.label :cron, _('Interval Pattern'), class: 'label-bold'
#interval-pattern-input{ data: { initial_interval: @schedule.cron } }
.form-group.row
.col-md-9
= f.label :cron_timezone, _('Cron Timezone'), class: 'label-light'
= f.label :cron_timezone, _('Cron Timezone'), class: 'label-bold'
= dropdown_tag(_("Select a timezone"), options: { toggle_class: 'btn js-timezone-dropdown', title: _("Select a timezone"), filter: true, placeholder: s_("OfSearchInADropdown|Filter"), data: { data: timezone_data } } )
= f.text_field :cron_timezone, value: @schedule.cron_timezone, id: 'schedule_cron_timezone', class: 'hidden', name: 'schedule[cron_timezone]', required: true
.form-group.row
.col-md-9
= f.label :ref, _('Target Branch'), class: 'label-light'
= f.label :ref, _('Target Branch'), class: 'label-bold'
= dropdown_tag(_("Select target branch"), options: { toggle_class: 'btn js-target-branch-dropdown', dropdown_class: 'git-revision-dropdown', title: _("Select target branch"), filter: true, placeholder: s_("OfSearchInADropdown|Filter"), data: { data: @project.repository.branch_names, default_branch: @project.default_branch } } )
= f.text_field :ref, value: @schedule.ref, id: 'schedule_ref', class: 'hidden', name: 'schedule[ref]', required: true
.form-group.row.js-ci-variable-list-section
.col-md-9
%label.label-light
%label.label-bold
#{ s_('PipelineSchedules|Variables') }
%ul.ci-variable-list
- @schedule.variables.each do |variable|
......@@ -34,7 +34,7 @@
= n_('Reveal value', 'Reveal values', @schedule.variables.size)
.form-group.row
.col-md-9
= f.label :active, s_('PipelineSchedules|Activated'), class: 'label-light'
= f.label :active, s_('PipelineSchedules|Activated'), class: 'label-bold'
%div
= f.check_box :active, required: false, value: @schedule.active?
= _('Active')
......
......@@ -2,10 +2,10 @@
.col-sm-12
= form_for @project_member, as: :project_member, url: project_project_members_path(@project), html: { class: 'users-project-form' } do |f|
.form-group
= label_tag :user_ids, "Select members to invite", class: "label-light"
= label_tag :user_ids, "Select members to invite", class: "label-bold"
= users_select_tag(:user_ids, multiple: true, class: "input-clamp", scope: :all, email_user: true, placeholder: "Search for members to update or invite")
.form-group
= label_tag :access_level, "Choose a role permission", class: "label-light"
= label_tag :access_level, "Choose a role permission", class: "label-bold"
.select-wrapper
= select_tag :access_level, options_for_select(ProjectMember.access_level_roles, @project_member.access_level), class: "form-control project-access-select select-control"
= icon('chevron-down')
......@@ -14,7 +14,7 @@
about role permissions
.form-group
.clearable-input
= label_tag :expires_at, 'Access expiration date', class: 'label-light'
= label_tag :expires_at, 'Access expiration date', class: 'label-bold'
= text_field_tag :expires_at, nil, class: 'form-control js-access-expiration-date', placeholder: 'Expiration date'
%i.clear-icon.js-clear-input
= f.submit "Add to project", class: "btn btn-create"
......
......@@ -2,10 +2,10 @@
.col-sm-12
= form_tag project_group_links_path(@project), class: 'js-requires-input', method: :post do
.form-group
= label_tag :link_group_id, "Select a group to share with", class: "label-light"
= label_tag :link_group_id, "Select a group to share with", class: "label-bold"
= groups_select_tag(:link_group_id, data: { skip_groups: @skip_groups }, class: "input-clamp", required: true)
.form-group
= label_tag :link_group_access, "Max access level", class: "label-light"
= label_tag :link_group_access, "Max access level", class: "label-bold"
.select-wrapper
= select_tag :link_group_access, options_for_select(ProjectGroupLink.access_options, ProjectGroupLink.default_access), class: "form-control select-control"
= icon('chevron-down')
......@@ -13,7 +13,7 @@
= link_to "Read more", help_page_path("user/permissions"), class: "vlink"
about role permissions
.form-group
= label_tag :expires_at, 'Access expiration date', class: 'label-light'
= label_tag :expires_at, 'Access expiration date', class: 'label-bold'
.clearable-input
= text_field_tag :expires_at, nil, class: 'form-control js-access-expiration-date-groups', placeholder: 'Expiration date', id: 'expires_at_groups'
%i.clear-icon.js-clear-input
......
......@@ -4,7 +4,7 @@
= form_errors(@project)
%fieldset.builds-feature
.form-group.append-bottom-default.js-secret-runner-token
= f.label :runners_token, _("Runner token"), class: 'label-light'
= f.label :runners_token, _("Runner token"), class: 'label-bold'
.form-control.js-secret-value-placeholder
= '*' * 20
= f.text_field :runners_token, class: "form-control hide js-secret-value", placeholder: 'xEeFCaDAB89'
......@@ -36,7 +36,7 @@
%hr
.form-group
= f.label :build_timeout_human_readable, _('Timeout'), class: 'label-light'
= f.label :build_timeout_human_readable, _('Timeout'), class: 'label-bold'
= f.text_field :build_timeout_human_readable, class: 'form-control'
%p.form-text.text-muted
= _("Per job. If a job passes this threshold, it will be marked as failed")
......@@ -44,7 +44,7 @@
%hr
.form-group
= f.label :ci_config_path, _('Custom CI config path'), class: 'label-light'
= f.label :ci_config_path, _('Custom CI config path'), class: 'label-bold'
= f.text_field :ci_config_path, class: 'form-control', placeholder: '.gitlab-ci.yml'
%p.form-text.text-muted
= _("The path to CI config file. Defaults to <code>.gitlab-ci.yml</code>")
......@@ -83,7 +83,7 @@
%hr
.form-group
= f.label :build_coverage_regex, _("Test coverage parsing"), class: 'label-light'
= f.label :build_coverage_regex, _("Test coverage parsing"), class: 'label-bold'
.input-group
%span.input-group-prepend
.input-group-text /
......
......@@ -3,9 +3,9 @@
- if @trigger.token
.form-group
%label.label-light Token
%label.label-bold Token
%p.form-control-plaintext= @trigger.token
.form-group
= f.label :key, "Description", class: "label-light"
= f.label :key, "Description", class: "label-bold"
= f.text_field :description, class: "form-control", required: true, title: 'Trigger description is required.', placeholder: "Trigger description"
= f.submit btn_text, class: "btn btn-save"
- ci_cd_only = local_assigns.fetch(:ci_cd_only, false)
.form-group.import-url-data
= f.label :import_url, class: 'label-light' do
= f.label :import_url, class: 'label-bold' do
%span
= _('Git repository URL')
......
......@@ -11,18 +11,18 @@
.row
.form-group.col-md-6
= f.label :name, class: 'label-light'
= f.label :name, class: 'label-bold'
= f.text_field :name, class: "form-control", required: true
.row
.form-group.col-md-6
= f.label :expires_at, class: 'label-light'
= f.label :expires_at, class: 'label-bold'
.input-icon-wrapper
= f.text_field :expires_at, class: "datepicker form-control", placeholder: 'YYYY-MM-DD'
= icon('calendar', { class: 'input-icon-right' })
.form-group
= f.label :scopes, class: 'label-light'
= f.label :scopes, class: 'label-bold'
= render 'shared/tokens/scopes_form', prefix: 'personal_access_token', token: token, scopes: scopes
.prepend-top-default
......
......@@ -5,5 +5,5 @@
- scopes.each do |scope|
%fieldset.form-group.form-check
= check_box_tag "#{prefix}[scopes][]", scope, token.scopes.include?(scope), id: "#{prefix}_scopes_#{scope}", class: 'form-check-input'
= label_tag ("#{prefix}_scopes_#{scope}"), scope, class: 'label-light form-check-label'
= label_tag ("#{prefix}_scopes_#{scope}"), scope, class: 'label-bold form-check-label'
.text-secondary= t scope, scope: [:doorkeeper, :scope_desc]
= form_errors(hook)
.form-group
= form.label :url, 'URL', class: 'label-light'
= form.label :url, 'URL', class: 'label-bold'
= form.text_field :url, class: 'form-control', placeholder: 'http://example.com/trigger-ci.json'
.form-group
= form.label :token, 'Secret Token', class: 'label-light'
= form.label :token, 'Secret Token', class: 'label-bold'
= form.text_field :token, class: 'form-control', placeholder: ''
%p.form-text.text-muted
Use this token to validate received payloads. It will be sent with the request in the X-Gitlab-Token HTTP header.
.form-group
= form.label :url, 'Trigger', class: 'label-light'
= form.label :url, 'Trigger', class: 'label-bold'
%ul.list-unstyled.prepend-left-20
%li
= form.check_box :push_events, class: 'form-check-input'
......@@ -72,7 +72,7 @@
%p.light.ml-1
This URL will be triggered when a wiki page is created/updated
.form-group
= form.label :enable_ssl_verification, 'SSL verification', class: 'label-light checkbox'
= form.label :enable_ssl_verification, 'SSL verification', class: 'label-bold checkbox'
.form-check
= form.check_box :enable_ssl_verification, class: 'form-check-input'
= form.label :enable_ssl_verification, class: 'form-check-label ml-1' do
......
---
title: Use monospaced font for MR diff commit link ref on GFM
merge_request:
author:
type: other
---
title: Add SHA256 and HEAD on File API
merge_request: 19439
author: ahmet2mir
type: added
---
title: Add option to add README when creating a project
merge_request: 20335
author:
type: added
---
title: Fix double "in" in time to artifact deletion message
merge_request: 20357
author: "@bbodenmiller"
type: fixed
---
title: Add download button for single file (including raw files) in repository
merge_request: 20480
author: Kia Mei Somabes
type: added
---
title: Present state indication on GFM preview
merge_request:
author:
type: added
---
title: Expose visibility via Snippets API
merge_request: 19620
author: Jan Beckmann
type: added
---
title: Add dropdown to Groups link in top bar
merge_request: 18280
author:
type: added
---
title: Fix link to job when creating a new issue from a failed job
merge_request: 20328
author:
type: fixed
---
title: Allows settings sections to expand by default when linking to them
merge_request: 20211
author:
type: other
---
title: Milestone page list redesign
merge_request: 19832
author: Constance Okoghenun
type: changed
---
title: Change avatar image in the header when user updates their avatar.
merge_request: 20119
author: Jamie Schembri
type: added
---
title: Improve U2F workflow when using unsupported browsers
merge_request: 19938
author: Jan Beckmann
type: changed
---
title: Keep lists ordered when copying only list items
merge_request: 18522
author: Jan Beckmann
type: fixed
---
title: Fixes Microsoft Teams notifications for pipeline events
merge_request: 19632
author: Jeff Brown
type: fixed
---
title: Fix label and milestone duplicated records and IID errors
merge_request: 19961
author:
type: fixed
---
title: Create new or add existing Kubernetes cluster from a single page
merge_request: 18963
author:
type: changed
---
title: Removes the environment scope field for users that cannot edit it
merge_request: 19643
author:
type: changed
---
title: Use one column form layout on Admin Area Settings page
merge_request:
author:
type: changed
---
title: Fixed bug when editing a comment in an issue,the preview mode is toggled in
the main textarea
merge_request: 20112
author: Constance Okoghenun
type: fixed
---
title: Expire correct method caches after HEAD changed
merge_request:
author:
type: fixed
---
title: Set MR target branch to default branch if target branch is not valid
merge_request: 19067
author:
type: fixed
---
title: Resolve "Unable to save user profile update with Safari"
merge_request: 20676
author:
type: fixed
---
title: Fix chat service tag notifications not sending when only default branch enabled
merge_request: 19864
author:
type: fixed
---
title: Add machine type and pricing documentation links, add class to labels to make
bold
merge_request:
author:
type: changed
---
title: 'Fix username validation order on signup, resolves #45575'
merge_request: 19610
author: Jan Beckmann
type: fixed
---
title: Update WebIDE to show file in tree on load
merge_request: 19887
author:
type: changed
---
title: Add environment dropdown for the metrics page
merge_request: 19833
author:
type: changed
---
title: Fade uneditable area in Web IDE
merge_request: 20008
author:
type: changed
---
title: Update Web IDE file tree styles
merge_request: 19969
author:
type: changed
---
title: Add Object Storage to project export
merge_request: 20105
author:
type: added
---
title: Update new SSH key page to improve copy
merge_request: 19994
author:
type: other
---
title: Update new SSH key page to improve key input validation
merge_request: 19997
author:
type: other
---
title: Allows you to create another deploy token dimmediately after creating one
merge_request: 19639
author:
type: changed
---
title: CE port gitlab-ee!6112
merge_request: 19714
author:
type: other
---
title: Fix webhook error when password is not present
merge_request: 19945
author: Jan Beckmann
type: fixed
---
title: Ignore unknown OAuth sources in ApplicationSetting
merge_request: 20129
author:
type: fixed
---
title: Removes unused bootstrap 4 scss files
merge_request: 19423
author:
type: deprecated
---
title: Fix CSS for buttons not to be hidden on issues/MR title
merge_request: 19176
author: Takuya Noguchi
type: fixed
---
title: Add readme button to non-empty project page
merge_request: 20104
author:
type: fixed
---
title: Show jobs from same pipeline in sidebar in job details view.
merge_request: 20243
author:
type: fixed
---
title: Make quick commands case insensitive
merge_request: 19614
author: Jan Beckmann
type: fixed
---
title: Add /confidential quick action
merge_request:
author: Jan Beckmann
type: added
---
title: Update new group page to better explain what groups are
merge_request: 19991
author:
type: other
---
title: Add a link to the contributing page in the user dropdown
merge_request: 19708
author:
type: added
---
title: Only show new issue / new merge request on group page when issues / merge requests
are enabled
merge_request: 19869
author: Jan Beckmann
type: fixed
---
title: Omits operartions and kubernetes item from project sidebar when repository or builds are disabled
merge_request: 19835
author:
type: fixed
---
title: Change environment scope text depending on number of project clusters. Update
form to only include form-groups
merge_request:
author:
type: changed
---
title: Minor style changes to personal access token form and scope checkboxes
merge_request: 20052
author:
type: other
---
title: Fix Web IDE crashing on directories named 'blob'
merge_request: 20712
author:
type: fixed
---
title: Uses long sha version of the merged commit in MR widget copy to clipboard button
merge_request: 19955
author:
type: other
---
title: Fix branches are not shown in Merge Request dropdown when preferred language
is not English
merge_request: 20016
author: Hiroyuki Sato
type: fixed
---
title: Prevent browser autocomplete for milestone date fields
merge_request:
author:
type: fixed
---
title: Fixes toggle discussion button not expanding collapsed discussions
merge_request: 20452
author:
type: fixed
---
title: Fixes issue with uploading same image to Profile Avatar twice
merge_request: 20161
author: Chirag Bhatia
type: fixed
---
title: Fixed Merge request changes dropdown displays incorrectly
merge_request: 20237
author: Constance Okoghenun
type: fixed
---
title: Fix performance bar modal visibility in Safari
merge_request:
author:
type: fixed
---
title: Add option to hide third party offers in admin application settings
merge_request: 20379
author:
type: added
---
title: Fix overlapping file title and file actions in MR changes tag
merge_request:
author:
type: fixed
---
title: Line separator to the left of the 'Admin area' wrench icon had vanished
merge_request: 20282
author: bitsapien
type: fixed
---
title: Resolve compatibility issues with node 6
merge_request: 20461
author:
type: fixed
---
title: Stop relying on migrations in the CacheableAttributes cache key and cache attributes
for 1 minute instead
merge_request: 20389
author:
type: fixed
---
title: Load Devise with Omniauth when auto_sign_in_with_provider is configured
merge_request: 20302
author:
type: fixed
---
title: Improves performance on Merge Request diff tab by removing the scroll event
listeners being added to every file
merge_request:
author:
type: performance
---
title: Fix navigation to First and Next discussion on MR Changes tab
merge_request: 20434
author:
type: fixed
---
title: Improves performance of mr code, by fixing the state being mutated outside
of the store in the util function trimFirstCharOfLineContent and in map operations.
Avoids map operation in an empty array. Adds specs to the trimFirstCharOfLineContent
function
merge_request: 20380
author: filipa
type: performance
---
title: Fix RSS button interaction on Dashboard, Project and Group activities
merge_request: 20549
author:
type: fixed
---
title: Removes unused vuex code in mr refactor and removes unneeded dependencies
merge_request: 20499
author:
type: other
---
title: Fixes base command used in Helm installations
merge_request: 20471
author:
type: fixed
---
title: Add index on deployable_type/id for deployments
merge_request:
author:
type: performance
---
title: Add more detailed logging to githost.log when rebasing
merge_request:
author:
type: other
---
title: Add title placeholder for new issues
merge_request: 20271
author: George Tsiolis
type: changed
---
title: Remove healthchecks from prometheus endpoint
merge_request: 20565
author:
type: fixed
---
title: Fix fields for author & assignee in MR API docs.
merge_request: 19798
author: gfyoung
type: fixed
---
title: Fully migrate pipeline stages position
merge_request: 19369
author:
type: performance
---
title: Cleanup Prometheus ruby metrics
merge_request: 20039
author: Ben Kochie
type: fixed
---
title: Add CI job to check Gemfile.rails5.lock
merge_request: 19605
author: "@blackst0ne"
type: other
---
title: Bump grape-path-helpers to 1.0.5
merge_request: 19604
author: "@blackst0ne"
type: other
---
title: "[Rails5] Force the callback run first"
merge_request: 20055
author: "@blackst0ne"
type: fixed
---
title: "[Rails5] Fix milestone GROUP BY query"
merge_request: 20256
author: "@blackst0ne"
type: fixed
---
title: "[Rails5] Fix sessions_controller_spec"
merge_request: 19936
author: "@blackst0ne"
type: fixed
---
title: "[Rails5] Set request.format for artifacts_controller"
merge_request: 19937
author: "@blackst0ne"
type: fixed
---
title: "[Rails5] Explicitly set request.format for blob_controller"
merge_request: 19876
author: "@blackst0ne"
type: fixed
---
title: '[Rails5] Fix "-1 is not a valid data_store"'
merge_request: 19917
author: "@blackst0ne"
type: fixed
---
title: "[Rails5] Fix optimistic lock value"
merge_request: 19878
author: "@blackst0ne"
type: fixed
---
title: "[Rails5] Fix pipeline_schedules_controller_spec"
merge_request: 19919
author: "@blackst0ne"
type: fixed
---
title: "[Rails5] Fix snippets_finder arel queries"
merge_request: 19796
author: "@blackst0ne"
type: fixed
---
title: "[Rails5] Fix ActionCable '/cable' mountpoint conflict"
merge_request: 20015
author: "@blackst0ne"
type: fixed
---
title: "[Rails5] Invalid single-table inheritance type: Group is not a subclass of
Namespace"
merge_request: 19918
author: "@blackst0ne"
type: fixed
---
title: "[Rails5] Set request.format in commits_controller"
merge_request: 20023
author: "@blackst0ne"
type: fixed
---
title: Use object storage as the first class persistable store for new live trace
architecture
merge_request: 19515
author:
type: changed
---
title: Bump carrierwave gem verion to 1.2.3
merge_request: 20287
author:
type: performance
---
title: Fix bug where maintainer would not be allowed to push to forks with merge requests
that have `Allow maintainer edits` enabled.
merge_request: 18968
author:
type: fixed
---
title: Allow querying a single merge request within a project
merge_request: 19853
author:
type: changed
---
title: 'Expose permissions of the current user on resources in GraphQL'
merge_request: 20152
author:
type: added
---
title: Add pipeline lists to GraphQL
merge_request: 20249
author:
type: added
---
title: Reduce the number of queries when searching for groups
merge_request: 20398
author:
type: performance
---
title: Use CommonMark syntax and rendering for new Markdown content
merge_request: 19331
author:
type: added
---
title: Add filename filtering to code search
merge_request: 19509
author:
type: added
---
title: Close revoke deploy token modal on escape keypress
merge_request: 20347
author: George Tsiolis
type: changed
---
title: Added with_statsoption for GET /projects/:id/repository/commits
merge_request:
author:
type: added
---
title: Adds the `locked` state to the merge request API so that it can be used as a search filter.
merge_request: 20186
author:
type: fixed
---
title: Keeps the label on an issue when the issue is moved.
merge_request: 20036
author:
type: fixed
---
title: Add Gitlab::SQL:CTE for easily building CTE statements
merge_request:
author:
type: added
---
title: Fixes an issue where migrations instead of schema loading were run
merge_request: 20227
author:
type: changed
---
title: Allow trailing whitespace on blockquote fence lines
merge_request:
author:
type: fixed
---
title: Expose whether current user can push into a branch on branches API
merge_request:
author:
type: added
---
title: Deactivate new KubernetesService created from active template to prevent project creation from failing
merge_request:
author:
type: fixed
---
title: Properly detect label reference if followed by period or question mark
merge_request:
author:
type: fixed
---
title: Improve performance of listing users without projects
merge_request:
author:
type: performance
---
title: Add back copy for existing gcp accounts within offer banner
merge_request:
author:
type: changed
---
title: Add CI_PIPELINE_URL and CI_JOB_URL
merge_request: 19618
author:
type: added
---
title: Don't hash user ID in OIDC subject claim
merge_request: 19784
author: Markus Koller
type: changed
---
title: Fix boards issue highlight
merge_request: 20063
author: George Tsiolis
type: changed
---
title: mergeError message has been binded using v-html directive
merge_request: 19058
author: Murat Dogan
type: fixed
---
title: Fix accessing imported pipeline builds
merge_request: 20713
author:
type: fixed
---
title: Fix merge request diffs when created with gitaly_diff_between enabled
merge_request:
author:
type: fixed
title: Fixed pagination of groups API
merge_request: 19665
author: Marko, Peter
type: added
---
title: Updated last commit link color
merge_request: 20234
author: Constance Okoghenun
type: fixed
---
title: Fix paragraph line height for emoji
merge_request: 20137
author: George Tsiolis
type: fixed
---
title: Fix performance problem of accessing tag list for projects api endpoints
merge_request:
author:
type: performance
---
title: Check if archived trace exist before archive it
merge_request: 20297
author:
type: fixed
---
title: Disabled Web IDE autocomplete suggestions for Markdown files.
merge_request:
author: Isaac Smith
type: fixed
---
title: Fix wrong role badge displayed in projects dashboard
merge_request: 20374
author:
type: fixed
---
title: Fix OAuth Application Authorization screen to appear with each access
merge_request: 20216
author:
type: fixed
---
title: Enable Doorkeeper option to avoid generating new tokens when users login via
oauth
merge_request: 20200
author:
type: fixed
---
title: Fixed bug with invalid repository reference using the wiki search
merge_request: 20722
author:
type: fixed
---
title: Fixed bug that allowed to remove other wiki pages if the title had wildcard characters
merge_request:
author:
type: fixed
---
title: Add Web Terminal for Ci Builds
merge_request:
author: Vicky Chijwani
type: added
---
title: Structure getters for diff Store properly and adds specs
merge_request:
author:
type: fixed
---
title: Enable frozen string in app/workers/*.rb
merge_request: 19944
author: gfyoung
type: other
---
title: Enable frozen string in apps/validators/*.rb
merge_request: 20382
author: gfyoung
type: other
---
title: Enable frozen string in apps/validators/*.rb
merge_request: 20220
author: gfyoung
type: other
---
title: Finish enabling frozen string for app/workers/*.rb
merge_request: 20197
author: gfyoung
type: other
---
title: Move some Gitaly RPC's to opt-out
merge_request: 19591
author:
type: other
---
title: Move Gitaly branch/tag/ref RPC's to opt-out
merge_request: 19644
author:
type: other
---
title: Use appropriate timeout on Gitaly server info checks, avoid error on timeout
merge_request: 20552
author:
type: fixed
---
title: Updated Gitaly fail-fast timeout values
merge_request: !20259
author:
type: performance
---
title: Highlight cluster settings message
merge_request: 19996
author: George Tsiolis
type: changed
---
title: Improve Web IDE commit flow
merge_request:
author:
type: changed
---
title: Display merge request title & description in Web IDE
merge_request:
author:
type: added
---
title: Remove deprecated object_storage_upload queue.
merge_request:
author:
type: removed
---
title: Support direct_upload for generic uploads
merge_request:
author:
type: added
---
title: Don't show context button for diffs of deleted files.
merge_request:
author:
type: fixed
---
title: Invalidate merge request diffs cache if diff data change.
merge_request:
author:
type: fixed
---
title: Fix cross-project label references.
merge_request:
author:
type: fixed
---
title: Add /uploads subdirectory to allowed upload paths.
merge_request:
author:
type: fixed
---
title: Add ellispsis to web ide commit button
merge_request: 20030
author:
type: other
---
title: Rubix, scikit-learn, tensorflow & other useful libraries pre-installed with JupyterHub
merge_request: 20714
author: Amit Rathi
type: changed
---
title: Limit the action suffixes in transaction metrics
merge_request:
author:
type: fixed
---
title: Added id sorting option to GET groups and subgroups API
merge_request: 19665
author: Marko, Peter
type: added
---
title: Move boards modal EmptyState vue component
merge_request: 20068
author: George Tsiolis
type: performance
---
title: Enable no-multi-assignment in JS files
merge_request: 19808
author: gfyoung
type: other
---
title: Improve no-multi-assignment fixes after enabling rule
merge_request: 19915
author: gfyoung
type: other
---
title: Enable no-restricted globals in JS files
merge_request: 19877
author: gfyoung
type: other
---
title: Schedule workers to delete non-latest diffs in post-migration
merge_request:
author:
type: other
---
title: Delete non-latest merge request diff files upon merge
merge_request:
author:
type: other
---
title: Render MR page when diffs cannot be fetched from the database or the git repository
merge_request: 20680
author:
type: fixed
---
title: Mark MR as merged regardless of errors when closing issues
merge_request:
author:
type: fixed
---
title: Improve render performance of large wiki pages
merge_request: 20465
author: Peter Leitzen
type: performance
---
title: Ensure MR diffs always exist in the PR importer
merge_request:
author:
type: fixed
---
title: Enable prefer-structuring in JS files
merge_request: 19943
author: gfyoung
type: other
---
title: 'Remove incorrect CI doc re: PowerShell'
merge_request: 19622
title: Don't overflow project/group dropdown results
merge_request: 20704
author: gfyoung
type: fixed
---
title: Prune web hook logs older than 90 days
merge_request:
author:
type: added
---
title: Rails5 fix format in uploads actions
merge_request: 19907
author: Jasper Maes
type: fixed
---
title: Rails5 fix expected `issuable.reload.updated_at` to have changed
merge_request: 19733
author: Jasper Maes
type: fixed
---
title: Use same gem versions for rails5 as for rails4 where possible
merge_request: 19498
author: Jasper Maes
type: fixed
---
title: Rails5 fix stack level too deep
merge_request: 19762
author: Jasper Maes
type: fixed
---
title: 'Rails5 ActionController::ParameterMissing: param is missing or the value is
empty: application_setting'
merge_request: 19763
author: Jasper Maes
type: fixed
---
title: Rails5 fix no implicit conversion of Hash into String. ActionController::Parameters
no longer returns an hash in Rails 5
merge_request: 19792
author: Jasper Maes
type: fixed
---
title: Rails5 fix passing Group objects array into for_projects_and_groups milestone
scope
merge_request: 19863
author: Jasper Maes
type: fixed
---
title: Rails5 fix update_attribute usage not causing a save
merge_request: 19881
author: Jasper Maes
type: fixed
---
title: Rails5 update Gemfile.rails5.lock
merge_request: 19921
author: Jasper Maes
type: fixed
---
title: Rails5 fix passing Group objects array into for_projects_and_groups milestone
scope
merge_request: 19920
author: Jasper Maes
type: fixed
---
title: 'Rails5 fix expected: 1 time with arguments: (97, anything, {"squash"=>false})
received: 0 times'
merge_request: 20004
author: Jasper Maes
type: fixed
---
title: 'Rails 5 fix Capybara::ElementNotFound: Unable to find visible css #modal-revert-commit
and expected: "/bar" got: "/foo"'
merge_request: 20044
author: Jasper Maes
type: fixed
---
title: 'Rails5 fix expected: 0 times with any arguments received: 1 time with arguments:
DashboardController'
merge_request: 20018
author: Jasper Maes
type: fixed
---
title: Rails5 fix Admin::HooksController
merge_request: 20017
author: Jasper Maes
type: fixed
---
title: Rails5 fix MySQL milliseconds problem in specs
merge_request: 20221
author: Jasper Maes
type: fixed
---
title: Rails5 fix Mysql comparison failure caused by milliseconds problem
merge_request: 20222
author: Jasper Maes
type: fixed
---
title: Rails5 fix connection execute return integer instead of string
merge_request: 19901
author: Jasper Maes
type: fixed
---
title: Rails5 fix arel from in mysql_median_datetime_sql
merge_request: 20167
author: Jasper Maes
type: fixed
---
title: Rails5 fix Projects::PagesController spec
merge_request: 20007
author: Jasper Maes
type: fixed
---
title: Invalidate cache with project details when repository is updated
merge_request: 19774
author:
type: fixed
---
title: Remove remaining traces of the Allocations Gem
merge_request:
author:
type: changed
---
title: Remove the ci_job_request_with_tags_matcher
merge_request:
author:
type: performance
---
title: Remove the use of `is_shared` of `Ci::Runner`
merge_request:
author:
type: other
---
title: Change label link vertical alignment property
merge_request: 18777
author: George Tsiolis
type: changed
---
title: Remove small container width
merge_request: 19893
author: George Tsiolis
type: changed
---
title: Remove redundant query when removing trace
merge_request: 20324
author:
type: performance
---
title: Revert merge request discussion buttons padding
merge_request: 20060
author: George Tsiolis
type: changed
---
title: Remove scrollbar in Safari in repo settings page
merge_request: 19809
author: gfyoung
type: fixed
---
title: Fix XSS vulnerability for table of content generation
merge_request:
author:
type: security
---
title: Update sanitize gem to 4.6.5 to fix HTML injection vulnerability
merge_request:
author:
type: security
---
title: HTML escape branch name in project graphs page
merge_request:
author:
type: security
---
title: HTML escape the name of the user in ProjectsHelper#link_to_member
merge_request:
author:
type: security
---
title: Don't show events from internal projects for anonymous users in public feed
merge_request:
author:
type: security
---
title: Bump rugged to 0.27.2
merge_request:
author:
type: fixed
---
title: Fix Bamboo CI status not showing for branch plans
merge_request:
author:
type: fixed
---
title: Eliminate N+1 queries in LFS file locks checks during a push
merge_request:
author:
type: performance
---
title: Allow straight diff in Compare API
merge_request: 20120
author: Maciej Nowak
type: added
---
title: Run repository checks in parallel for each shard
merge_request: 20179
author:
type: added
---
title: Updated the icon for expand buttons to ellipsis
merge_request: 18793
author: Constance Okoghenun
type: changed
\ No newline at end of file
---
title: Add transfer project API endpoint
merge_request: 20122
author: Aram Visser
type: added
---
title: Web IDE supports now Image + Download Diff Viewing
merge_request: 18768
author:
type: added
---
title: Hide project name if searching against a project
merge_request: 19595
author:
type: changed
---
title: update bcrypt to also support libxcrypt
merge_request: 20260
author: muhammadn
type: other
---
title: Update environments nav controls icons
merge_request: 20199
author: George Tsiolis
type: changed
---
title: Update external link icon in header user dropdown
merge_request: 20150
author: George Tsiolis
type: changed
---
title: Update external link icon in merge request widget
merge_request: 20154
author: George Tsiolis
type: changed
---
title: Update integrations external link icons
merge_request: 20205
author: George Tsiolis
type: changed
---
title: Update pipeline icon in web ide sidebar
merge_request: 20058
author: George Tsiolis
type: changed
---
title: Fix extra blank line at start of rendered reStructuredText code block
merge_request: 19596
author:
type: fixed
---
title: migrate backup rake task to gitaly
merge_request:
author:
type: added
---
title: Use Tooltip component in MrWidgetAuthorTime vue comonent
merge_request: 19635
author: George Tsiolis
type: performance
---
title: Fixed pagination of web hook logs
merge_request:
author:
type: performance
---
title: Fix branch name encoding for dropdown on issue page
merge_request: 19634
author:
type: fixed
---
title: Gitaly metrics check for read/writeability
merge_request: 20022
author:
type: other
......@@ -9,3 +9,8 @@ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../#{gemfile}", __dir__)
# Set up gems listed in the Gemfile.
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
begin
require 'bootsnap/setup'
rescue LoadError
# bootsnap is optional dependency, so if we don't have it it's fine
end
module BootstrapFormBuilderCustomization
def label_class
"label-light"
"label-bold"
end
end
......
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class MigrateProcessCommitWorkerJobs < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
class Repository
attr_reader :storage
def initialize(storage, relative_path)
@storage = storage
@relative_path = relative_path
end
def gitaly_repository
Gitaly::Repository.new(storage_name: @storage, relative_path: @relative_path)
end
end
class Project < ActiveRecord::Base
def self.find_including_path(id)
select("projects.*, CONCAT(namespaces.path, '/', projects.path) AS path_with_namespace")
......@@ -11,19 +21,12 @@ class MigrateProcessCommitWorkerJobs < ActiveRecord::Migration
.find_by(id: id)
end
def repository_storage_path
Gitlab::GitalyClient::StorageSettings.allow_disk_access do
Gitlab.config.repositories.storages[repository_storage].legacy_disk_path
end
end
def repository_path
# TODO: review if the change from Legacy storage needs to reflect here as well.
File.join(repository_storage_path, read_attribute(:path_with_namespace) + '.git')
def commit(rev)
Gitlab::GitalyClient::CommitService.new(repository).find_commit(rev)
end
def repository
@repository ||= Rugged::Repository.new(repository_path)
@repository ||= Repository.new(repository_storage, read_attribute(:path_with_namespace) + '.git')
end
end
......@@ -42,22 +45,19 @@ class MigrateProcessCommitWorkerJobs < ActiveRecord::Migration
next unless project
begin
commit = project.repository.lookup(payload['args'][2])
rescue Rugged::OdbError
next
end
commit = project.commit(payload['args'][2])
next unless commit
hash = {
id: commit.oid,
message: encode(commit.message),
parent_ids: commit.parent_ids,
authored_date: commit.author[:time],
author_name: encode(commit.author[:name]),
author_email: encode(commit.author[:email]),
committed_date: commit.committer[:time],
committer_email: encode(commit.committer[:email]),
committer_name: encode(commit.committer[:name])
id: commit.id,
message: encode(commit.body),
parent_ids: commit.parent_ids.to_a,
authored_date: Time.at(commit.author.date.seconds).utc,
author_name: encode(commit.author.name),
author_email: encode(commit.author.email),
committed_date: Time.at(commit.committer.date.seconds).utc,
committer_email: encode(commit.committer.email),
committer_name: encode(commit.committer.name)
}
payload['args'][2] = hash
......
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class RemoveDotGitFromUsernames < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
include Gitlab::ShellAdapter
# Set this constant to true if this migration requires downtime.
DOWNTIME = false
def up
......@@ -64,16 +60,14 @@ class RemoveDotGitFromUsernames < ActiveRecord::Migration
# we rename suffix instead of removing it
path = path.sub(/\.git\z/, '_git')
Gitlab::GitalyClient::StorageSettings.allow_disk_access do
check_routes(path.dup, 0, path)
end
check_routes(path.dup, 0, path)
end
def check_routes(base, counter, path)
route_exists = route_exists?(path)
Gitlab.config.repositories.storages.each do |shard, storage|
if route_exists || path_exists?(shard, storage.legacy_disk_path)
Gitlab.config.repositories.storages.each do |shard, _storage|
if route_exists || path_exists?(shard, path)
counter += 1
path = "#{base}#{counter}"
......
......@@ -40,6 +40,7 @@ description: 'Learn how to contribute to GitLab.'
- [View sent emails or preview mailers](emails.md)
- [Shell commands](shell_commands.md) in the GitLab codebase
- [`Gemfile` guidelines](gemfile.md)
- [Pry debugging](pry_debugging.md)
- [Sidekiq debugging](sidekiq_debugging.md)
- [Gotchas](gotchas.md) to avoid
- [Avoid modules with instance variables](module_with_instance_variables.md) if possible
......
# Pry debugging
## Invoking pry debugging
To invoke the debugger, place `binding.pry` somewhere in your
code. When the Ruby interpreter hits that code, execution will stop,
and you can type in commands to debug the state of the program
## `byebug` vs `binding.pry`
`byebug` has a very similar interface as `gdb`, but `byebug` does not
use the powerful Pry REPL.
`binding.pry` uses Pry, but lacks some of the `byebug`
features. GitLab uses the [`pry-byebug`](https://github.com/deivid-rodriguez/pry-byebug)
gem. This gem brings some capabilities `byebug` to `binding.pry`, so
using that, will give you the most debugging powers.
## `byebug`
Check out [the docs](https://github.com/deivid-rodriguez/byebug) for the full list of commands.
You can start the Pry REPL with the `pry` command.
## `pry`
There are **a lot** of features present in `pry`, too much to cover in
this document, so for the full documentation head over to the [Pry wiki](https://github.com/pry/pry/wiki).
Below are a few features definitely worth checking out, also run
`help` in a pry session to see what else you can do.
### State navigation
With the [state navigation](https://github.com/pry/pry/wiki/State-navigation)
you can move around in the code to discover methods and such:
```ruby
# Change context
[1] pry(main)> cd Pry
[2] pry(Pry):1>
# Print methods
[2] pry(Pry):1> ls -m
# Find a method
[3] pry(Pry):1> find-method to_yaml
```
### Source browsing
You [look at the source code](https://github.com/pry/pry/wiki/Source-browsing)
from your `pry` session:
```ruby
[1] pry(main)> $ Array#first
# The above is equivalent to
[2] pry(main)> cd Array
[3] pry(Array):1> show-source first
```
`$` is an alias for `show-source`.
### Documentation browsing
Similar to source browsing, is [Documentation browsing](https://github.com/pry/pry/wiki/Documentation-browsing).
```ruby
[1] pry(main)> show-doc Array#first
```
`?` is an alias for `show-doc`.
### Command history
With <kdb>Ctrl+R</kbd> you can search your [command history](https://github.com/pry/pry/wiki/History).
## Stepping
To step through the code, you can use the following commands:
- `break`: Manage breakpoints.
- `step`: Step execution into the next line or method. Takes an
optional numeric argument to step multiple times.
- `next`: Step over to the next line within the same frame. Also takes
an optional numeric argument to step multiple lines.
- `finish`: Execute until current stack frame returns.
- `continue`: Continue program execution and end the Pry session.
## Callstack navigation
You also can move around in the callstack with these commands:
- `backtrace`: Shows the current stack. You can use the numbers on the
left side with the frame command to navigate the stack.
- `up`: Moves the stack frame up. Takes an optional numeric argument
to move multiple frames.
- `down`: Moves the stack frame down. Takes an optional numeric
argument to move multiple frames.
- `frame <n>`: Moves to a specific frame. Called without arguments
will show the current frame.
## Short commands
When you use `binding.pry` instead of `byebug`, the short commands
like `s`, `n`, `f`, and `c` do not work. To reinstall them, add this
to `~/.pryrc`:
```ruby
if defined?(PryByebug)
Pry.commands.alias_command 's', 'step'
Pry.commands.alias_command 'n', 'next'
Pry.commands.alias_command 'f', 'finish'
Pry.commands.alias_command 'c', 'continue'
end
```
## Repeat last command
You can repeat the last command by just hitting the <kbd>Enter</kbd>
key (e.g., with `step` or`next`), if you place the following snippet
in your `~/.pryrc`:
```ruby
Pry::Commands.command /^$/, "repeat last command" do
_pry_.run_command Pry.history.to_a.last
end
```
`byebug` supports this out-of-the-box.
......@@ -101,7 +101,7 @@ CHROME_HEADLESS=0 bundle exec rspec some_spec.rb
The test will go by quickly, but this will give you an idea of what's happening.
You can also add `byebug` or `binding.pry` to pause execution and step through
You can also add `byebug` or `binding.pry` to pause execution and [step through](../pry_debugging.md#stepping)
the test.
#### Screenshots
......
......@@ -194,12 +194,12 @@ sudo apt-get install pgloader
1. Switch database from MySQL to PostgreSQL
``` bash
cd /home/git/gitlab
sudo -u git mv config/database.yml config/database.yml.bak
sudo -u git cp config/database.yml.postgresql config/database.yml
sudo -u git -H chmod o-rwx config/database.yml
```
``` bash
cd /home/git/gitlab
sudo -u git mv config/database.yml config/database.yml.bak
sudo -u git cp config/database.yml.postgresql config/database.yml
sudo -u git -H chmod o-rwx config/database.yml
```
1. Run the following commands to prepare the schema:
......
......@@ -167,7 +167,7 @@ twice, which can lead to confusion during deployments.
| [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) | 10.2+ | Ingress can provide load balancing, SSL termination, and name-based virtual hosting. It acts as a web proxy for your applications and is useful if you want to use [Auto DevOps] or deploy your own web apps. |
| [Prometheus](https://prometheus.io/docs/introduction/overview/) | 10.4+ | Prometheus is an open-source monitoring and alerting system useful to supervise your deployed applications. |
| [GitLab Runner](https://docs.gitlab.com/runner/) | 10.6+ | GitLab Runner is the open source project that is used to run your jobs and send the results back to GitLab. It is used in conjunction with [GitLab CI/CD](https://about.gitlab.com/features/gitlab-ci-cd/), the open-source continuous integration service included with GitLab that coordinates the jobs. When installing the GitLab Runner via the applications, it will run in **privileged mode** by default. Make sure you read the [security implications](#security-implications) before doing so. |
| [JupyterHub](http://jupyter.org/) | 11.0+ | [JupyterHub](https://jupyterhub.readthedocs.io/en/stable/) is a multi-user service for managing notebooks across a team. [Jupyter Notebooks](https://jupyter-notebook.readthedocs.io/en/latest/) provide a web-based interactive programming environment used for data analysis, visualization, and machine learning. **Note**: Authentication will be enabled for any user of the GitLab server via OAuth2. HTTPS will be supported in a future release. |
| [JupyterHub](http://jupyter.org/) | 11.0+ | [JupyterHub](https://jupyterhub.readthedocs.io/en/stable/) is a multi-user service for managing notebooks across a team. [Jupyter Notebooks](https://jupyter-notebook.readthedocs.io/en/latest/) provide a web-based interactive programming environment used for data analysis, visualization, and machine learning. We use [this](https://gitlab.com/gitlab-org/jupyterhub-user-image/blob/master/Dockerfile) custom Jupyter image that installs additional useful packages on top of the base Jupyter. **Note**: Authentication will be enabled for any user of the GitLab server via OAuth2. HTTPS will be supported in a future release. |
## Getting the external IP address
......
......@@ -34,7 +34,7 @@ module Gitlab
def self.fabricate(resource)
case resource
when Hash
self.new(resource)
self.new(resource.symbolize_keys)
when ::HasVariable
self.new(resource.to_runner_variable)
when self
......
# Gitlab::Git::Repository is a wrapper around native Rugged::Repository object
require 'tempfile'
require 'forwardable'
require "rubygems/package"
......@@ -673,35 +672,17 @@ module Gitlab
# If `mirror_refmap` is present the remote is set as mirror with that mapping
def add_remote(remote_name, url, mirror_refmap: nil)
gitaly_migrate(:remote_add_remote) do |is_enabled|
if is_enabled
gitaly_remote_client.add_remote(remote_name, url, mirror_refmap)
else
rugged_add_remote(remote_name, url, mirror_refmap)
end
wrapped_gitaly_errors do
gitaly_remote_client.add_remote(remote_name, url, mirror_refmap)
end
end
def remove_remote(remote_name)
gitaly_migrate(:remote_remove_remote) do |is_enabled|
if is_enabled
gitaly_remote_client.remove_remote(remote_name)
else
rugged_remove_remote(remote_name)
end
wrapped_gitaly_errors do
gitaly_remote_client.remove_remote(remote_name)
end
end
# Update the specified remote using the values in the +options+ hash
#
# Example
# repo.update_remote("origin", url: "path/to/repo")
def remote_update(remote_name, url:)
# TODO: Implement other remote options
rugged.remotes.set_url(remote_name, url)
nil
end
AUTOCRLF_VALUES = {
"true" => true,
"false" => false,
......@@ -875,12 +856,8 @@ module Gitlab
end
def fetch_repository_as_mirror(repository)
gitaly_migrate(:remote_fetch_internal_remote) do |is_enabled|
if is_enabled
gitaly_remote_client.fetch_internal_remote(repository)
else
rugged_fetch_repository_as_mirror(repository)
end
wrapped_gitaly_errors do
gitaly_remote_client.fetch_internal_remote(repository)
end
end
......@@ -1288,35 +1265,6 @@ module Gitlab
gitaly_ref_client.delete_refs(refs: ref_names) if ref_names.any?
end
def rugged_remove_remote(remote_name)
# When a remote is deleted all its remote refs are deleted too, but in
# the case of mirrors we map its refs (that would usualy go under
# [remote_name]/) to the top level namespace. We clean the mapping so
# those don't get deleted.
if rugged.config["remote.#{remote_name}.mirror"]
rugged.config.delete("remote.#{remote_name}.fetch")
end
rugged.remotes.delete(remote_name)
true
rescue Rugged::ConfigError
false
end
def rugged_fetch_repository_as_mirror(repository)
remote_name = "tmp-#{SecureRandom.hex}"
repository = RemoteRepository.new(repository) unless repository.is_a?(RemoteRepository)
add_remote(remote_name, GITALY_INTERNAL_URL, mirror_refmap: :all_refs)
fetch_remote(remote_name, env: repository.fetch_env)
ensure
remove_remote(remote_name)
end
def fetch_remote(remote_name = 'origin', env: nil)
run_git(['fetch', remote_name], env: env).last.zero?
end
def gitlab_projects_error
raise CommandError, @gitlab_projects.output
end
......
module Gitlab
module Git
module RepositoryMirroring
REFMAPS = {
# With `:all_refs`, the repository is equivalent to the result of `git clone --mirror`
all_refs: '+refs/*:refs/*',
heads: '+refs/heads/*:refs/heads/*',
tags: '+refs/tags/*:refs/tags/*'
}.freeze
RemoteError = Class.new(StandardError)
def set_remote_as_mirror(remote_name, refmap: :all_refs)
set_remote_refmap(remote_name, refmap)
rugged.config["remote.#{remote_name}.mirror"] = true
rugged.config["remote.#{remote_name}.prune"] = true
end
def remote_branches(remote_name)
gitaly_migrate(:ref_find_all_remote_branches) do |is_enabled|
if is_enabled
......@@ -45,20 +29,6 @@ module Gitlab
branches
end
def set_remote_refmap(remote_name, refmap)
Array(refmap).each_with_index do |refspec, i|
refspec = REFMAPS[refspec] || refspec
# We need multiple `fetch` entries, but Rugged only allows replacing a config, not adding to it.
# To make sure we start from scratch, we set the first using rugged, and use `git` for any others
if i == 0
rugged.config["remote.#{remote_name}.fetch"] = refspec
else
run_git(%W[config --add remote.#{remote_name}.fetch #{refspec}])
end
end
end
end
end
end
......@@ -5,7 +5,7 @@ module Gitlab
def initialize(current_user, project, query, repository_ref = nil, per_page: 20)
@current_user = current_user
@project = project
@repository_ref = repository_ref.presence || project.default_branch
@repository_ref = repository_ref.presence
@query = query
@per_page = per_page
end
......@@ -95,7 +95,7 @@ module Gitlab
def blobs
return [] unless Ability.allowed?(@current_user, :download_code, @project)
@blobs ||= Gitlab::FileFinder.new(project, repository_ref).find(query)
@blobs ||= Gitlab::FileFinder.new(project, repository_project_ref).find(query)
end
def wiki_blobs
......@@ -103,11 +103,8 @@ module Gitlab
@wiki_blobs ||= begin
if project.wiki_enabled? && query.present?
project_wiki = ProjectWiki.new(project)
unless project_wiki.empty?
ref = repository_ref || project.wiki.default_branch
Gitlab::WikiFileFinder.new(project, ref).find(query)
unless project.wiki.empty?
Gitlab::WikiFileFinder.new(project, repository_wiki_ref).find(query)
else
[]
end
......@@ -150,5 +147,13 @@ module Gitlab
def project_ids_relation
project
end
def repository_project_ref
@repository_project_ref ||= repository_ref || project.default_branch
end
def repository_wiki_ref
@repository_wiki_ref ||= repository_ref || project.wiki.default_branch
end
end
end
......@@ -13,8 +13,9 @@ module Gitlab
object = YAML.safe_load(string, [Symbol])
object.map do |variable|
variable[:key] = variable[:key].to_s
variable
variable.symbolize_keys.tap do |variable|
variable[:key] = variable[:key].to_s
end
end
end
......
......@@ -104,28 +104,5 @@ namespace :gitlab do
puts "To block these users run this command with BLOCK=true".color(:yellow)
end
end
# This is a rake task which removes faulty refs. These refs where only
# created in the 8.13.RC cycle, and fixed in the stable builds which were
# released. So likely this should only be run once on gitlab.com
# Faulty refs are moved so they are kept around, else some features break.
desc 'GitLab | Cleanup | Remove faulty deployment refs'
task move_faulty_deployment_refs: :gitlab_environment do
projects = Project.where(id: Deployment.select(:project_id).distinct)
projects.find_each do |project|
rugged = project.repository.rugged
max_iid = project.deployments.maximum(:iid)
rugged.references.each('refs/environments/**/*') do |ref|
id = ref.name.split('/').last.to_i
next unless id > max_iid
project.deployments.find(id).create_ref
project.repository.delete_refs(ref)
end
end
end
end
end
......@@ -342,8 +342,9 @@ describe 'Merge request > User resolves diff notes and discussions', :js do
end
end
it 'shows jump to next discussion button' do
expect(page.all('.discussion-reply-holder', count: 2)).to all(have_selector('.discussion-next-btn'))
it 'shows jump to next discussion button, apart from the last one' do
expect(page).to have_selector('.discussion-reply-holder', count: 2)
expect(page).to have_selector('.discussion-reply-holder .discussion-next-btn', count: 1)
end
it 'displays next discussion even if hidden' do
......
......@@ -38,7 +38,7 @@ describe('new file modal component', () => {
});
it(`sets form label as ${type}`, () => {
expect(vm.$el.querySelector('.label-light').textContent.trim()).toBe('Name');
expect(vm.$el.querySelector('.label-bold').textContent.trim()).toBe('Name');
});
describe('createEntryInStore', () => {
......
import router from '~/ide/ide_router';
import store from '~/ide/stores';
describe('IDE router', () => {
const PROJECT_NAMESPACE = 'my-group/sub-group';
const PROJECT_NAME = 'my-project';
afterEach(() => {
router.push('/');
});
afterAll(() => {
// VueRouter leaves this window.history at the "base" url. We need to clean this up.
window.history.replaceState({}, '', '/');
});
[
`/project/${PROJECT_NAMESPACE}/${PROJECT_NAME}/tree/master/-/src/blob/`,
`/project/${PROJECT_NAMESPACE}/${PROJECT_NAME}/tree/master/-/src/blob`,
`/project/${PROJECT_NAMESPACE}/${PROJECT_NAME}/tree/blob/-/src/blob`,
`/project/${PROJECT_NAMESPACE}/${PROJECT_NAME}/tree/master/-/src/tree/`,
`/project/${PROJECT_NAMESPACE}/${PROJECT_NAME}/tree/weird:branch/name-123/-/src/tree/`,
`/project/${PROJECT_NAMESPACE}/${PROJECT_NAME}/blob/master/-/src/blob`,
`/project/${PROJECT_NAMESPACE}/${PROJECT_NAME}/blob/master/-/src/edit`,
`/project/${PROJECT_NAMESPACE}/${PROJECT_NAME}/blob/master/-/src/merge_requests/2`,
`/project/${PROJECT_NAMESPACE}/${PROJECT_NAME}/blob/blob/-/src/blob`,
`/project/${PROJECT_NAMESPACE}/${PROJECT_NAME}/edit/blob/-/src/blob`,
`/project/${PROJECT_NAMESPACE}/${PROJECT_NAME}/merge_requests/2`,
`/project/${PROJECT_NAMESPACE}/${PROJECT_NAME}/tree/blob`,
`/project/${PROJECT_NAMESPACE}/${PROJECT_NAME}/edit`,
`/project/${PROJECT_NAMESPACE}/${PROJECT_NAME}`,
].forEach(route => {
it(`finds project path when route is "${route}"`, () => {
spyOn(store, 'dispatch').and.returnValue(new Promise(() => {}));
router.push(route);
expect(store.dispatch).toHaveBeenCalledWith('getProjectData', {
namespace: PROJECT_NAMESPACE,
projectId: PROJECT_NAME,
});
});
});
});
......@@ -46,7 +46,7 @@ describe('DiscussionCounter component', () => {
discussions,
});
setFixtures(`
<div data-discussion-id="${firstDiscussionId}"></div>
<div class="discussion" data-discussion-id="${firstDiscussionId}"></div>
`);
vm.jumpToFirstUnresolvedDiscussion();
......
......@@ -14,6 +14,7 @@ describe('noteable_discussion component', () => {
preloadFixtures(discussionWithTwoUnresolvedNotes);
beforeEach(() => {
window.mrTabs = {};
store = createStore();
store.dispatch('setNoteableData', noteableDataMock);
store.dispatch('setNotesData', notesDataMock);
......@@ -106,33 +107,29 @@ describe('noteable_discussion component', () => {
describe('methods', () => {
describe('jumpToNextDiscussion', () => {
it('expands next unresolved discussion', () => {
spyOn(vm, 'expandDiscussion').and.stub();
const discussions = [
discussionMock,
{
...discussionMock,
id: discussionMock.id + 1,
notes: [{ ...discussionMock.notes[0], resolvable: true, resolved: true }],
},
{
...discussionMock,
id: discussionMock.id + 2,
notes: [{ ...discussionMock.notes[0], resolvable: true, resolved: false }],
},
];
const nextDiscussionId = discussionMock.id + 2;
store.replaceState({
...store.state,
discussions,
});
setFixtures(`
<div data-discussion-id="${nextDiscussionId}"></div>
`);
it('expands next unresolved discussion', done => {
const discussion2 = getJSONFixture(discussionWithTwoUnresolvedNotes)[0];
discussion2.resolved = false;
discussion2.id = 'next'; // prepare this for being identified as next one (to be jumped to)
vm.$store.dispatch('setInitialNotes', [discussionMock, discussion2]);
window.mrTabs.currentAction = 'show';
Vue.nextTick()
.then(() => {
spyOn(vm, 'expandDiscussion').and.stub();
const nextDiscussionId = discussion2.id;
vm.jumpToNextDiscussion();
setFixtures(`
<div class="discussion" data-discussion-id="${nextDiscussionId}"></div>
`);
expect(vm.expandDiscussion).toHaveBeenCalledWith({ discussionId: nextDiscussionId });
vm.jumpToNextDiscussion();
expect(vm.expandDiscussion).toHaveBeenCalledWith({ discussionId: nextDiscussionId });
})
.then(done)
.catch(done.fail);
});
});
});
......
......@@ -1168,3 +1168,87 @@ export const collapsedSystemNotes = [
diff_discussion: false,
},
];
export const discussion1 = {
id: 'abc1',
resolvable: true,
resolved: false,
diff_file: {
file_path: 'about.md',
},
position: {
formatter: {
new_line: 50,
old_line: null,
},
},
notes: [
{
created_at: '2018-07-04T16:25:41.749Z',
},
],
};
export const resolvedDiscussion1 = {
id: 'abc1',
resolvable: true,
resolved: true,
diff_file: {
file_path: 'about.md',
},
position: {
formatter: {
new_line: 50,
old_line: null,
},
},
notes: [
{
created_at: '2018-07-04T16:25:41.749Z',
},
],
};
export const discussion2 = {
id: 'abc2',
resolvable: true,
resolved: false,
diff_file: {
file_path: 'README.md',
},
position: {
formatter: {
new_line: null,
old_line: 20,
},
},
notes: [
{
created_at: '2018-07-04T12:05:41.749Z',
},
],
};
export const discussion3 = {
id: 'abc3',
resolvable: true,
resolved: false,
diff_file: {
file_path: 'README.md',
},
position: {
formatter: {
new_line: 21,
old_line: null,
},
},
notes: [
{
created_at: '2018-07-05T17:25:41.749Z',
},
],
};
export const unresolvableDiscussion = {
resolvable: false,
};
......@@ -5,6 +5,11 @@ import {
noteableDataMock,
individualNote,
collapseNotesMock,
discussion1,
discussion2,
discussion3,
resolvedDiscussion1,
unresolvableDiscussion,
} from '../mock_data';
const discussionWithTwoUnresolvedNotes = 'merge_requests/resolved_diff_discussion.json';
......@@ -109,4 +114,154 @@ describe('Getters Notes Store', () => {
expect(getters.isNotesFetched(state)).toBeFalsy();
});
});
describe('allResolvableDiscussions', () => {
it('should return only resolvable discussions in same order', () => {
const localGetters = {
allDiscussions: [
discussion3,
unresolvableDiscussion,
discussion1,
unresolvableDiscussion,
discussion2,
],
};
expect(getters.allResolvableDiscussions(state, localGetters)).toEqual([
discussion3,
discussion1,
discussion2,
]);
});
it('should return empty array if there are no resolvable discussions', () => {
const localGetters = {
allDiscussions: [unresolvableDiscussion, unresolvableDiscussion],
};
expect(getters.allResolvableDiscussions(state, localGetters)).toEqual([]);
});
});
describe('unresolvedDiscussionsIdsByDiff', () => {
it('should return all discussions IDs in diff order', () => {
const localGetters = {
allResolvableDiscussions: [discussion3, discussion1, discussion2],
};
expect(getters.unresolvedDiscussionsIdsByDiff(state, localGetters)).toEqual([
'abc1',
'abc2',
'abc3',
]);
});
it('should return empty array if all discussions have been resolved', () => {
const localGetters = {
allResolvableDiscussions: [resolvedDiscussion1],
};
expect(getters.unresolvedDiscussionsIdsByDiff(state, localGetters)).toEqual([]);
});
});
describe('unresolvedDiscussionsIdsByDate', () => {
it('should return all discussions in date ascending order', () => {
const localGetters = {
allResolvableDiscussions: [discussion3, discussion1, discussion2],
};
expect(getters.unresolvedDiscussionsIdsByDate(state, localGetters)).toEqual([
'abc2',
'abc1',
'abc3',
]);
});
it('should return empty array if all discussions have been resolved', () => {
const localGetters = {
allResolvableDiscussions: [resolvedDiscussion1],
};
expect(getters.unresolvedDiscussionsIdsByDate(state, localGetters)).toEqual([]);
});
});
describe('unresolvedDiscussionsIdsOrdered', () => {
const localGetters = {
unresolvedDiscussionsIdsByDate: ['123', '456'],
unresolvedDiscussionsIdsByDiff: ['abc', 'def'],
};
it('should return IDs ordered by diff when diffOrder param is true', () => {
expect(getters.unresolvedDiscussionsIdsOrdered(state, localGetters)(true)).toEqual([
'abc',
'def',
]);
});
it('should return IDs ordered by date when diffOrder param is not true', () => {
expect(getters.unresolvedDiscussionsIdsOrdered(state, localGetters)(false)).toEqual([
'123',
'456',
]);
expect(getters.unresolvedDiscussionsIdsOrdered(state, localGetters)(undefined)).toEqual([
'123',
'456',
]);
});
});
describe('isLastUnresolvedDiscussion', () => {
const localGetters = {
unresolvedDiscussionsIdsOrdered: () => ['123', '456', '789'],
};
it('should return true if the discussion id provided is the last', () => {
expect(getters.isLastUnresolvedDiscussion(state, localGetters)('789')).toBe(true);
});
it('should return false if the discussion id provided is not the last', () => {
expect(getters.isLastUnresolvedDiscussion(state, localGetters)('123')).toBe(false);
expect(getters.isLastUnresolvedDiscussion(state, localGetters)('456')).toBe(false);
});
});
describe('nextUnresolvedDiscussionId', () => {
const localGetters = {
unresolvedDiscussionsIdsOrdered: () => ['123', '456', '789'],
};
it('should return the ID of the discussion after the ID provided', () => {
expect(getters.nextUnresolvedDiscussionId(state, localGetters)('123')).toBe('456');
expect(getters.nextUnresolvedDiscussionId(state, localGetters)('456')).toBe('789');
expect(getters.nextUnresolvedDiscussionId(state, localGetters)('789')).toBe(undefined);
});
});
describe('firstUnresolvedDiscussionId', () => {
const localGetters = {
unresolvedDiscussionsIdsByDate: ['123', '456'],
unresolvedDiscussionsIdsByDiff: ['abc', 'def'],
};
it('should return the first discussion id by diff when diffOrder param is true', () => {
expect(getters.firstUnresolvedDiscussionId(state, localGetters)(true)).toBe('abc');
});
it('should return the first discussion id by date when diffOrder param is not true', () => {
expect(getters.firstUnresolvedDiscussionId(state, localGetters)(false)).toBe('123');
expect(getters.firstUnresolvedDiscussionId(state, localGetters)(undefined)).toBe('123');
});
it('should be falsy if all discussions are resolved', () => {
const localGettersFalsy = {
unresolvedDiscussionsIdsByDiff: [],
unresolvedDiscussionsIdsByDate: [],
};
expect(getters.firstUnresolvedDiscussionId(state, localGettersFalsy)(true)).toBeFalsy();
expect(getters.firstUnresolvedDiscussionId(state, localGettersFalsy)(false)).toBeFalsy();
});
});
});
......@@ -75,6 +75,14 @@ describe Gitlab::Ci::Variables::Collection::Item do
expect(resource).to eq variable
end
it 'supports using a hash with stringified values' do
variable = { 'key' => 'VARIABLE', 'value' => 'my value' }
resource = described_class.fabricate(variable)
expect(resource).to eq(key: 'VARIABLE', value: 'my value')
end
it 'supports using an active record resource' do
variable = create(:ci_variable, key: 'CI_VAR', value: '123')
resource = described_class.fabricate(variable)
......
......@@ -527,25 +527,6 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
end
describe "#remote_update" do
before(:all) do
@repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '')
@repo.remote_update("expendable", url: TEST_NORMAL_REPO_PATH)
end
it "should add the remote" do
rugged = Gitlab::GitalyClient::StorageSettings.allow_disk_access { @repo.rugged }
expect(rugged.remotes["expendable"].url).to(
eq(TEST_NORMAL_REPO_PATH)
)
end
after(:all) do
ensure_seeds
end
end
describe '#fetch_repository_as_mirror' do
let(:new_repository) do
Gitlab::Git::Repository.new('default', 'my_project.git', '')
......
......@@ -64,6 +64,49 @@ describe Gitlab::ProjectSearchResults do
end
end
shared_examples 'blob search repository ref' do |entity_type|
let(:query) { 'files' }
let(:file_finder) { double }
let(:project_branch) { 'project_branch' }
subject(:results) { described_class.new(user, project, query, repository_ref).objects(blob_type) }
before do
allow(entity).to receive(:default_branch).and_return(project_branch)
allow(file_finder).to receive(:find).and_return([])
end
context 'when repository_ref exists' do
let(:repository_ref) { 'ref_branch' }
it 'uses it' do
expect(Gitlab::FileFinder).to receive(:new).with(project, repository_ref).and_return(file_finder)
results
end
end
context 'when repository_ref is not present' do
let(:repository_ref) { nil }
it "uses #{entity_type} repository default reference" do
expect(Gitlab::FileFinder).to receive(:new).with(project, project_branch).and_return(file_finder)
results
end
end
context 'when repository_ref is blank' do
let(:repository_ref) { '' }
it "uses #{entity_type} repository default reference" do
expect(Gitlab::FileFinder).to receive(:new).with(project, project_branch).and_return(file_finder)
results
end
end
end
describe 'blob search' do
let(:project) { create(:project, :public, :repository) }
......@@ -75,6 +118,11 @@ describe Gitlab::ProjectSearchResults do
let(:expected_file_by_content) { 'CHANGELOG' }
end
it_behaves_like 'blob search repository ref', 'project' do
let(:blob_type) { 'blobs' }
let(:entity) { project }
end
describe 'parsing results' do
let(:results) { project.repository.search_files_by_content('feature', 'master') }
let(:search_result) { results.first }
......@@ -212,6 +260,11 @@ describe Gitlab::ProjectSearchResults do
let(:expected_file_by_name) { 'Files/Title.md' }
let(:expected_file_by_content) { 'CHANGELOG.md' }
end
it_behaves_like 'blob search repository ref', 'wiki' do
let(:blob_type) { 'wiki_blobs' }
let(:entity) { project.wiki }
end
end
it 'does not list issues on private projects' do
......
require 'spec_helper'
require 'fast_spec_helper'
describe Gitlab::Serializer::Ci::Variables do
subject do
......@@ -6,11 +6,11 @@ describe Gitlab::Serializer::Ci::Variables do
end
let(:object) do
[{ key: :key, value: 'value', public: true },
[{ 'key' => :key, 'value' => 'value', 'public' => true },
{ key: 'wee', value: 1, public: false }]
end
it 'converts keys into strings' do
it 'converts keys into strings and symbolizes hash' do
is_expected.to eq([
{ key: 'key', value: 'value', public: true },
{ key: 'wee', value: 1, public: false }
......
......@@ -4,14 +4,11 @@ require 'spec_helper'
require Rails.root.join('db', 'migrate', '20161124141322_migrate_process_commit_worker_jobs.rb')
describe MigrateProcessCommitWorkerJobs do
let(:project) { create(:project, :legacy_storage, :repository) } # rubocop:disable RSpec/FactoriesInMigrationSpecs
let(:user) { create(:user) } # rubocop:disable RSpec/FactoriesInMigrationSpecs
let(:rugged) do
Gitlab::GitalyClient::StorageSettings.allow_disk_access do
project.repository.rugged
end
set(:project) { create(:project, :legacy_storage, :repository) } # rubocop:disable RSpec/FactoriesInMigrationSpecs
set(:user) { create(:user) } # rubocop:disable RSpec/FactoriesInMigrationSpecs
let(:commit) do
Gitlab::Git::Commit.last(project.repository.raw)
end
let(:commit) { rugged.rev_parse(project.commit.id) }
describe 'Project' do
describe 'find_including_path' do
......@@ -29,32 +26,13 @@ describe MigrateProcessCommitWorkerJobs do
end
end
describe '#repository_storage_path' do
it 'returns the storage path for the repository' do
migration_project = described_class::Project
.find_including_path(project.id)
expect(File.directory?(migration_project.repository_storage_path))
.to eq(true)
end
end
describe '#repository_path' do
it 'returns the path to the repository' do
migration_project = described_class::Project
.find_including_path(project.id)
expect(File.directory?(migration_project.repository_path)).to eq(true)
end
end
describe '#repository' do
it 'returns a Rugged::Repository' do
it 'returns a mock implemention of ::Repository' do
migration_project = described_class::Project
.find_including_path(project.id)
expect(migration_project.repository)
.to be_an_instance_of(Rugged::Repository)
expect(migration_project.repository).to respond_to(:storage)
expect(migration_project.repository).to respond_to(:gitaly_repository)
end
end
end
......@@ -72,7 +50,7 @@ describe MigrateProcessCommitWorkerJobs do
before do
Sidekiq.redis do |redis|
job = JSON.dump(args: [project.id, user.id, commit.oid])
job = JSON.dump(args: [project.id, user.id, commit.id])
redis.lpush('queue:process_commit', job)
end
end
......@@ -88,9 +66,10 @@ describe MigrateProcessCommitWorkerJobs do
end
it 'skips jobs using commits that no longer exist' do
allow_any_instance_of(Rugged::Repository).to receive(:lookup)
.with(commit.oid)
.and_raise(Rugged::OdbError)
allow_any_instance_of(Gitlab::GitalyClient::CommitService)
.to receive(:find_commit)
.with(commit.id)
.and_return(nil)
migration.up
......@@ -104,11 +83,7 @@ describe MigrateProcessCommitWorkerJobs do
end
it 'encodes data to UTF-8' do
allow_any_instance_of(Rugged::Repository).to receive(:lookup)
.with(commit.oid)
.and_return(commit)
allow(commit).to receive(:message)
allow(commit).to receive(:body)
.and_return('김치'.force_encoding('BINARY'))
migration.up
......@@ -140,7 +115,7 @@ describe MigrateProcessCommitWorkerJobs do
end
it 'includes the commit ID' do
expect(commit_hash['id']).to eq(commit.oid)
expect(commit_hash['id']).to eq(commit.id)
end
it 'includes the commit message' do
......@@ -152,27 +127,27 @@ describe MigrateProcessCommitWorkerJobs do
end
it 'includes the author date' do
expect(commit_hash['authored_date']).to eq(commit.author[:time].to_s)
expect(commit_hash['authored_date']).to eq(commit.authored_date.to_s)
end
it 'includes the author name' do
expect(commit_hash['author_name']).to eq(commit.author[:name])
expect(commit_hash['author_name']).to eq(commit.author_name)
end
it 'includes the author Email' do
expect(commit_hash['author_email']).to eq(commit.author[:email])
expect(commit_hash['author_email']).to eq(commit.author_email)
end
it 'includes the commit date' do
expect(commit_hash['committed_date']).to eq(commit.committer[:time].to_s)
expect(commit_hash['committed_date']).to eq(commit.committed_date.to_s)
end
it 'includes the committer name' do
expect(commit_hash['committer_name']).to eq(commit.committer[:name])
expect(commit_hash['committer_name']).to eq(commit.committer_name)
end
it 'includes the committer Email' do
expect(commit_hash['committer_email']).to eq(commit.committer[:email])
expect(commit_hash['committer_email']).to eq(commit.committer_email)
end
end
end
......@@ -186,7 +161,7 @@ describe MigrateProcessCommitWorkerJobs do
before do
Sidekiq.redis do |redis|
job = JSON.dump(args: [project.id, user.id, commit.oid])
job = JSON.dump(args: [project.id, user.id, commit.id])
redis.lpush('queue:process_commit', job)
migration.up
......@@ -215,7 +190,7 @@ describe MigrateProcessCommitWorkerJobs do
end
it 'includes the commit SHA' do
expect(job['args'][2]).to eq(commit.oid)
expect(job['args'][2]).to eq(commit.id)
end
end
end
......
......@@ -2269,6 +2269,34 @@ describe Ci::Build do
end
end
describe '#yaml_variables' do
before do
build.update_attribute(:yaml_variables, variables)
end
context 'when serialized valu is a symbolized hash' do
let(:variables) do
[{ key: :VARIABLE, value: 'my value 1' }]
end
it 'keeps symbolizes keys and stringifies variables names' do
expect(build.yaml_variables)
.to eq [{ key: 'VARIABLE', value: 'my value 1' }]
end
end
context 'when serialized value is a hash with string keys' do
let(:variables) do
[{ 'key' => :VARIABLE, 'value' => 'my value 2' }]
end
it 'symblizes variables hash' do
expect(build.yaml_variables)
.to eq [{ key: 'VARIABLE', value: 'my value 2' }]
end
end
end
describe 'state transition: any => [:pending]' do
let(:build) { create(:ci_build, :created) }
......
......@@ -4,6 +4,7 @@ rbac:
hub:
extraEnv:
JUPYTER_ENABLE_LAB: 1
SINGLEUSER_IMAGE: 'registry.gitlab.com/gitlab-org/jupyterhub-user-image:latest'
extraConfig: |
c.KubeSpawner.cmd = ['jupyter-labhub']
......
......@@ -3211,6 +3211,10 @@ form-data@~2.3.0, form-data@~2.3.1:
combined-stream "1.0.6"
mime-types "^2.1.12"
formdata-polyfill@^3.0.11:
version "3.0.11"
resolved "https://registry.yarnpkg.com/formdata-polyfill/-/formdata-polyfill-3.0.11.tgz#c82b4b4bea3356c0a6752219e54ce1edb2a7fb5b"
forwarded@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84"
......
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