Merge remote-tracking branch 'upstream/master' into 36089-handle-ref-failure-better
* upstream/master: (62 commits) Update gitlab.po: Missing 'r' in "Fouché" that comes from "Fourcher" verb. Docs: update user docs index Fix minor typos in views Fix Layout/SpaceBeforeBlockBraces violation in bin/changelog_spec Merge branch 'rs-alphanumeric-ssh-params' into 'security-9-4' Merge branch 'import-symlinks-9-3' into 'security-9-3' Fix wrong method call on prometheus histogram Document new all-in-one Helm chart - docs Fix 404 on link path Fix line numbers not matching up to code in code viewer. Hide overflow-x on collapsed sidebar removed global use of breakpoint checker Increase performance of the breakpoint size checker Filter sensitive query string parameters from NGINX access logs Added a template for database changes Render new issue link in failed job as a regular link instead of a UJS one Include RE2 in the upgrade docs Remove affix plugin from issuable sidebar with new navigation Fix linter error alternative route for download archive ...
This commit is contained in:
commit
e04c1ae7c7
|
@ -0,0 +1,73 @@
|
|||
Remove this section and replace it with a description of your MR. Also follow the
|
||||
checklist below and check off any tasks that are done. If a certain task can not
|
||||
be done you should explain so in the MR body. You are free to remove any
|
||||
sections that do not apply to your MR.
|
||||
|
||||
When gathering statistics (e.g. the output of `EXPLAIN ANALYZE`) you should make
|
||||
sure your database has enough data. Having around 10 000 rows in the tables
|
||||
being queries should provide a reasonable estimate of how a query will behave.
|
||||
Also make sure that PostgreSQL uses the following settings:
|
||||
|
||||
* `random_page_cost`: `1`
|
||||
* `work_mem`: `16MB`
|
||||
* `maintenance_work_mem`: at least `64MB`
|
||||
* `shared_buffers`: at least `256MB`
|
||||
|
||||
If you have access to GitLab.com's staging environment you should also run your
|
||||
measurements there, and include the results in this MR.
|
||||
|
||||
## Database Checklist
|
||||
|
||||
When adding migrations:
|
||||
|
||||
- [ ] Updated `db/schema.rb`
|
||||
- [ ] Added a `down` method so the migration can be reverted
|
||||
- [ ] Added the output of the migration(s) to the MR body
|
||||
- [ ] Added the execution time of the migration(s) to the MR body
|
||||
- [ ] Added tests for the migration in `spec/migrations` if necessary (e.g. when
|
||||
migrating data)
|
||||
- [ ] Made sure the migration won't interfere with a running GitLab cluster,
|
||||
for example by disabling transactions for long running migrations
|
||||
|
||||
When adding or modifying queries to improve performance:
|
||||
|
||||
- [ ] Included the raw SQL queries of the relevant queries
|
||||
- [ ] Included the output of `EXPLAIN ANALYZE` and execution timings of the
|
||||
relevant queries
|
||||
- [ ] Added tests for the relevant changes
|
||||
|
||||
When adding indexes:
|
||||
|
||||
- [ ] Described the need for these indexes in the MR body
|
||||
- [ ] Made sure existing indexes can not be reused instead
|
||||
|
||||
When adding foreign keys to existing tables:
|
||||
|
||||
- [ ] Included a migration to remove orphaned rows in the source table
|
||||
- [ ] Removed any instances of `dependent: ...` that may no longer be necessary
|
||||
|
||||
When adding tables:
|
||||
|
||||
- [ ] Ordered columns based on their type sizes in descending order
|
||||
- [ ] Added foreign keys if necessary
|
||||
- [ ] Added indexes if necessary
|
||||
|
||||
When removing columns, tables, indexes or other structures:
|
||||
|
||||
- [ ] Removed these in a post-deployment migration
|
||||
- [ ] Made sure the application no longer uses (or ignores) these structures
|
||||
|
||||
## General Checklist
|
||||
|
||||
- [ ] [Changelog entry](https://docs.gitlab.com/ce/development/changelog.html) added, if necessary
|
||||
- [ ] [Documentation created/updated](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/development/doc_styleguide.md)
|
||||
- [ ] API support added
|
||||
- [ ] Tests added for this feature/bug
|
||||
- Review
|
||||
- [ ] Has been reviewed by UX
|
||||
- [ ] Has been reviewed by Frontend
|
||||
- [ ] Has been reviewed by Backend
|
||||
- [ ] Has been reviewed by Database
|
||||
- [ ] Conform by the [merge request performance guides](http://docs.gitlab.com/ce/development/merge_request_performance_guidelines.html)
|
||||
- [ ] Conform by the [style guides](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#style-guides)
|
||||
- [ ] [Squashed related commits together](https://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits)
|
|
@ -207,6 +207,13 @@ Layout/SpaceAroundKeyword:
|
|||
Layout/SpaceAroundOperators:
|
||||
Enabled: true
|
||||
|
||||
# Checks that block braces have or don't have a space before the opening
|
||||
# brace depending on configuration.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: space, no_space
|
||||
Layout/SpaceBeforeBlockBraces:
|
||||
Enabled: true
|
||||
|
||||
# No spaces before commas.
|
||||
Layout/SpaceBeforeComma:
|
||||
Enabled: true
|
||||
|
|
|
@ -26,13 +26,6 @@ Layout/IndentArray:
|
|||
Layout/IndentHash:
|
||||
Enabled: false
|
||||
|
||||
# Offense count: 174
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
||||
# SupportedStyles: space, no_space
|
||||
Layout/SpaceBeforeBlockBraces:
|
||||
Enabled: false
|
||||
|
||||
# Offense count: 8
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: AllowForAlignment.
|
||||
|
|
30
CHANGELOG.md
30
CHANGELOG.md
|
@ -2,6 +2,11 @@
|
|||
documentation](doc/development/changelog.md) for instructions on adding your own
|
||||
entry.
|
||||
|
||||
## 9.4.4 (2017-08-09)
|
||||
|
||||
- Remove hidden symlinks from project import files.
|
||||
- Disallow Git URLs that include a username or hostname beginning with a non-alphanumeric character.
|
||||
|
||||
## 9.4.3 (2017-07-31)
|
||||
|
||||
- Fix Prometheus client PID reuse bug. !13130
|
||||
|
@ -226,6 +231,11 @@ entry.
|
|||
- Log rescued exceptions to Sentry.
|
||||
- Remove remaining N+1 queries in merge requests API with emojis and labels.
|
||||
|
||||
## 9.3.10 (2017-08-09)
|
||||
|
||||
- Remove hidden symlinks from project import files.
|
||||
- Disallow Git URLs that include a username or hostname beginning with a non-alphanumeric character.
|
||||
|
||||
## 9.3.9 (2017-07-20)
|
||||
|
||||
- Fix an infinite loop when handling user-supplied regular expressions.
|
||||
|
@ -498,6 +508,11 @@ entry.
|
|||
- Remove foreigh key on ci_trigger_schedules only if it exists.
|
||||
- Allow translation of Pipeline Schedules.
|
||||
|
||||
## 9.2.10 (2017-08-09)
|
||||
|
||||
- Remove hidden symlinks from project import files.
|
||||
- Disallow Git URLs that include a username or hostname beginning with a non-alphanumeric character.
|
||||
|
||||
## 9.2.9 (2017-07-20)
|
||||
|
||||
- Fix an infinite loop when handling user-supplied regular expressions.
|
||||
|
@ -753,6 +768,11 @@ entry.
|
|||
- Fix preemptive scroll bar on user activity calendar.
|
||||
- Pipeline chat notifications convert seconds to minutes and hours.
|
||||
|
||||
## 9.1.10 (2017-08-09)
|
||||
|
||||
- Remove hidden symlinks from project import files.
|
||||
- Disallow Git URLs that include a username or hostname beginning with a non-alphanumeric character.
|
||||
|
||||
## 9.1.9 (2017-07-20)
|
||||
|
||||
- Fix an infinite loop when handling user-supplied regular expressions.
|
||||
|
@ -1076,6 +1096,11 @@ entry.
|
|||
- Only send chat notifications for the default branch.
|
||||
- Don't fill in the default kubernetes namespace.
|
||||
|
||||
## 9.0.13 (2017-08-09)
|
||||
|
||||
- Remove hidden symlinks from project import files.
|
||||
- Disallow Git URLs that include a username or hostname beginning with a non-alphanumeric character.
|
||||
|
||||
## 9.0.12 (2017-07-20)
|
||||
|
||||
- Fix an infinite loop when handling user-supplied regular expressions.
|
||||
|
@ -1456,6 +1481,11 @@ entry.
|
|||
- Change development tanuki favicon colors to match logo color order.
|
||||
- API issues - support filtering by iids.
|
||||
|
||||
## 8.17.8 (2017-08-09)
|
||||
|
||||
- Remove hidden symlinks from project import files.
|
||||
- Disallow Git URLs that include a username or hostname beginning with a non-alphanumeric character.
|
||||
|
||||
## 8.17.7 (2017-07-19)
|
||||
|
||||
- Renders 404 if given project is not readable by the user on Todos dashboard.
|
||||
|
|
|
@ -744,6 +744,7 @@ GEM
|
|||
rubocop-gitlab-security (0.0.6)
|
||||
rubocop (>= 0.47.1)
|
||||
rubocop-rspec (1.15.1)
|
||||
rubocop (>= 0.42.0)
|
||||
ruby-fogbugz (0.2.1)
|
||||
crack (~> 0.4)
|
||||
ruby-prof (0.16.2)
|
||||
|
|
37
PROCESS.md
37
PROCESS.md
|
@ -119,6 +119,12 @@ only be left until after the freeze if:
|
|||
are aware of it.
|
||||
* It is in the correct milestone, with the ~Deliverable label.
|
||||
|
||||
If a merge request is not ready, but the developers and Product Manager
|
||||
responsible for the feature think it is essential that it is in the release,
|
||||
they can [ask for an exception](#asking-for-an-exception) in advance. This is
|
||||
preferable to merging something that we are not confident in, but should still
|
||||
be a rare case: most features can be allowed to slip a release.
|
||||
|
||||
All Community Edition merge requests from GitLab team members merged on the
|
||||
freeze date (the 7th) should have a corresponding Enterprise Edition merge
|
||||
request, even if there are no conflicts. This is to reduce the size of the
|
||||
|
@ -128,11 +134,26 @@ information, see
|
|||
|
||||
### After the 7th
|
||||
|
||||
Once the stable branch is frozen, only fixes for [regressions](#regressions)
|
||||
and security issues will be cherry-picked into the stable branch.
|
||||
Any merge requests cherry-picked into the stable branch for a previous release will also be picked into the latest stable branch.
|
||||
These fixes will be shipped in the next RC for that release if it is before the 22nd.
|
||||
If the fixes are are completed on or after the 22nd, they will be shipped in a patch for that release.
|
||||
Once the stable branch is frozen, the only MRs that can be cherry-picked into
|
||||
the stable branch are:
|
||||
|
||||
* Fixes for [regressions](#regressions)
|
||||
* Fixes for security issues
|
||||
* New or updated translations (as long as they do not touch application code)
|
||||
|
||||
Any merge requests cherry-picked into the stable branch for a previous release
|
||||
will also be picked into the latest stable branch. These fixes will be shipped
|
||||
in the next RC for that release if it is before the 22nd. If the fixes are are
|
||||
completed on or after the 22nd, they will be shipped in a patch for that
|
||||
release.
|
||||
|
||||
During the feature freeze all merge requests that are meant to go into the upcoming
|
||||
release should have the correct milestone assigned _and_ have the label
|
||||
~"Pick into Stable" set, so that release managers can find and pick them.
|
||||
Merge requests without a milestone and this label will
|
||||
not be merged into any stable branches.
|
||||
|
||||
### Asking for an exception
|
||||
|
||||
If you think a merge request should go into an RC or patch even though it does not meet these requirements,
|
||||
you can ask for an exception to be made. Exceptions require sign-off from 3 people besides the developer:
|
||||
|
@ -152,11 +173,7 @@ When in doubt, we err on the side of _not_ cherry-picking.
|
|||
For example, it is likely that an exception will be made for a trivial 1-5 line performance improvement
|
||||
(e.g. adding a database index or adding `includes` to a query), but not for a new feature, no matter how relatively small or thoroughly tested.
|
||||
|
||||
During the feature freeze all merge requests that are meant to go into the upcoming
|
||||
release should have the correct milestone assigned _and_ have the label
|
||||
~"Pick into Stable" set, so that release managers can find and pick them.
|
||||
Merge requests without a milestone and this label will
|
||||
not be merged into any stable branches.
|
||||
All MRs which have had exceptions granted must be merged by the 15th.
|
||||
|
||||
### Regressions
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* global ListIssue */
|
||||
/* global bp */
|
||||
|
||||
import Vue from 'vue';
|
||||
import bp from '../../../breakpoints';
|
||||
|
||||
const ModalStore = gl.issueBoards.ModalStore;
|
||||
|
||||
|
|
|
@ -1,66 +1,19 @@
|
|||
/* eslint-disable func-names, space-before-function-paren, wrap-iife, one-var, no-var, one-var-declaration-per-line, quotes, no-shadow, prefer-arrow-callback, prefer-template, consistent-return, no-return-assign, new-parens, no-param-reassign, max-len */
|
||||
export const breakpoints = {
|
||||
lg: 1200,
|
||||
md: 992,
|
||||
sm: 768,
|
||||
xs: 0,
|
||||
};
|
||||
|
||||
var Breakpoints = (function() {
|
||||
var BreakpointInstance, instance;
|
||||
const BreakpointInstance = {
|
||||
windowWidth: () => window.innerWidth,
|
||||
getBreakpointSize() {
|
||||
const windowWidth = this.windowWidth();
|
||||
|
||||
function Breakpoints() {}
|
||||
const breakpoint = Object.keys(breakpoints).find(key => windowWidth > breakpoints[key]);
|
||||
|
||||
instance = null;
|
||||
return breakpoint;
|
||||
},
|
||||
};
|
||||
|
||||
BreakpointInstance = (function() {
|
||||
var BREAKPOINTS;
|
||||
|
||||
BREAKPOINTS = ["xs", "sm", "md", "lg"];
|
||||
|
||||
function BreakpointInstance() {
|
||||
this.setup();
|
||||
}
|
||||
|
||||
BreakpointInstance.prototype.setup = function() {
|
||||
var allDeviceSelector, els;
|
||||
allDeviceSelector = BREAKPOINTS.map(function(breakpoint) {
|
||||
return ".device-" + breakpoint;
|
||||
});
|
||||
if ($(allDeviceSelector.join(",")).length) {
|
||||
return;
|
||||
}
|
||||
// Create all the elements
|
||||
els = $.map(BREAKPOINTS, function(breakpoint) {
|
||||
return "<div class='device-" + breakpoint + " visible-" + breakpoint + "'></div>";
|
||||
});
|
||||
return $("body").append(els.join(''));
|
||||
};
|
||||
|
||||
BreakpointInstance.prototype.visibleDevice = function() {
|
||||
var allDeviceSelector;
|
||||
allDeviceSelector = BREAKPOINTS.map(function(breakpoint) {
|
||||
return ".device-" + breakpoint;
|
||||
});
|
||||
return $(allDeviceSelector.join(",")).filter(":visible");
|
||||
};
|
||||
|
||||
BreakpointInstance.prototype.getBreakpointSize = function() {
|
||||
var $visibleDevice;
|
||||
$visibleDevice = this.visibleDevice;
|
||||
// TODO: Consider refactoring in light of turbolinks removal.
|
||||
// the page refreshed via turbolinks
|
||||
if (!$visibleDevice().length) {
|
||||
this.setup();
|
||||
}
|
||||
$visibleDevice = this.visibleDevice();
|
||||
return $visibleDevice.attr("class").split("visible-")[1];
|
||||
};
|
||||
|
||||
return BreakpointInstance;
|
||||
})();
|
||||
|
||||
Breakpoints.get = function() {
|
||||
return instance != null ? instance : instance = new BreakpointInstance;
|
||||
};
|
||||
|
||||
return Breakpoints;
|
||||
})();
|
||||
|
||||
$(() => { window.bp = Breakpoints.get(); });
|
||||
|
||||
window.Breakpoints = Breakpoints;
|
||||
export default BreakpointInstance;
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
/* eslint-disable func-names, wrap-iife, no-use-before-define,
|
||||
consistent-return, prefer-rest-params */
|
||||
/* global Breakpoints */
|
||||
|
||||
import _ from 'underscore';
|
||||
import bp from './breakpoints';
|
||||
import { bytesToKiB } from './lib/utils/number_utils';
|
||||
|
||||
window.Build = (function () {
|
||||
|
@ -34,8 +33,6 @@ window.Build = (function () {
|
|||
this.$scrollBottomBtn = $('.js-scroll-down');
|
||||
|
||||
clearTimeout(Build.timeout);
|
||||
// Init breakpoint checker
|
||||
this.bp = Breakpoints.get();
|
||||
|
||||
this.initSidebar();
|
||||
this.populateJobs(this.buildStage);
|
||||
|
@ -230,7 +227,7 @@ window.Build = (function () {
|
|||
};
|
||||
|
||||
Build.prototype.shouldHideSidebarForViewport = function () {
|
||||
const bootstrapBreakpoint = this.bp.getBreakpointSize();
|
||||
const bootstrapBreakpoint = bp.getBreakpointSize();
|
||||
return bootstrapBreakpoint === 'xs' || bootstrapBreakpoint === 'sm';
|
||||
};
|
||||
|
||||
|
|
|
@ -76,6 +76,7 @@ import initLegacyFilters from './init_legacy_filters';
|
|||
import initIssuableSidebar from './init_issuable_sidebar';
|
||||
import GpgBadges from './gpg_badges';
|
||||
import UserFeatureHelper from './helpers/user_feature_helper';
|
||||
import initChangesDropdown from './init_changes_dropdown';
|
||||
|
||||
(function() {
|
||||
var Dispatcher;
|
||||
|
@ -228,6 +229,7 @@ import UserFeatureHelper from './helpers/user_feature_helper';
|
|||
break;
|
||||
case 'projects:compare:show':
|
||||
new gl.Diff();
|
||||
initChangesDropdown();
|
||||
break;
|
||||
case 'projects:branches:new':
|
||||
case 'projects:branches:create':
|
||||
|
@ -320,6 +322,7 @@ import UserFeatureHelper from './helpers/user_feature_helper';
|
|||
container: '.js-commit-pipeline-graph',
|
||||
}).bindEvents();
|
||||
initNotes();
|
||||
initChangesDropdown();
|
||||
$('.commit-info.branches').load(document.querySelector('.js-commit-box').dataset.commitPath);
|
||||
break;
|
||||
case 'projects:commit:pipelines':
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* eslint-disable wrap-iife, func-names, space-before-function-paren, comma-dangle, prefer-template, consistent-return, class-methods-use-this, arrow-body-style, no-unused-vars, no-underscore-dangle, no-new, max-len, no-sequences, no-unused-expressions, no-param-reassign */
|
||||
/* global dateFormat */
|
||||
/* global Pikaday */
|
||||
|
||||
import Pikaday from 'pikaday';
|
||||
import DateFix from './lib/utils/datefix';
|
||||
|
||||
class DueDateSelect {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* global bp */
|
||||
import Cookies from 'js-cookie';
|
||||
import './breakpoints';
|
||||
import bp from './breakpoints';
|
||||
|
||||
export const canShowActiveSubItems = (el) => {
|
||||
const isHiddenByMedia = bp.getBreakpointSize() === 'sm' || bp.getBreakpointSize() === 'md';
|
||||
|
@ -49,7 +48,8 @@ export const hideSubLevelItems = (el) => {
|
|||
|
||||
el.classList.remove('is-showing-fly-out');
|
||||
el.classList.remove('is-over');
|
||||
subItems.style.display = 'none';
|
||||
subItems.style.display = '';
|
||||
subItems.style.transform = '';
|
||||
subItems.classList.remove('is-above');
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
import stickyMonitor from './lib/utils/sticky';
|
||||
|
||||
export default () => {
|
||||
stickyMonitor(document.querySelector('.js-diff-files-changed'));
|
||||
|
||||
$('.js-diff-stats-dropdown').glDropdown({
|
||||
filterable: true,
|
||||
remoteFilter: false,
|
||||
});
|
||||
};
|
|
@ -1,7 +1,6 @@
|
|||
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-new, comma-dangle, quotes, prefer-arrow-callback, consistent-return, one-var, no-var, one-var-declaration-per-line, no-underscore-dangle, max-len */
|
||||
/* global bp */
|
||||
|
||||
import Cookies from 'js-cookie';
|
||||
import bp from './breakpoints';
|
||||
import UsersSelect from './users_select';
|
||||
|
||||
const PARTICIPANTS_ROW_COUNT = 7;
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
/* global GitLab */
|
||||
/* global Autosave */
|
||||
/* global dateFormat */
|
||||
/* global Pikaday */
|
||||
|
||||
import Pikaday from 'pikaday';
|
||||
import UsersSelect from './users_select';
|
||||
import GfmAutoComplete from './gfm_auto_complete';
|
||||
import ZenMode from './zen_mode';
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
label: 'New issue',
|
||||
path: this.job.new_issue_path,
|
||||
cssClass: 'js-new-issue btn btn-new btn-inverted visible-md-block visible-lg-block',
|
||||
type: 'ujs-link',
|
||||
type: 'link',
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* eslint-disable func-names, space-before-function-paren, no-var, quotes, consistent-return, prefer-arrow-callback, comma-dangle, object-shorthand, no-new, max-len, no-multi-spaces, import/newline-after-import, import/first */
|
||||
/* global bp */
|
||||
/* global Flash */
|
||||
/* global ConfirmDangerModal */
|
||||
/* global Aside */
|
||||
|
@ -7,7 +6,6 @@
|
|||
import jQuery from 'jquery';
|
||||
import _ from 'underscore';
|
||||
import Cookies from 'js-cookie';
|
||||
import Pikaday from 'pikaday';
|
||||
import Dropzone from 'dropzone';
|
||||
import Sortable from 'vendor/Sortable';
|
||||
|
||||
|
@ -20,7 +18,6 @@ import 'vendor/fuzzaldrin-plus';
|
|||
window.jQuery = jQuery;
|
||||
window.$ = jQuery;
|
||||
window._ = _;
|
||||
window.Pikaday = Pikaday;
|
||||
window.Dropzone = Dropzone;
|
||||
window.Sortable = Sortable;
|
||||
|
||||
|
@ -68,7 +65,7 @@ import './api';
|
|||
import './aside';
|
||||
import './autosave';
|
||||
import loadAwardsHandler from './awards_handler';
|
||||
import './breakpoints';
|
||||
import bp from './breakpoints';
|
||||
import './broadcast_message';
|
||||
import './build';
|
||||
import './build_artifacts';
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
/* global Pikaday */
|
||||
/* global dateFormat */
|
||||
|
||||
import Pikaday from 'pikaday';
|
||||
|
||||
(() => {
|
||||
// Add datepickers to all `js-access-expiration-date` elements. If those elements are
|
||||
// children of an element with the `clearable-input` class, and have a sibling
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
/* eslint-disable no-new, class-methods-use-this */
|
||||
/* global Breakpoints */
|
||||
/* global Flash */
|
||||
/* global notes */
|
||||
|
||||
import Cookies from 'js-cookie';
|
||||
import './breakpoints';
|
||||
import './flash';
|
||||
import BlobForkSuggestion from './blob/blob_fork_suggestion';
|
||||
import stickyMonitor from './lib/utils/sticky';
|
||||
import initChangesDropdown from './init_changes_dropdown';
|
||||
import bp from './breakpoints';
|
||||
|
||||
/* eslint-disable max-len */
|
||||
// MergeRequestTabs
|
||||
|
@ -134,7 +133,7 @@ import stickyMonitor from './lib/utils/sticky';
|
|||
this.destroyPipelinesView();
|
||||
} else if (this.isDiffAction(action)) {
|
||||
this.loadDiff($target.attr('href'));
|
||||
if (Breakpoints.get().getBreakpointSize() !== 'lg') {
|
||||
if (bp.getBreakpointSize() !== 'lg') {
|
||||
this.shrinkView();
|
||||
}
|
||||
if (this.diffViewType() === 'parallel') {
|
||||
|
@ -145,7 +144,7 @@ import stickyMonitor from './lib/utils/sticky';
|
|||
this.resetViewContainer();
|
||||
this.mountPipelinesView();
|
||||
} else {
|
||||
if (Breakpoints.get().getBreakpointSize() !== 'xs') {
|
||||
if (bp.getBreakpointSize() !== 'xs') {
|
||||
this.expandView();
|
||||
}
|
||||
this.resetViewContainer();
|
||||
|
@ -267,9 +266,7 @@ import stickyMonitor from './lib/utils/sticky';
|
|||
const $container = $('#diffs');
|
||||
$container.html(data.html);
|
||||
|
||||
this.initChangesDropdown();
|
||||
|
||||
stickyMonitor(document.querySelector('.js-diff-files-changed'));
|
||||
initChangesDropdown();
|
||||
|
||||
if (typeof gl.diffNotesCompileComponents !== 'undefined') {
|
||||
gl.diffNotesCompileComponents();
|
||||
|
@ -319,13 +316,6 @@ import stickyMonitor from './lib/utils/sticky';
|
|||
});
|
||||
}
|
||||
|
||||
initChangesDropdown() {
|
||||
$('.js-diff-stats-dropdown').glDropdown({
|
||||
filterable: true,
|
||||
remoteFilter: false,
|
||||
});
|
||||
}
|
||||
|
||||
// Show or hide the loading spinner
|
||||
//
|
||||
// status - Boolean, true to show, false to hide
|
||||
|
@ -401,7 +391,7 @@ import stickyMonitor from './lib/utils/sticky';
|
|||
|
||||
// Screen space on small screens is usually very sparse
|
||||
// So we dont affix the tabs on these
|
||||
if (Breakpoints.get().getBreakpointSize() === 'xs' || !$tabs.length) return;
|
||||
if (bp.getBreakpointSize() === 'xs' || !$tabs.length) return;
|
||||
|
||||
/**
|
||||
If the browser does not support position sticky, it returns the position as static.
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<script>
|
||||
/* global Breakpoints */
|
||||
import d3 from 'd3';
|
||||
import monitoringLegends from './monitoring_legends.vue';
|
||||
import monitoringFlag from './monitoring_flag.vue';
|
||||
|
@ -8,6 +7,7 @@
|
|||
import eventHub from '../event_hub';
|
||||
import measurements from '../utils/measurements';
|
||||
import { formatRelevantDigits } from '../../lib/utils/number_utils';
|
||||
import bp from '../../breakpoints';
|
||||
|
||||
const bisectDate = d3.bisector(d => d.time).left;
|
||||
|
||||
|
@ -42,7 +42,6 @@
|
|||
yScale: {},
|
||||
margin: {},
|
||||
data: [],
|
||||
breakpointHandler: Breakpoints.get(),
|
||||
unitOfDisplay: '',
|
||||
areaColorRgb: '#8fbce8',
|
||||
lineColorRgb: '#1f78d1',
|
||||
|
@ -96,7 +95,7 @@
|
|||
|
||||
methods: {
|
||||
draw() {
|
||||
const breakpointSize = this.breakpointHandler.getBreakpointSize();
|
||||
const breakpointSize = bp.getBreakpointSize();
|
||||
const query = this.columnData.queries[0];
|
||||
this.margin = measurements.large.margin;
|
||||
if (breakpointSize === 'xs' || breakpointSize === 'sm') {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import Cookies from 'js-cookie';
|
||||
import _ from 'underscore';
|
||||
/* global bp */
|
||||
import './breakpoints';
|
||||
import bp from './breakpoints';
|
||||
|
||||
export default class NewNavSidebar {
|
||||
constructor() {
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
import _ from 'underscore';
|
||||
import Cookies from 'js-cookie';
|
||||
|
||||
export default {
|
||||
init() {
|
||||
if (!this.initialized) {
|
||||
if (Cookies.get('new_nav') === 'true' && $('.js-issuable-sidebar').length) return;
|
||||
|
||||
this.$window = $(window);
|
||||
this.$rightSidebar = $('.js-right-sidebar');
|
||||
this.$navHeight = $('.navbar-gitlab').outerHeight() +
|
||||
|
|
|
@ -120,7 +120,7 @@ export default {
|
|||
</a>
|
||||
|
||||
<a
|
||||
v-if="action.type === 'ujs-link'"
|
||||
v-else-if="action.type === 'ujs-link'"
|
||||
:href="action.path"
|
||||
data-method="post"
|
||||
rel="nofollow"
|
||||
|
@ -129,7 +129,7 @@ export default {
|
|||
</a>
|
||||
|
||||
<button
|
||||
v-else="action.type === 'button'"
|
||||
v-else-if="action.type === 'button'"
|
||||
@click="onClickAction(action)"
|
||||
:disabled="action.isLoading"
|
||||
:class="action.cssClass"
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
/* global Breakpoints */
|
||||
|
||||
import './breakpoints';
|
||||
import bp from './breakpoints';
|
||||
|
||||
export default class Wikis {
|
||||
constructor() {
|
||||
this.bp = Breakpoints.get();
|
||||
this.sidebarEl = document.querySelector('.js-wiki-sidebar');
|
||||
this.sidebarExpanded = false;
|
||||
|
||||
|
@ -41,15 +38,15 @@ export default class Wikis {
|
|||
this.renderSidebar();
|
||||
}
|
||||
|
||||
sidebarCanCollapse() {
|
||||
const bootstrapBreakpoint = this.bp.getBreakpointSize();
|
||||
static sidebarCanCollapse() {
|
||||
const bootstrapBreakpoint = bp.getBreakpointSize();
|
||||
return bootstrapBreakpoint === 'xs' || bootstrapBreakpoint === 'sm';
|
||||
}
|
||||
|
||||
renderSidebar() {
|
||||
if (!this.sidebarEl) return;
|
||||
const { classList } = this.sidebarEl;
|
||||
if (this.sidebarExpanded || !this.sidebarCanCollapse()) {
|
||||
if (this.sidebarExpanded || !Wikis.sidebarCanCollapse()) {
|
||||
if (!classList.contains('right-sidebar-expanded')) {
|
||||
classList.remove('right-sidebar-collapsed');
|
||||
classList.add('right-sidebar-expanded');
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
font-family: $monospace_font;
|
||||
display: block;
|
||||
font-size: $code_font_size !important;
|
||||
line-height: 19px;
|
||||
min-height: 19px;
|
||||
white-space: nowrap;
|
||||
|
||||
i {
|
||||
|
|
|
@ -103,12 +103,16 @@ $new-sidebar-collapsed-width: 50px;
|
|||
|
||||
&.sidebar-icons-only {
|
||||
width: $new-sidebar-collapsed-width;
|
||||
overflow-x: hidden;
|
||||
|
||||
.nav-item-name,
|
||||
.badge,
|
||||
.project-title {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.nav-item-name {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.nav-sidebar-expanded {
|
||||
|
@ -182,7 +186,7 @@ $new-sidebar-collapsed-width: 50px;
|
|||
|
||||
> li {
|
||||
a {
|
||||
padding: 8px 16px 8px 50px;
|
||||
padding: 8px 16px 8px 40px;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
|
@ -215,6 +219,10 @@ $new-sidebar-collapsed-width: 50px;
|
|||
|
||||
&:hover {
|
||||
color: $gl-text-color;
|
||||
|
||||
svg {
|
||||
fill: $gl-text-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -301,6 +309,7 @@ $new-sidebar-collapsed-width: 50px;
|
|||
|
||||
> a {
|
||||
margin-left: 4px;
|
||||
padding-left: 12px;
|
||||
}
|
||||
|
||||
.badge {
|
||||
|
@ -361,7 +370,7 @@ $new-sidebar-collapsed-width: 50px;
|
|||
|
||||
.sidebar-icons-only {
|
||||
.context-header {
|
||||
height: 60px;
|
||||
height: 61px;
|
||||
|
||||
a {
|
||||
padding: 10px 4px;
|
||||
|
|
|
@ -574,10 +574,14 @@
|
|||
@media (min-width: $screen-sm-min) {
|
||||
position: -webkit-sticky;
|
||||
position: sticky;
|
||||
top: 84px;
|
||||
top: 34px;
|
||||
background-color: $white-light;
|
||||
z-index: 190;
|
||||
|
||||
&.diff-files-changed-merge-request {
|
||||
top: 84px;
|
||||
}
|
||||
|
||||
+ .files,
|
||||
+ .alert {
|
||||
margin-top: 1px;
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
.commit-box,
|
||||
.info-well,
|
||||
.commit-ci-menu,
|
||||
.files-changed,
|
||||
.files-changed-inner,
|
||||
.limited-header-width,
|
||||
.limited-width-notes {
|
||||
@extend .fixed-width-container;
|
||||
|
|
|
@ -566,14 +566,14 @@ a.deploy-project-label {
|
|||
&::before {
|
||||
content: "OR";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 40%;
|
||||
left: -10px;
|
||||
top: 50%;
|
||||
z-index: 10;
|
||||
padding: 8px 0;
|
||||
text-align: center;
|
||||
background-color: $white-light;
|
||||
color: $gl-text-color-tertiary;
|
||||
transform: translateX(-50%);
|
||||
transform: translateY(-50%);
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
line-height: 20px;
|
||||
|
@ -581,8 +581,8 @@ a.deploy-project-label {
|
|||
// Mobile
|
||||
@media (max-width: $screen-xs-max) {
|
||||
left: 50%;
|
||||
top: 10px;
|
||||
transform: translateY(-50%);
|
||||
top: 0;
|
||||
transform: translateX(-50%);
|
||||
padding: 0 8px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -117,7 +117,7 @@ class ApplicationController < ActionController::Base
|
|||
Raven.capture_exception(exception) if sentry_enabled?
|
||||
|
||||
application_trace = ActionDispatch::ExceptionWrapper.new(env, exception).application_trace
|
||||
application_trace.map!{ |t| " #{t}\n" }
|
||||
application_trace.map! { |t| " #{t}\n" }
|
||||
logger.error "\n#{exception.class.name} (#{exception.message}):\n#{application_trace.join}"
|
||||
end
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ class Import::GitlabController < Import::BaseController
|
|||
@already_added_projects = current_user.created_projects.where(import_type: "gitlab")
|
||||
already_added_projects_names = @already_added_projects.pluck(:import_source)
|
||||
|
||||
@repos = @repos.to_a.reject{ |repo| already_added_projects_names.include? repo["path_with_namespace"] }
|
||||
@repos = @repos.to_a.reject { |repo| already_added_projects_names.include? repo["path_with_namespace"] }
|
||||
end
|
||||
|
||||
def jobs
|
||||
|
|
|
@ -257,18 +257,6 @@ class Projects::IssuesController < Projects::ApplicationController
|
|||
return render_404 unless @project.feature_available?(:issues, current_user)
|
||||
end
|
||||
|
||||
def redirect_to_external_issue_tracker
|
||||
external = @project.external_issue_tracker
|
||||
|
||||
return unless external
|
||||
|
||||
if action_name == 'new'
|
||||
redirect_to external.new_issue_path
|
||||
else
|
||||
redirect_to external.issue_tracker_path
|
||||
end
|
||||
end
|
||||
|
||||
def issue_params
|
||||
params.require(:issue).permit(*issue_params_attributes)
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@ module GraphHelper
|
|||
refs = ""
|
||||
# Commit::ref_names already strips the refs/XXX from important refs (e.g. refs/heads/XXX)
|
||||
# so anything leftover is internally used by GitLab
|
||||
commit_refs = commit.ref_names(repo).reject{ |name| name.starts_with?('refs/') }
|
||||
commit_refs = commit.ref_names(repo).reject { |name| name.starts_with?('refs/') }
|
||||
refs << commit_refs.join(' ')
|
||||
|
||||
# append note count
|
||||
|
|
|
@ -151,7 +151,7 @@ module IssuablesHelper
|
|||
end
|
||||
|
||||
def issuable_labels_tooltip(labels, limit: 5)
|
||||
first, last = labels.partition.with_index{ |_, i| i < limit }
|
||||
first, last = labels.partition.with_index { |_, i| i < limit }
|
||||
|
||||
label_names = first.collect(&:name)
|
||||
label_names << "and #{last.size} more" unless last.empty?
|
||||
|
@ -329,7 +329,7 @@ module IssuablesHelper
|
|||
end
|
||||
|
||||
def selected_template(issuable)
|
||||
params[:issuable_template] if issuable_templates(issuable).any?{ |template| template[:name] == params[:issuable_template] }
|
||||
params[:issuable_template] if issuable_templates(issuable).any? { |template| template[:name] == params[:issuable_template] }
|
||||
end
|
||||
|
||||
def issuable_todo_button_data(issuable, todo, is_collapsed)
|
||||
|
|
|
@ -206,7 +206,7 @@ module Network
|
|||
|
||||
# Visit branching chains
|
||||
leaves.each do |l|
|
||||
parents = l.parents(@map).select{|p| p.space.zero?}
|
||||
parents = l.parents(@map).select {|p| p.space.zero?}
|
||||
parents.each do |p|
|
||||
place_chain(p, l.time)
|
||||
end
|
||||
|
|
|
@ -77,20 +77,20 @@ class Note < ActiveRecord::Base
|
|||
|
||||
# Scopes
|
||||
scope :for_commit_id, ->(commit_id) { where(noteable_type: "Commit", commit_id: commit_id) }
|
||||
scope :system, ->{ where(system: true) }
|
||||
scope :user, ->{ where(system: false) }
|
||||
scope :common, ->{ where(noteable_type: ["", nil]) }
|
||||
scope :fresh, ->{ order(created_at: :asc, id: :asc) }
|
||||
scope :updated_after, ->(time){ where('updated_at > ?', time) }
|
||||
scope :inc_author_project, ->{ includes(:project, :author) }
|
||||
scope :inc_author, ->{ includes(:author) }
|
||||
scope :system, -> { where(system: true) }
|
||||
scope :user, -> { where(system: false) }
|
||||
scope :common, -> { where(noteable_type: ["", nil]) }
|
||||
scope :fresh, -> { order(created_at: :asc, id: :asc) }
|
||||
scope :updated_after, ->(time) { where('updated_at > ?', time) }
|
||||
scope :inc_author_project, -> { includes(:project, :author) }
|
||||
scope :inc_author, -> { includes(:author) }
|
||||
scope :inc_relations_for_view, -> do
|
||||
includes(:project, :author, :updated_by, :resolved_by, :award_emoji, :system_note_metadata)
|
||||
end
|
||||
|
||||
scope :diff_notes, ->{ where(type: %w(LegacyDiffNote DiffNote)) }
|
||||
scope :new_diff_notes, ->{ where(type: 'DiffNote') }
|
||||
scope :non_diff_notes, ->{ where(type: ['Note', 'DiscussionNote', nil]) }
|
||||
scope :diff_notes, -> { where(type: %w(LegacyDiffNote DiffNote)) }
|
||||
scope :new_diff_notes, -> { where(type: 'DiffNote') }
|
||||
scope :non_diff_notes, -> { where(type: ['Note', 'DiscussionNote', nil]) }
|
||||
|
||||
scope :with_associations, -> do
|
||||
# FYI noteable cannot be loaded for LegacyDiffNote for commits
|
||||
|
|
|
@ -8,5 +8,13 @@ class RedirectRoute < ActiveRecord::Base
|
|||
presence: true,
|
||||
uniqueness: { case_sensitive: false }
|
||||
|
||||
scope :matching_path_and_descendants, -> (path) { where('redirect_routes.path = ? OR redirect_routes.path LIKE ?', path, "#{sanitize_sql_like(path)}/%") }
|
||||
scope :matching_path_and_descendants, -> (path) do
|
||||
wheres = if Gitlab::Database.postgresql?
|
||||
'LOWER(redirect_routes.path) = LOWER(?) OR LOWER(redirect_routes.path) LIKE LOWER(?)'
|
||||
else
|
||||
'redirect_routes.path = ? OR redirect_routes.path LIKE ?'
|
||||
end
|
||||
|
||||
where(wheres, path, "#{sanitize_sql_like(path)}/%")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -148,6 +148,8 @@ class User < ActiveRecord::Base
|
|||
uniqueness: { case_sensitive: false }
|
||||
|
||||
validate :namespace_uniq, if: :username_changed?
|
||||
validate :namespace_move_dir_allowed, if: :username_changed?
|
||||
|
||||
validate :avatar_type, if: ->(user) { user.avatar.present? && user.avatar_changed? }
|
||||
validate :unique_email, if: :email_changed?
|
||||
validate :owns_notification_email, if: :notification_email_changed?
|
||||
|
@ -487,6 +489,12 @@ class User < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
|
||||
def namespace_move_dir_allowed
|
||||
if namespace&.any_project_has_container_registry_tags?
|
||||
errors.add(:username, 'cannot be changed if a personal project has container registry tags.')
|
||||
end
|
||||
end
|
||||
|
||||
def avatar_type
|
||||
unless avatar.image?
|
||||
errors.add :avatar, "only images allowed"
|
||||
|
|
|
@ -85,13 +85,13 @@ module Ci
|
|||
end
|
||||
|
||||
def register_failure
|
||||
failed_attempt_counter.increase
|
||||
attempt_counter.increase
|
||||
failed_attempt_counter.increment
|
||||
attempt_counter.increment
|
||||
end
|
||||
|
||||
def register_success(job)
|
||||
job_queue_duration_seconds.observe({ shared_runner: @runner.shared? }, Time.now - job.created_at)
|
||||
attempt_counter.increase
|
||||
attempt_counter.increment
|
||||
end
|
||||
|
||||
def failed_attempt_counter
|
||||
|
|
|
@ -16,6 +16,7 @@ module Issues
|
|||
spam_check(issue, current_user)
|
||||
issue.move_to_end
|
||||
|
||||
# current_user (defined in BaseService) is not available within run_after_commit block
|
||||
user = current_user
|
||||
issue.run_after_commit do
|
||||
NewIssueWorker.perform_async(issue.id, user.id)
|
||||
|
|
|
@ -17,6 +17,7 @@ module MergeRequests
|
|||
end
|
||||
|
||||
def before_create(merge_request)
|
||||
# current_user (defined in BaseService) is not available within run_after_commit block
|
||||
user = current_user
|
||||
merge_request.run_after_commit do
|
||||
NewMergeRequestWorker.perform_async(merge_request.id, user.id)
|
||||
|
|
|
@ -172,11 +172,11 @@ module Projects
|
|||
end
|
||||
|
||||
def register_attempt
|
||||
pages_deployments_total_counter.increase
|
||||
pages_deployments_total_counter.increment
|
||||
end
|
||||
|
||||
def register_failure
|
||||
pages_deployments_failed_total_counter.increase
|
||||
pages_deployments_failed_total_counter.increment
|
||||
end
|
||||
|
||||
def pages_deployments_total_counter
|
||||
|
|
|
@ -28,6 +28,6 @@
|
|||
%h3.blank-state-title
|
||||
Create a group
|
||||
%p.blank-state-text
|
||||
Groups are a great way to organise projects and people.
|
||||
Groups are a great way to organize projects and people.
|
||||
= link_to new_group_path, class: "btn btn-new" do
|
||||
New group
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
Customize how FogBugz email addresses and usernames are imported into GitLab.
|
||||
In the next step, you'll be able to select the projects you want to import.
|
||||
%p
|
||||
The user map is a mapping of the FogBugz users that participated on your projects to the way their email address and usernames wil be imported into GitLab. You can change this by populating the table below.
|
||||
The user map is a mapping of the FogBugz users that participated on your projects to the way their email address and usernames will be imported into GitLab. You can change this by populating the table below.
|
||||
%ul
|
||||
%li
|
||||
%strong Default: Map a FogBugz account ID to a full name
|
||||
|
|
|
@ -2,22 +2,24 @@
|
|||
- show_whitespace_toggle = local_assigns.fetch(:show_whitespace_toggle, true)
|
||||
- can_create_note = !@diff_notes_disabled && can?(current_user, :create_note, diffs.project)
|
||||
- diff_files = diffs.diff_files
|
||||
- merge_request = local_assigns.fetch(:merge_request, false)
|
||||
|
||||
.content-block.oneline-block.files-changed.diff-files-changed.js-diff-files-changed
|
||||
.inline-parallel-buttons
|
||||
- if !diffs_expanded? && diff_files.any? { |diff_file| diff_file.collapsed? }
|
||||
= link_to 'Expand all', url_for(params.merge(expanded: 1, format: nil)), class: 'btn btn-default'
|
||||
- if show_whitespace_toggle
|
||||
- if current_controller?(:commit)
|
||||
= commit_diff_whitespace_link(diffs.project, @commit, class: 'hidden-xs')
|
||||
- elsif current_controller?('projects/merge_requests/diffs')
|
||||
= diff_merge_request_whitespace_link(diffs.project, @merge_request, class: 'hidden-xs')
|
||||
- elsif current_controller?(:compare)
|
||||
= diff_compare_whitespace_link(diffs.project, params[:from], params[:to], class: 'hidden-xs')
|
||||
.btn-group
|
||||
= inline_diff_btn
|
||||
= parallel_diff_btn
|
||||
= render 'projects/diffs/stats', diff_files: diff_files
|
||||
.content-block.oneline-block.files-changed.diff-files-changed.js-diff-files-changed{ class: ("diff-files-changed-merge-request" if merge_request) }
|
||||
.files-changed-inner
|
||||
.inline-parallel-buttons
|
||||
- if !diffs_expanded? && diff_files.any? { |diff_file| diff_file.collapsed? }
|
||||
= link_to 'Expand all', url_for(params.merge(expanded: 1, format: nil)), class: 'btn btn-default'
|
||||
- if show_whitespace_toggle
|
||||
- if current_controller?(:commit)
|
||||
= commit_diff_whitespace_link(diffs.project, @commit, class: 'hidden-xs')
|
||||
- elsif current_controller?('projects/merge_requests/diffs')
|
||||
= diff_merge_request_whitespace_link(diffs.project, @merge_request, class: 'hidden-xs')
|
||||
- elsif current_controller?(:compare)
|
||||
= diff_compare_whitespace_link(diffs.project, params[:from], params[:to], class: 'hidden-xs')
|
||||
.btn-group
|
||||
= inline_diff_btn
|
||||
= parallel_diff_btn
|
||||
= render 'projects/diffs/stats', diff_files: diff_files
|
||||
|
||||
- if render_overflow_warning?(diff_files)
|
||||
= render 'projects/diffs/warning', diff_files: diffs
|
||||
|
|
|
@ -205,7 +205,7 @@
|
|||
%button.btn.js-settings-toggle
|
||||
= expanded ? 'Collapse' : 'Expand'
|
||||
%p
|
||||
Perform advanced options such as housekeeping, exporting, archiveing, renameing, transfering, or removeing your project.
|
||||
Perform advanced options such as housekeeping, exporting, archiving, renaming, transferring, or removing your project.
|
||||
.settings-content.no-animate{ class: ('expanded' if expanded) }
|
||||
.sub-section
|
||||
%h4 Housekeeping
|
||||
|
@ -274,7 +274,7 @@
|
|||
%li Be careful. Changing the project's namespace can have unintended side effects.
|
||||
%li You can only transfer the project to namespaces you manage.
|
||||
%li You will need to update your local repositories to point to the new location.
|
||||
%li Project visibility level will be changed to match namespace rules when transfering to a group.
|
||||
%li Project visibility level will be changed to match namespace rules when transferring to a group.
|
||||
= f.submit 'Transfer project', class: "btn btn-remove js-confirm-danger", data: { "confirm-danger-message" => transfer_project_message(@project) }
|
||||
- if @project.forked? && can?(current_user, :remove_fork_project, @project)
|
||||
.sub-section
|
||||
|
|
|
@ -75,7 +75,7 @@
|
|||
Pipeline
|
||||
= link_to "##{@build.pipeline.id}", project_pipeline_path(@project, @build.pipeline), class: 'link-commit'
|
||||
from
|
||||
= link_to "#{@build.pipeline.ref}", project_branch_path(@project, @build.pipeline.ref), class: 'link-commit'
|
||||
= link_to "#{@build.pipeline.ref}", project_ref_path(@project, @build.pipeline.ref), class: 'link-commit ref-name'
|
||||
%button.dropdown-menu-toggle{ type: 'button', 'data-toggle' => 'dropdown' }
|
||||
%span.stage-selection More
|
||||
= icon('chevron-down')
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
- if @merge_request_diff.collected? || @merge_request_diff.overflow?
|
||||
= render 'projects/merge_requests/diffs/versions'
|
||||
= render "projects/diffs/diffs", diffs: @diffs, environment: @environment
|
||||
= render "projects/diffs/diffs", diffs: @diffs, environment: @environment, merge_request: true
|
||||
- elsif @merge_request_diff.empty?
|
||||
.nothing-here-block Nothing to merge from #{@merge_request.source_branch} into #{@merge_request.target_branch}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
= page_specific_javascript_bundle_tag('common_vue')
|
||||
= page_specific_javascript_bundle_tag('sidebar')
|
||||
|
||||
%aside.right-sidebar.js-right-sidebar{ data: { "offset-top" => "50", "spy" => "affix", signed: { in: current_user.present? } }, class: sidebar_gutter_collapsed_class, 'aria-live' => 'polite' }
|
||||
%aside.right-sidebar.js-right-sidebar.js-issuable-sidebar{ data: { "offset-top" => ("50" unless show_new_nav?), "spy" => ("affix" unless show_new_nav?), signed: { in: current_user.present? } }, class: sidebar_gutter_collapsed_class, 'aria-live' => 'polite' }
|
||||
.issuable-sidebar{ data: { endpoint: "#{issuable_json_path(issuable)}" } }
|
||||
- can_edit_issuable = can?(current_user, :"admin_#{issuable.to_ability_name}", @project)
|
||||
.block.issuable-sidebar-header
|
||||
|
|
|
@ -1,20 +1,23 @@
|
|||
module NewIssuable
|
||||
attr_reader :issuable, :user
|
||||
|
||||
def ensure_objects_found(issuable_id, user_id)
|
||||
@issuable = issuable_class.find_by(id: issuable_id)
|
||||
unless @issuable
|
||||
log_error(issuable_class, issuable_id)
|
||||
return false
|
||||
end
|
||||
def objects_found?(issuable_id, user_id)
|
||||
set_user(user_id)
|
||||
set_issuable(issuable_id)
|
||||
|
||||
user && issuable
|
||||
end
|
||||
|
||||
def set_user(user_id)
|
||||
@user = User.find_by(id: user_id)
|
||||
unless @user
|
||||
log_error(User, user_id)
|
||||
return false
|
||||
end
|
||||
|
||||
true
|
||||
log_error(User, user_id) unless @user
|
||||
end
|
||||
|
||||
def set_issuable(issuable_id)
|
||||
@issuable = issuable_class.find_by(id: issuable_id)
|
||||
|
||||
log_error(issuable_class, issuable_id) unless @issuable
|
||||
end
|
||||
|
||||
def log_error(record_class, record_id)
|
||||
|
|
|
@ -4,7 +4,7 @@ class NewIssueWorker
|
|||
include NewIssuable
|
||||
|
||||
def perform(issue_id, user_id)
|
||||
return unless ensure_objects_found(issue_id, user_id)
|
||||
return unless objects_found?(issue_id, user_id)
|
||||
|
||||
EventCreateService.new.open_issue(issuable, user)
|
||||
NotificationService.new.new_issue(issuable, user)
|
||||
|
|
|
@ -4,7 +4,7 @@ class NewMergeRequestWorker
|
|||
include NewIssuable
|
||||
|
||||
def perform(merge_request_id, user_id)
|
||||
return unless ensure_objects_found(merge_request_id, user_id)
|
||||
return unless objects_found?(merge_request_id, user_id)
|
||||
|
||||
EventCreateService.new.open_mr(issuable, user)
|
||||
NotificationService.new.new_merge_request(issuable, user)
|
||||
|
|
136
bin/changelog
136
bin/changelog
|
@ -14,54 +14,107 @@ Options = Struct.new(
|
|||
:dry_run,
|
||||
:force,
|
||||
:merge_request,
|
||||
:title
|
||||
:title,
|
||||
:type
|
||||
)
|
||||
INVALID_TYPE = -1
|
||||
|
||||
class ChangelogOptionParser
|
||||
def self.parse(argv)
|
||||
options = Options.new
|
||||
Type = Struct.new(:name, :description)
|
||||
TYPES = [
|
||||
Type.new('added', 'New feature'),
|
||||
Type.new('fixed', 'Bug fix'),
|
||||
Type.new('changed', 'Feature change'),
|
||||
Type.new('deprecated', 'New deprecation'),
|
||||
Type.new('removed', 'Feature removal'),
|
||||
Type.new('security', 'Security fix'),
|
||||
Type.new('other', 'Other')
|
||||
].freeze
|
||||
TYPES_OFFSET = 1
|
||||
|
||||
parser = OptionParser.new do |opts|
|
||||
opts.banner = "Usage: #{__FILE__} [options] [title]\n\n"
|
||||
class << self
|
||||
def parse(argv)
|
||||
options = Options.new
|
||||
|
||||
# Note: We do not provide a shorthand for this in order to match the `git
|
||||
# commit` interface
|
||||
opts.on('--amend', 'Amend the previous commit') do |value|
|
||||
options.amend = value
|
||||
parser = OptionParser.new do |opts|
|
||||
opts.banner = "Usage: #{__FILE__} [options] [title]\n\n"
|
||||
|
||||
# Note: We do not provide a shorthand for this in order to match the `git
|
||||
# commit` interface
|
||||
opts.on('--amend', 'Amend the previous commit') do |value|
|
||||
options.amend = value
|
||||
end
|
||||
|
||||
opts.on('-f', '--force', 'Overwrite an existing entry') do |value|
|
||||
options.force = value
|
||||
end
|
||||
|
||||
opts.on('-m', '--merge-request [integer]', Integer, 'Merge Request ID') do |value|
|
||||
options.merge_request = value
|
||||
end
|
||||
|
||||
opts.on('-n', '--dry-run', "Don't actually write anything, just print") do |value|
|
||||
options.dry_run = value
|
||||
end
|
||||
|
||||
opts.on('-u', '--git-username', 'Use Git user.name configuration as the author') do |value|
|
||||
options.author = git_user_name if value
|
||||
end
|
||||
|
||||
opts.on('-t', '--type [string]', String, "The category of the change, valid options are: #{TYPES.map(&:name).join(', ')}") do |value|
|
||||
options.type = parse_type(value)
|
||||
end
|
||||
|
||||
opts.on('-h', '--help', 'Print help message') do
|
||||
$stdout.puts opts
|
||||
exit
|
||||
end
|
||||
end
|
||||
|
||||
opts.on('-f', '--force', 'Overwrite an existing entry') do |value|
|
||||
options.force = value
|
||||
end
|
||||
parser.parse!(argv)
|
||||
|
||||
opts.on('-m', '--merge-request [integer]', Integer, 'Merge Request ID') do |value|
|
||||
options.merge_request = value
|
||||
end
|
||||
# Title is everything that remains, but let's clean it up a bit
|
||||
options.title = argv.join(' ').strip.squeeze(' ').tr("\r\n", '')
|
||||
|
||||
opts.on('-n', '--dry-run', "Don't actually write anything, just print") do |value|
|
||||
options.dry_run = value
|
||||
end
|
||||
options
|
||||
end
|
||||
|
||||
opts.on('-u', '--git-username', 'Use Git user.name configuration as the author') do |value|
|
||||
options.author = git_user_name if value
|
||||
end
|
||||
def read_type
|
||||
read_type_message
|
||||
|
||||
opts.on('-h', '--help', 'Print help message') do
|
||||
$stdout.puts opts
|
||||
exit
|
||||
type = TYPES[$stdin.getc.to_i - TYPES_OFFSET]
|
||||
assert_valid_type!(type)
|
||||
|
||||
type.name
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def parse_type(name)
|
||||
type_found = TYPES.find do |type|
|
||||
type.name == name
|
||||
end
|
||||
type_found ? type_found.name : INVALID_TYPE
|
||||
end
|
||||
|
||||
def read_type_message
|
||||
$stdout.puts "\n>> Please specify the index for the category of your change:"
|
||||
TYPES.each_with_index do |type, index|
|
||||
$stdout.puts "#{index + TYPES_OFFSET}. #{type.description}"
|
||||
end
|
||||
$stdout.print "\n?> "
|
||||
end
|
||||
|
||||
def assert_valid_type!(type)
|
||||
unless type
|
||||
$stderr.puts "Invalid category index, please select an index between 1 and #{TYPES.length}"
|
||||
exit 1
|
||||
end
|
||||
end
|
||||
|
||||
parser.parse!(argv)
|
||||
|
||||
# Title is everything that remains, but let's clean it up a bit
|
||||
options.title = argv.join(' ').strip.squeeze(' ').tr("\r\n", '')
|
||||
|
||||
options
|
||||
end
|
||||
|
||||
def self.git_user_name
|
||||
%x{git config user.name}.strip
|
||||
def git_user_name
|
||||
%x{git config user.name}.strip
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -72,8 +125,12 @@ class ChangelogEntry
|
|||
@options = options
|
||||
|
||||
assert_feature_branch!
|
||||
assert_new_file!
|
||||
assert_title!
|
||||
assert_new_file!
|
||||
|
||||
# Read type from $stdin unless is already set
|
||||
options.type ||= ChangelogOptionParser.read_type
|
||||
assert_valid_type!
|
||||
|
||||
$stdout.puts "\e[32mcreate\e[0m #{file_path}"
|
||||
$stdout.puts contents
|
||||
|
@ -90,7 +147,8 @@ class ChangelogEntry
|
|||
yaml_content = YAML.dump(
|
||||
'title' => title,
|
||||
'merge_request' => options.merge_request,
|
||||
'author' => options.author
|
||||
'author' => options.author,
|
||||
'type' => options.type
|
||||
)
|
||||
remove_trailing_whitespace(yaml_content)
|
||||
end
|
||||
|
@ -129,6 +187,12 @@ class ChangelogEntry
|
|||
" to use the title from the previous commit."
|
||||
end
|
||||
|
||||
def assert_valid_type!
|
||||
return unless options.type && options.type == INVALID_TYPE
|
||||
|
||||
fail_with 'Invalid category given!'
|
||||
end
|
||||
|
||||
def title
|
||||
if options.title.empty?
|
||||
last_commit_subject
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Added type to CHANGELOG entries
|
||||
merge_request:
|
||||
author: Jacopo Beschi @jacopo-beschi
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Fix the alignment of line numbers to lines of code in code viewer
|
||||
merge_request: 13403
|
||||
author: Trevor Flynn
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Simplify checking if objects exist code in new issaubles workers
|
||||
merge_request:
|
||||
author:
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Fixes new issue button for failed job returning 404
|
||||
merge_request:
|
||||
author:
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Align OR separator to center in new project page
|
||||
merge_request:
|
||||
author:
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Remove hidden symlinks from project import files
|
||||
merge_request:
|
||||
author:
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Fix destroy of case-insensitive conflicting redirects
|
||||
merge_request: 13357
|
||||
author:
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Add missing validation error for username change with container registry tags
|
||||
merge_request: 13356
|
||||
author:
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Disallow Git URLs that include a username or hostname beginning with a non-alphanumeric
|
||||
character
|
||||
merge_request:
|
||||
author:
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Use project_ref_path to create the link to a branch to fix links that 404
|
||||
merge_request:
|
||||
author:
|
|
@ -71,7 +71,7 @@ class Settings < Settingslogic
|
|||
|
||||
# check that `current` (string or integer) is a contant in `modul`.
|
||||
def verify_constant(modul, current, default)
|
||||
constant = modul.constants.find{ |name| modul.const_get(name) == current }
|
||||
constant = modul.constants.find { |name| modul.const_get(name) == current }
|
||||
value = constant.nil? ? default : modul.const_get(constant)
|
||||
if current.is_a? String
|
||||
value = modul.const_get(current.upcase) rescue default
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
resource :repository, only: [:create] do
|
||||
member do
|
||||
get ':ref/archive', constraints: { format: Gitlab::PathRegex.archive_formats_regex, ref: /.+/ }, action: 'archive', as: 'archive'
|
||||
|
||||
# deprecated since GitLab 9.5
|
||||
get 'archive', constraints: { format: Gitlab::PathRegex.archive_formats_regex }, as: 'archive_alternative'
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ class AddUniqueIndexToLabels < ActiveRecord::Migration
|
|||
def up
|
||||
select_all('SELECT title, project_id, COUNT(id) as cnt FROM labels GROUP BY project_id, title HAVING COUNT(id) > 1').each do |label|
|
||||
label_title = quote_string(label['title'])
|
||||
duplicated_ids = select_all("SELECT id FROM labels WHERE project_id = #{label['project_id']} AND title = '#{label_title}' ORDER BY id ASC").map{ |label| label['id'] }
|
||||
duplicated_ids = select_all("SELECT id FROM labels WHERE project_id = #{label['project_id']} AND title = '#{label_title}' ORDER BY id ASC").map { |label| label['id'] }
|
||||
label_id = duplicated_ids.first
|
||||
duplicated_ids.delete(label_id)
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ class CleanupNamespacelessPendingDeleteProjects < ActiveRecord::Migration
|
|||
private
|
||||
|
||||
def pending_delete_batch
|
||||
connection.exec_query(find_batch).map{ |row| row['id'].to_i }
|
||||
connection.exec_query(find_batch).map { |row| row['id'].to_i }
|
||||
end
|
||||
|
||||
BATCH_SIZE = 5000
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
---
|
||||
toc: false
|
||||
---
|
||||
|
||||
# GitLab Documentation
|
||||
|
||||
Welcome to [GitLab](https://about.gitlab.com/), a Git-based fully featured
|
||||
|
@ -26,6 +30,9 @@ Shortcuts to GitLab's most visited docs:
|
|||
| [Configuring `.gitlab-ci.yml`](ci/yaml/README.md) | [SSH authentication](ssh/README.md) |
|
||||
| [Using Docker images](ci/docker/using_docker_images.md) | [GitLab Pages](user/project/pages/index.md) |
|
||||
|
||||
- [User documentation](user/index.md)
|
||||
- [Administrator documentation](#administrator-documentation)
|
||||
|
||||
## Getting started with GitLab
|
||||
|
||||
- [GitLab Basics](gitlab-basics/README.md): Start working on your command line and on GitLab.
|
||||
|
@ -36,7 +43,6 @@ Shortcuts to GitLab's most visited docs:
|
|||
|
||||
### User account
|
||||
|
||||
- [User documentation](user/index.md): Learn how to use GitLab and explore its features
|
||||
- [User account](user/profile/index.md): Manage your account
|
||||
- [Authentication](topics/authentication/index.md): Account security with two-factor authentication, setup your ssh keys and deploy keys for secure access to your projects.
|
||||
- [Profile settings](user/profile/index.md#profile-settings): Manage your profile settings, two factor authentication and more.
|
||||
|
|
|
@ -42,6 +42,10 @@ GitLab does not recommend using EFS with GitLab.
|
|||
are allocated. For smaller volumes, users may experience decent performance
|
||||
for a period of time due to 'Burst Credits'. Over a period of weeks to months
|
||||
credits may run out and performance will bottom out.
|
||||
- To keep "Burst Credits" available, it may be necessary to provision more space
|
||||
with 'dummy data'. However, this may get expensive.
|
||||
- Another option to maintain "Burst Credits" is to use FS Cache on the server so
|
||||
that AWS doesn't always have to go into EFS to access files.
|
||||
- For larger volumes, allocated IOPS may not be the problem. Workloads where
|
||||
many small files are written in a serialized manner are not well-suited for EFS.
|
||||
EBS with an NFS server on top will perform much better.
|
||||
|
|
|
@ -15,11 +15,14 @@ following format:
|
|||
title: "Going through change[log]s"
|
||||
merge_request: 1972
|
||||
author: Ozzy Osbourne
|
||||
type: added
|
||||
```
|
||||
|
||||
The `merge_request` value is a reference to a merge request that adds this
|
||||
entry, and the `author` key is used to give attribution to community
|
||||
contributors. **Both are optional**.
|
||||
The `type` field maps the category of the change,
|
||||
valid options are: added, fixed, changed, deprecated, removed, security, other. **Type field is mandatory**.
|
||||
|
||||
Community contributors and core team members are encouraged to add their name to
|
||||
the `author` field. GitLab team members **should not**.
|
||||
|
@ -94,6 +97,19 @@ Its simplest usage is to provide the value for `title`:
|
|||
$ bin/changelog 'Hey DZ, I added a feature to GitLab!'
|
||||
```
|
||||
|
||||
At this point the script would ask you to select the category of the change (mapped to the `type` field in the entry):
|
||||
|
||||
```text
|
||||
>> Please specify the category of your change:
|
||||
1. New feature
|
||||
2. Bug fix
|
||||
3. Feature change
|
||||
4. New deprecation
|
||||
5. Feature removal
|
||||
6. Security fix
|
||||
7. Other
|
||||
```
|
||||
|
||||
The entry filename is based on the name of the current Git branch. If you run
|
||||
the command above on a branch called `feature/hey-dz`, it will generate a
|
||||
`changelogs/unreleased/feature-hey-dz.yml` file.
|
||||
|
@ -106,26 +122,29 @@ create changelogs/unreleased/my-feature.yml
|
|||
title: Hey DZ, I added a feature to GitLab!
|
||||
merge_request:
|
||||
author:
|
||||
type:
|
||||
```
|
||||
If you're working on the GitLab EE repository, the entry will be added to
|
||||
`changelogs/unreleased-ee/` instead.
|
||||
|
||||
#### Arguments
|
||||
|
||||
| Argument | Shorthand | Purpose |
|
||||
| ----------------- | --------- | --------------------------------------------- |
|
||||
| [`--amend`] | | Amend the previous commit |
|
||||
| [`--force`] | `-f` | Overwrite an existing entry |
|
||||
| [`--merge-request`] | `-m` | Set merge request ID |
|
||||
| [`--dry-run`] | `-n` | Don't actually write anything, just print |
|
||||
| [`--git-username`] | `-u` | Use Git user.name configuration as the author |
|
||||
| [`--help`] | `-h` | Print help message |
|
||||
| Argument | Shorthand | Purpose |
|
||||
| ----------------- | --------- | ---------------------------------------------------------------------------------------------------------- |
|
||||
| [`--amend`] | | Amend the previous commit |
|
||||
| [`--force`] | `-f` | Overwrite an existing entry |
|
||||
| [`--merge-request`] | `-m` | Set merge request ID |
|
||||
| [`--dry-run`] | `-n` | Don't actually write anything, just print |
|
||||
| [`--git-username`] | `-u` | Use Git user.name configuration as the author |
|
||||
| [`--type`] | `-t` | The category of the change, valid options are: added, fixed, changed, deprecated, removed, security, other |
|
||||
| [`--help`] | `-h` | Print help message |
|
||||
|
||||
[`--amend`]: #-amend
|
||||
[`--force`]: #-force-or-f
|
||||
[`--merge-request`]: #-merge-request-or-m
|
||||
[`--dry-run`]: #-dry-run-or-n
|
||||
[`--git-username`]: #-git-username-or-u
|
||||
[`--type`]: #-type-or-t
|
||||
[`--help`]: #-help
|
||||
|
||||
##### `--amend`
|
||||
|
@ -147,6 +166,7 @@ create changelogs/unreleased/feature-hey-dz.yml
|
|||
title: Added an awesome new feature to GitLab
|
||||
merge_request:
|
||||
author:
|
||||
type:
|
||||
```
|
||||
|
||||
##### `--force` or `-f`
|
||||
|
@ -164,6 +184,7 @@ create changelogs/unreleased/feature-hey-dz.yml
|
|||
title: Hey DZ, I added a feature to GitLab!
|
||||
merge_request: 1983
|
||||
author:
|
||||
type:
|
||||
```
|
||||
|
||||
##### `--merge-request` or `-m`
|
||||
|
@ -178,6 +199,7 @@ create changelogs/unreleased/feature-hey-dz.yml
|
|||
title: Hey DZ, I added a feature to GitLab!
|
||||
merge_request: 1983
|
||||
author:
|
||||
type:
|
||||
```
|
||||
|
||||
##### `--dry-run` or `-n`
|
||||
|
@ -192,6 +214,7 @@ create changelogs/unreleased/feature-hey-dz.yml
|
|||
title: Added an awesome new feature to GitLab
|
||||
merge_request:
|
||||
author:
|
||||
type:
|
||||
|
||||
$ ls changelogs/unreleased/
|
||||
```
|
||||
|
@ -211,6 +234,21 @@ create changelogs/unreleased/feature-hey-dz.yml
|
|||
title: Hey DZ, I added a feature to GitLab!
|
||||
merge_request:
|
||||
author: Jane Doe
|
||||
type:
|
||||
```
|
||||
|
||||
##### `--type` or `-t`
|
||||
|
||||
Use the **`--type`** or **`-t`** argument to provide the `type` value:
|
||||
|
||||
```text
|
||||
$ bin/changelog 'Hey DZ, I added a feature to GitLab!' -t added
|
||||
create changelogs/unreleased/feature-hey-dz.yml
|
||||
---
|
||||
title: Hey DZ, I added a feature to GitLab!
|
||||
merge_request:
|
||||
author:
|
||||
type: added
|
||||
```
|
||||
|
||||
### History and Reasoning
|
||||
|
|
|
@ -66,6 +66,9 @@ Install the required packages (needed to compile Ruby and native extensions to R
|
|||
|
||||
sudo apt-get install -y build-essential zlib1g-dev libyaml-dev libssl-dev libgdbm-dev libre2-dev libreadline-dev libncurses5-dev libffi-dev curl openssh-server checkinstall libxml2-dev libxslt-dev libcurl4-openssl-dev libicu-dev logrotate python-docutils pkg-config cmake
|
||||
|
||||
Ubuntu 14.04 (Trusty Tahr) doesn't have the `libre2-dev` package available, but
|
||||
you can [install re2 manually](https://github.com/google/re2/wiki/Install).
|
||||
|
||||
If you want to use Kerberos for user authentication, then install libkrb5-dev:
|
||||
|
||||
sudo apt-get install libkrb5-dev
|
||||
|
@ -296,9 +299,9 @@ sudo usermod -aG redis git
|
|||
### Clone the Source
|
||||
|
||||
# Clone GitLab repository
|
||||
sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 9-4-stable gitlab
|
||||
sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 9-5-stable gitlab
|
||||
|
||||
**Note:** You can change `9-4-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server!
|
||||
**Note:** You can change `9-5-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server!
|
||||
|
||||
### Configure It
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# GitLab Helm Chart
|
||||
> Officially supported cloud providers are Google Container Service and Azure Container Service.
|
||||
> These Helm charts are in beta. GitLab is working on a [cloud-native](http://docs.gitlab.com/omnibus/package-information/cloud_native.html) set of [Charts](https://gitlab.com/charts/helm.gitlab.io) which will replace these.
|
||||
|
||||
> Officially supported schedulers are Kubernetes and Terraform.
|
||||
> Officially supported cloud providers are Google Container Service and Azure Container Service.
|
||||
|
||||
The `gitlab` Helm chart deploys GitLab into your Kubernetes cluster.
|
||||
|
||||
|
@ -207,7 +207,7 @@ its class in an annotation.
|
|||
>**Note:**
|
||||
The Ingress alone doesn't expose GitLab externally. You need to have a Ingress controller setup to do that.
|
||||
Setting up an Ingress controller can be done by installing the `nginx-ingress` helm chart. But be sure
|
||||
to read the [documentation](https://github.com/kubernetes/charts/blob/master/stable/nginx-ingress/README.md).
|
||||
to read the [documentation](https://github.com/kubernetes/charts/blob/master/stable/nginx-ingress/README.md).
|
||||
>**Note:**
|
||||
If you would like to use the Registry, you will also need to ensure your Ingress supports a [sufficiently large request size](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size).
|
||||
|
||||
|
|
|
@ -0,0 +1,171 @@
|
|||
# GitLab-Omnibus Helm Chart
|
||||
> These Helm charts are in beta. GitLab is working on a [cloud-native](http://docs.gitlab.com/omnibus/package-information/cloud_native.html) set of [Charts](https://gitlab.com/charts/helm.gitlab.io) which will replace these.
|
||||
|
||||
> Officially supported cloud providers are Google Container Service and Azure Container Service.
|
||||
|
||||
This work is based partially on: https://github.com/lwolf/kubernetes-gitlab/. GitLab would like to thank Sergey Nuzhdin for his work.
|
||||
|
||||
## Introduction
|
||||
|
||||
This chart provides an easy way to get started with GitLab, provisioning an installation with nearly all functionality enabled. SSL is automatically provisioned as well via [Let's Encrypt](https://letsencrypt.org/).
|
||||
|
||||
The deployment includes:
|
||||
|
||||
- A [GitLab Omnibus](https://docs.gitlab.com/omnibus/) Pod, including Mattermost, Container Registry, and Prometheus
|
||||
- An auto-scaling [GitLab Runner](https://docs.gitlab.com/runner/) using the Kubernetes executor
|
||||
- [Redis](https://github.com/kubernetes/charts/tree/master/stable/redis)
|
||||
- [PostgreSQL](https://github.com/kubernetes/charts/tree/master/stable/postgresql)
|
||||
- [NGINX Ingress](https://github.com/kubernetes/charts/tree/master/stable/nginx-ingress)
|
||||
- Persistent Volume Claims for Data, Registry, Postgres, and Redis
|
||||
|
||||
A video demonstration of GitLab utilizing this chart [is available](https://about.gitlab.com/handbook/sales/demo/).
|
||||
|
||||
Terms:
|
||||
|
||||
- Google Cloud Platform (**GCP**)
|
||||
- Google Container Engine (**GKE**)
|
||||
- Azure Container Service (**ACS**)
|
||||
- Kubernetes (**k8s**)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- _At least_ 4 GB of RAM available on your cluster, in chunks of 1 GB. 41GB of storage and 2 CPU are also required.
|
||||
- Kubernetes 1.4+ with Beta APIs enabled
|
||||
- [Persistent Volume](https://kubernetes.io/docs/concepts/storage/persistent-volumes/) provisioner support in the underlying infrastructure
|
||||
- An [external IP address](#networking-prerequisites)
|
||||
- A [wildcard DNS entry](#networking-prerequisites), which resolves to the external IP address
|
||||
- The `kubectl` CLI installed locally and authenticated for the cluster
|
||||
- The Helm Client installed locally
|
||||
- The Helm Server (Tiller) already installed and running in the cluster, by running `helm init`
|
||||
- The GitLab Helm Repo [added to your Helm Client](index.md#add-the-gitlab-helm-repository)
|
||||
|
||||
### Networking Prerequisites
|
||||
|
||||
This chart configures a GitLab server and Kubernetes cluster which can support dynamic [Review Apps](https://docs.gitlab.com/ee/ci/review_apps/index.html), as well as services like the integrated [Container Registry](https://docs.gitlab.com/ee/user/project/container_registry.html) and [Mattermost](https://docs.gitlab.com/omnibus/gitlab-mattermost/).
|
||||
|
||||
To support the GitLab services and dynamic environments, a wildcard DNS entry is required which resolves to the external Load Balancer IP.
|
||||
|
||||
To provision an external IP on GCP and Azure, simply request a new address from the Networking section. Ensure that the region matches the region your container cluster is created in. Note, it is important that the IP is not assigned at this point in time. It will be automatically assigned once the Helm chart is installed, and assigned to the Load Balancer.
|
||||
|
||||
Now that an external IP address has been allocated, ensure that the wildcard DNS entry you would like to use resolves to this IP. Please consult the documentation for your DNS service for more information on creating DNS records.
|
||||
|
||||
## Configuring and Installing GitLab
|
||||
|
||||
For most installations, only two parameters are required:
|
||||
- `baseIP`: the desired [external IP address](#networking-prerequisites)
|
||||
- `baseDomain`: the [base domain](#networking-prerequisites) with the wildcard host entry resolving to the `baseIP`. For example, `mycompany.io`.
|
||||
|
||||
Other common configuration options:
|
||||
- `gitlab`: Choose the [desired edition](https://about.gitlab.com/products), either `ee` or `ce`. `ce` is the default.
|
||||
- `gitlabEELicense`: For Enterprise Edition, the [license](https://docs.gitlab.com/ee/user/admin_area/license.html) can be installed directly via the Chart
|
||||
- `provider`: Optimizes the deployment for a cloud provider. The default is `gke` for GCP, with `acs` also supported for Azure.
|
||||
- `legoEmail`: Email address to use when requesting new SSL certificates from Let's Encrypt
|
||||
|
||||
For additional configuration options, consult the [values.yaml](https://gitlab.com/charts/charts.gitlab.io/blob/master/charts/gitlab-omnibus/values.yaml).
|
||||
|
||||
These settings can either be passed directly on the command line:
|
||||
```bash
|
||||
helm install --name gitlab --set baseDomain=gitlab.io,baseIP=1.1.1.1,gitlab=ee,gitlabEELicense=$LICENSE,legoEmail=email@gitlab.com gitlab/gitlab-omnibus
|
||||
```
|
||||
|
||||
or within a YAML file:
|
||||
```bash
|
||||
helm install --name gitlab -f values.yaml gitlab/gitlab-omnibus
|
||||
```
|
||||
|
||||
> **Note:**
|
||||
If you are using a machine type with support for less than 4 attached disks, like an Azure trial, you should disable dedicated storage for [Postgres and Redis](#persistent-storage).
|
||||
|
||||
### Choosing a different GitLab release version
|
||||
|
||||
The version of GitLab installed is based on the `gitlab` setting (see [section](#choosing-gitlab-edition) above), and
|
||||
the value of the corresponding helm setting: `gitlabCEImage` or `gitabEEImage`.
|
||||
|
||||
```yaml
|
||||
gitlab: CE
|
||||
gitlabCEImage: gitlab/gitlab-ce:9.1.2-ce.0
|
||||
gitlabEEImage: gitlab/gitlab-ee:9.1.2-ee.0
|
||||
```
|
||||
|
||||
The different images can be found in the [gitlab-ce](https://hub.docker.com/r/gitlab/gitlab-ce/tags/) and [gitlab-ee](https://hub.docker.com/r/gitlab/gitlab-ee/tags/)
|
||||
repositories on Docker Hub.
|
||||
|
||||
> **Note:**
|
||||
There is no guarantee that other release versions of GitLab, other than what are
|
||||
used by default in the chart, will be supported by a chart install.
|
||||
|
||||
### Persistent storage
|
||||
|
||||
By default, persistent storage is enabled for GitLab and the charts it depends
|
||||
on (Redis and PostgreSQL).
|
||||
|
||||
Components can have their claim size set from your `values.yaml`, along with whether to provision separate storage for Postgres and Redis.
|
||||
|
||||
Basic configuration:
|
||||
|
||||
```yaml
|
||||
redisImage: redis:3.2.10
|
||||
redisDedicatedStorage: true
|
||||
redisStorageSize: 5Gi
|
||||
postgresImage: postgres:9.6.3
|
||||
# If you disable postgresDedicatedStorage, you should consider bumping up gitlabRailsStorageSize
|
||||
postgresDedicatedStorage: true
|
||||
postgresStorageSize: 30Gi
|
||||
gitlabRailsStorageSize: 30Gi
|
||||
gitlabRegistryStorageSize: 30Gi
|
||||
gitlabConfigStorageSize: 1Gi
|
||||
```
|
||||
|
||||
### Routing and SSL
|
||||
|
||||
Ingress routing and SSL are automatically configured within this Chart. An NGINX ingress is provisioned and configured, and will route traffic to any service. SSL certificates are automatically created and configured by [kube-lego](https://github.com/kubernetes/charts/tree/master/stable/kube-lego).
|
||||
|
||||
> **Note:**
|
||||
Let's Encrypt limits a single TLD to five certificate requests within a single week. This means that common DNS wildcard services like [xip.io](http://xip.io) and [nip.io](http://nip.io) are unlikely to work.
|
||||
|
||||
## Installing GitLab using the Helm Chart
|
||||
> You may see a temporary error message `SchedulerPredicates failed due to PersistentVolumeClaim is not bound` while storage provisions. Once the storage provisions, the pods will automatically restart. This may take a couple minutes depending on your cloud provider. If the error persists, please review the [prerequisites](#prerequisites) to ensure you have enough RAM, CPU, and storage.
|
||||
|
||||
Once you have reviewed the [configuration settings](#configuring-and-installing-gitlab), you can install the chart. We recommending saving your configuration options in a `values.yaml` file for easier upgrades in the future.
|
||||
|
||||
For example:
|
||||
```bash
|
||||
helm install --name gitlab -f values.yaml gitlab/gitlab-omnibus
|
||||
```
|
||||
|
||||
or passing them on the command line:
|
||||
```bash
|
||||
helm install --name gitlab --set baseDomain=gitlab.io,baseIP=1.1.1.1,gitlab=ee,gitlabEELicense=$LICENSE,legoEmail=email@gitlab.com gitlab/gitlab-omnibus
|
||||
```
|
||||
|
||||
## Updating GitLab using the Helm Chart
|
||||
|
||||
Once your GitLab Chart is installed, configuration changes and chart updates
|
||||
should we done using `helm upgrade`
|
||||
|
||||
```bash
|
||||
helm upgrade -f <CONFIG_VALUES_FILE> <RELEASE-NAME> gitlab/gitlab
|
||||
```
|
||||
|
||||
where:
|
||||
|
||||
- `<CONFIG_VALUES_FILE>` is the path to values file containing your custom
|
||||
[configuration] (#configuring-and-installing-gitlab).
|
||||
- `<RELEASE-NAME>` is the name you gave the chart when installing it.
|
||||
In the [Install section](#installing-gitlab-using-the-helm-chart) we called it `gitlab`.
|
||||
|
||||
## Uninstalling GitLab using the Helm Chart
|
||||
|
||||
To uninstall the GitLab Chart, run the following:
|
||||
|
||||
```bash
|
||||
helm delete <RELEASE-NAME>
|
||||
```
|
||||
|
||||
where:
|
||||
|
||||
- `<RELEASE-NAME>` is the name you gave the chart when installing it.
|
||||
In the [Install section](#installing) we called it `gitlab`.
|
||||
|
||||
[kube-srv]: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services---service-types
|
||||
[storageclass]: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#storageclasses
|
|
@ -1,7 +1,7 @@
|
|||
# GitLab Runner Helm Chart
|
||||
> Officially supported cloud providers are Google Container Service and Azure Container Service.
|
||||
> These Helm charts are in beta. GitLab is working on a [cloud-native](http://docs.gitlab.com/omnibus/package-information/cloud_native.html) set of [Charts](https://gitlab.com/charts/helm.gitlab.io) which will replace these.
|
||||
|
||||
> Officially supported schedulers are Kubernetes and Terraform.
|
||||
> Officially supported cloud providers are Google Container Service and Azure Container Service.
|
||||
|
||||
The `gitlab-runner` Helm chart deploys a GitLab Runner instance into your
|
||||
Kubernetes cluster.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Installing GitLab on Kubernetes
|
||||
> Officially supported cloud providers are Google Container Service and Azure Container Service.
|
||||
> These Helm charts are in beta. GitLab is working on a [cloud-native](http://docs.gitlab.com/omnibus/package-information/cloud_native.html) set of [Charts](https://gitlab.com/charts/helm.gitlab.io) which will replace these.
|
||||
|
||||
> Officially supported schedulers are Kubernetes, Terraform and Tectonic.
|
||||
> Officially supported cloud providers are Google Container Service and Azure Container Service.
|
||||
|
||||
The easiest method to deploy GitLab in [Kubernetes](https://kubernetes.io/) is
|
||||
to take advantage of the official GitLab Helm charts. [Helm] is a package
|
||||
|
@ -35,12 +35,11 @@ helm init
|
|||
|
||||
## Using the GitLab Helm Charts
|
||||
|
||||
GitLab makes available two Helm Charts, one for the GitLab server and another
|
||||
for the Runner. More detailed information on installing and configuring each
|
||||
Chart can be found below:
|
||||
GitLab makes available three Helm Charts: an easy to use bundled chart, and a specific chart for GitLab itself and the Runner.
|
||||
|
||||
- [Install GitLab](gitlab_chart.md)
|
||||
- [Install GitLab Runner](gitlab_runner_chart.md)
|
||||
- [gitlab-omnibus](gitlab_omnibus.md): The easiest way to get started. Includes everything needed to run GitLab, including: a Runner, Container Registry, automatic SSL, and an Ingress.
|
||||
- [gitlab](gitlab_chart.md): Just the GitLab service, with optional Postgres and Redis.
|
||||
- [gitlab-runner](gitlab_runner_chart.md): GitLab Runner, to process CI jobs.
|
||||
|
||||
[chart]: https://github.com/kubernetes/charts
|
||||
[helm-quick]: https://github.com/kubernetes/helm/blob/master/docs/quickstart.md
|
||||
|
|
|
@ -264,6 +264,16 @@ sudo systemctl daemon-reload
|
|||
|
||||
### 9. Install libs, migrations, etc.
|
||||
|
||||
GitLab 9.0.11 [introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/24570)
|
||||
a dependency on on the `re2` regular expression library. To install this dependency:
|
||||
|
||||
```bash
|
||||
sudo apt-get install libre2-dev
|
||||
```
|
||||
|
||||
Ubuntu 14.04 (Trusty Tahr) doesn't have the `libre2-dev` package available, but
|
||||
you can [install re2 manually](https://github.com/google/re2/wiki/Install).
|
||||
|
||||
```bash
|
||||
cd /home/git/gitlab
|
||||
|
||||
|
|
|
@ -264,6 +264,16 @@ sudo systemctl daemon-reload
|
|||
|
||||
### 9. Install libs, migrations, etc.
|
||||
|
||||
GitLab 9.1.8 [introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/24570)
|
||||
a dependency on on the `re2` regular expression library. To install this dependency:
|
||||
|
||||
```bash
|
||||
sudo apt-get install libre2-dev
|
||||
```
|
||||
|
||||
Ubuntu 14.04 (Trusty Tahr) doesn't have the `libre2-dev` package available, but
|
||||
you can [install re2 manually](https://github.com/google/re2/wiki/Install).
|
||||
|
||||
```bash
|
||||
cd /home/git/gitlab
|
||||
|
||||
|
|
|
@ -222,6 +222,16 @@ sudo systemctl daemon-reload
|
|||
|
||||
### 10. Install libs, migrations, etc.
|
||||
|
||||
GitLab 9.2.8 [introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/24570)
|
||||
a dependency on on the `re2` regular expression library. To install this dependency:
|
||||
|
||||
```bash
|
||||
sudo apt-get install libre2-dev
|
||||
```
|
||||
|
||||
Ubuntu 14.04 (Trusty Tahr) doesn't have the `libre2-dev` package available, but
|
||||
you can [install re2 manually](https://github.com/google/re2/wiki/Install).
|
||||
|
||||
```bash
|
||||
cd /home/git/gitlab
|
||||
|
||||
|
|
|
@ -258,6 +258,16 @@ sudo systemctl daemon-reload
|
|||
|
||||
### 12. Install libs, migrations, etc.
|
||||
|
||||
GitLab 9.3.8 [introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/24570)
|
||||
a dependency on on the `re2` regular expression library. To install this dependency:
|
||||
|
||||
```bash
|
||||
sudo apt-get install libre2-dev
|
||||
```
|
||||
|
||||
Ubuntu 14.04 (Trusty Tahr) doesn't have the `libre2-dev` package available, but
|
||||
you can [install re2 manually](https://github.com/google/re2/wiki/Install).
|
||||
|
||||
```bash
|
||||
cd /home/git/gitlab
|
||||
|
||||
|
|
|
@ -271,6 +271,16 @@ sudo systemctl daemon-reload
|
|||
|
||||
### 12. Install libs, migrations, etc.
|
||||
|
||||
GitLab 9.4 [introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/24570)
|
||||
a dependency on on the `re2` regular expression library. To install this dependency:
|
||||
|
||||
```bash
|
||||
sudo apt-get install libre2-dev
|
||||
```
|
||||
|
||||
Ubuntu 14.04 (Trusty Tahr) doesn't have the `libre2-dev` package available, but
|
||||
you can [install re2 manually](https://github.com/google/re2/wiki/Install).
|
||||
|
||||
```bash
|
||||
cd /home/git/gitlab
|
||||
|
||||
|
|
|
@ -295,6 +295,10 @@ sudo -u git -H bundle clean
|
|||
# Run database migrations
|
||||
sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production
|
||||
|
||||
# Compile GetText PO files
|
||||
|
||||
sudo -u git -H bundle exec rake gettext:compile RAILS_ENV=production
|
||||
|
||||
# Update node dependencies and recompile assets
|
||||
sudo -u git -H bundle exec rake yarn:install gitlab:assets:clean gitlab:assets:compile RAILS_ENV=production NODE_ENV=production
|
||||
|
||||
|
|
|
@ -71,80 +71,44 @@ your code, use it as an issue tracker, collaborate on code, and continuously
|
|||
build, test, and deploy your app with built-in GitLab CI/CD. Or, you can do
|
||||
it all at once, from one single project.
|
||||
|
||||
### Repository
|
||||
|
||||
Host your codebase in [GitLab repositories](project/repository/index.md) with version control
|
||||
and as part of a fully integrated platform.
|
||||
|
||||
### Issues
|
||||
|
||||
Explore the best of GitLab [Issues](project/issues/index.md).
|
||||
|
||||
### Merge Requests
|
||||
|
||||
Collanorate on code, gather reviews, live preview changes per branch, and
|
||||
request approvals with [Merge Requests](project/merge_requests/index.md).
|
||||
|
||||
### Milestones
|
||||
|
||||
Work on multiple issues and merge requests towards the same target date
|
||||
with [Milestones](project/milestones/index.md).
|
||||
|
||||
### GitLab Pages
|
||||
|
||||
Publish your static site directly from GitLab with [GitLab Pages](project/pages/index.md). You
|
||||
can [build, test, and deploy any Static Site Generator](https://about.gitlab.com/2016/06/17/ssg-overview-gitlab-pages-part-3-examples-ci/) with Pages.
|
||||
|
||||
### Container Registry
|
||||
|
||||
Build and deploy Docker images with [GitLab Container Registry](project/container_registry.md).
|
||||
- [Repositories](project/repository/index.md): Host your codebase in
|
||||
repositories with version control and as part of a fully integrated platform.
|
||||
- [Issues](project/issues/index.md): Explore the best of GitLab Issues' features.
|
||||
- [Merge Requests](project/merge_requests/index.md): Collaborate on code,
|
||||
reviews, live preview changes per branch, and request approvals with Merge Requests.
|
||||
- [Milestones](project/milestones/index.md): Work on multiple issues and merge
|
||||
requests towards the same target date with Milestones.
|
||||
|
||||
## GitLab CI/CD
|
||||
|
||||
Use built-in [GitLab CI/CD](../ci/README.md) to test, build, and deploy your applications
|
||||
directly from GitLab. No third-party integrations needed.
|
||||
|
||||
### Auto Deploy
|
||||
|
||||
Deploy your application out-of-the-box with [GitLab Auto Deploy](../ci/autodeploy/index.md).
|
||||
|
||||
### Review Apps
|
||||
|
||||
Live-preview the changes introduced by a merge request with [Review Apps](../ci/review_apps/index.md).
|
||||
|
||||
## Groups
|
||||
|
||||
With GitLab [Groups](group/index.md) you can assemble related projects together
|
||||
and grant members access to several projects at once.
|
||||
|
||||
### Subgroups
|
||||
|
||||
Groups can also be nested in [subgroups](group/subgroups/index.md).
|
||||
- [GitLab Auto Deploy](../ci/autodeploy/index.md): Deploy your application out-of-the-box with GitLab Auto Deploy.
|
||||
- [Review Apps](../ci/review_apps/index.md): Live-preview the changes introduced by a merge request with Review Apps.
|
||||
- [GitLab Pages](project/pages/index.md): Publish your static site directly from
|
||||
GitLab with Gitlab Pages. You can build, test, and deploy any Static Site Generator with Pages.
|
||||
- [GitLab Container Registry](project/container_registry.md): Build and deploy Docker
|
||||
images with Container Registry.
|
||||
|
||||
## Account
|
||||
|
||||
There is a lot you can customize and configure
|
||||
to enjoy the best of GitLab.
|
||||
|
||||
[Manage your user settings](profile/index.md) to change your personal info,
|
||||
- [Settings](profile/index.md): Manage your user settings to change your personal info,
|
||||
personal access tokens, authorized applications, etc.
|
||||
- [Authentication](../topics/authentication/index.md): Read through the authentication
|
||||
methods available in GitLab.
|
||||
- [Permissions](permissions.md): Learn the different set of permissions levels for each
|
||||
user type (guest, reporter, developer, master, owner).
|
||||
|
||||
### Authentication
|
||||
## Groups
|
||||
|
||||
Read through the [authentication](../topics/authentication/index.md) methods available in GitLab.
|
||||
With GitLab [Groups](group/index.md) you can assemble related projects together
|
||||
and grant members access to several projects at once.
|
||||
|
||||
### Permissions
|
||||
|
||||
Learn the different set of [permissions](permissions.md) for user type (guest, reporter, developer, master, owner).
|
||||
|
||||
## Integrations
|
||||
|
||||
[Integrate GitLab](../integration/README.md) with your preferred tool,
|
||||
such as Trello, JIRA, etc.
|
||||
|
||||
## Git and GitLab
|
||||
|
||||
Learn what is [Git](../topics/git/index.md) and its best practices.
|
||||
Groups can also be nested in [subgroups](group/subgroups/index.md).
|
||||
|
||||
## Discussions
|
||||
|
||||
|
@ -168,6 +132,11 @@ requests you're assigned to.
|
|||
you have quick access to. You can also gather feedback on them through
|
||||
[discussions](#discussions).
|
||||
|
||||
## Integrations
|
||||
|
||||
[Integrate GitLab](../integration/README.md) with your preferred tool,
|
||||
such as Trello, JIRA, etc.
|
||||
|
||||
## Webhooks
|
||||
|
||||
Configure [webhooks](project/integrations/webhooks.html) to listen for
|
||||
|
@ -178,3 +147,6 @@ POST request with data to the webhook URL.
|
|||
|
||||
Automate GitLab via [API](../api/README.html).
|
||||
|
||||
## Git and GitLab
|
||||
|
||||
Learn what is [Git](../topics/git/index.md) and its best practices.
|
||||
|
|
|
@ -132,7 +132,7 @@ module API
|
|||
expose :lfs_enabled?, as: :lfs_enabled
|
||||
expose :creator_id
|
||||
expose :namespace, using: 'API::Entities::Namespace'
|
||||
expose :forked_from_project, using: Entities::BasicProjectDetails, if: lambda{ |project, options| project.forked? }
|
||||
expose :forked_from_project, using: Entities::BasicProjectDetails, if: lambda { |project, options| project.forked? }
|
||||
expose :import_status
|
||||
expose :import_error, if: lambda { |_project, options| options[:user_can_admin_project] }
|
||||
expose :avatar_url do |user, options|
|
||||
|
|
|
@ -68,7 +68,7 @@ module API
|
|||
expose :lfs_enabled?, as: :lfs_enabled
|
||||
expose :creator_id
|
||||
expose :namespace, using: 'API::Entities::Namespace'
|
||||
expose :forked_from_project, using: ::API::Entities::BasicProjectDetails, if: lambda{ |project, options| project.forked? }
|
||||
expose :forked_from_project, using: ::API::Entities::BasicProjectDetails, if: lambda { |project, options| project.forked? }
|
||||
expose :avatar_url do |user, options|
|
||||
user.avatar_url(only_path: false)
|
||||
end
|
||||
|
|
|
@ -198,11 +198,11 @@ module Backup
|
|||
end
|
||||
|
||||
def archives_to_backup
|
||||
ARCHIVES_TO_BACKUP.map{ |name| (name + ".tar.gz") unless skipped?(name) }.compact
|
||||
ARCHIVES_TO_BACKUP.map { |name| (name + ".tar.gz") unless skipped?(name) }.compact
|
||||
end
|
||||
|
||||
def folders_to_backup
|
||||
FOLDERS_TO_BACKUP.reject{ |name| skipped?(name) }
|
||||
FOLDERS_TO_BACKUP.reject { |name| skipped?(name) }
|
||||
end
|
||||
|
||||
def disabled_features
|
||||
|
|
|
@ -6,6 +6,8 @@ class ProjectUrlConstrainer
|
|||
|
||||
return false unless DynamicPathValidator.valid_project_path?(full_path)
|
||||
|
||||
# We intentionally allow SELECT(*) here so result of this query can be used
|
||||
# as cache for further Project.find_by_full_path calls within request
|
||||
Project.find_by_full_path(full_path, follow_redirects: request.get?).present?
|
||||
end
|
||||
end
|
||||
|
|
|
@ -98,10 +98,11 @@ module Gitlab
|
|||
|
||||
if status.zero?
|
||||
@ee_branch_found = ee_branch_prefix
|
||||
else
|
||||
_, status = step("Fetching origin/#{ee_branch_suffix}", %W[git fetch origin #{ee_branch_suffix}])
|
||||
return
|
||||
end
|
||||
|
||||
_, status = step("Fetching origin/#{ee_branch_suffix}", %W[git fetch origin #{ee_branch_suffix}])
|
||||
|
||||
if status.zero?
|
||||
@ee_branch_found = ee_branch_suffix
|
||||
else
|
||||
|
|
|
@ -324,6 +324,23 @@ module Gitlab
|
|||
raw_log(options).map { |c| Commit.decorate(self, c) }
|
||||
end
|
||||
|
||||
# Used in gitaly-ruby
|
||||
def raw_log(options)
|
||||
actual_ref = options[:ref] || root_ref
|
||||
begin
|
||||
sha = sha_from_ref(actual_ref)
|
||||
rescue Rugged::OdbError, Rugged::InvalidError, Rugged::ReferenceError
|
||||
# Return an empty array if the ref wasn't found
|
||||
return []
|
||||
end
|
||||
|
||||
if log_using_shell?(options)
|
||||
log_by_shell(sha, options)
|
||||
else
|
||||
log_by_walk(sha, options)
|
||||
end
|
||||
end
|
||||
|
||||
def count_commits(options)
|
||||
gitaly_migrate(:count_commits) do |is_enabled|
|
||||
if is_enabled
|
||||
|
@ -733,22 +750,6 @@ module Gitlab
|
|||
sort_branches(branches, sort_by)
|
||||
end
|
||||
|
||||
def raw_log(options)
|
||||
actual_ref = options[:ref] || root_ref
|
||||
begin
|
||||
sha = sha_from_ref(actual_ref)
|
||||
rescue Rugged::OdbError, Rugged::InvalidError, Rugged::ReferenceError
|
||||
# Return an empty array if the ref wasn't found
|
||||
return []
|
||||
end
|
||||
|
||||
if log_using_shell?(options)
|
||||
log_by_shell(sha, options)
|
||||
else
|
||||
log_by_walk(sha, options)
|
||||
end
|
||||
end
|
||||
|
||||
def log_using_shell?(options)
|
||||
options[:path].present? ||
|
||||
options[:disable_walk] ||
|
||||
|
|
|
@ -10,7 +10,7 @@ module Gitlab
|
|||
def exists?
|
||||
request = Gitaly::RepositoryExistsRequest.new(repository: @gitaly_repo)
|
||||
|
||||
GitalyClient.call(@storage, :repository_service, :exists, request).exists
|
||||
GitalyClient.call(@storage, :repository_service, :repository_exists, request).exists
|
||||
end
|
||||
|
||||
def garbage_collect(create_bitmap)
|
||||
|
|
|
@ -71,7 +71,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def config
|
||||
Gitlab.config.omniauth.providers.find{|provider| provider.name == "gitlab"}
|
||||
Gitlab.config.omniauth.providers.find {|provider| provider.name == "gitlab"}
|
||||
end
|
||||
|
||||
def gitlab_options
|
||||
|
|
|
@ -47,12 +47,16 @@ module Gitlab
|
|||
end
|
||||
|
||||
def remove_symlinks!
|
||||
Dir["#{@shared.export_path}/**/*"].each do |path|
|
||||
extracted_files.each do |path|
|
||||
FileUtils.rm(path) if File.lstat(path).symlink?
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
def extracted_files
|
||||
Dir.glob("#{@shared.export_path}/**/*", File::FNM_DOTMATCH).reject { |f| f =~ /.*\/\.{1,2}$/ }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -19,6 +19,8 @@ module Gitlab
|
|||
return false if internal?(uri)
|
||||
|
||||
return true if blocked_port?(uri.port)
|
||||
return true if blocked_user_or_hostname?(uri.user)
|
||||
return true if blocked_user_or_hostname?(uri.hostname)
|
||||
|
||||
server_ips = Resolv.getaddresses(uri.hostname)
|
||||
return true if (blocked_ips & server_ips).any?
|
||||
|
@ -37,6 +39,12 @@ module Gitlab
|
|||
port < 1024 && !VALID_PORTS.include?(port)
|
||||
end
|
||||
|
||||
def blocked_user_or_hostname?(value)
|
||||
return false if value.blank?
|
||||
|
||||
value !~ /\A\p{Alnum}/
|
||||
end
|
||||
|
||||
def internal?(uri)
|
||||
internal_web?(uri) || internal_shell?(uri)
|
||||
end
|
||||
|
|
|
@ -25,6 +25,39 @@ map $http_upgrade $connection_upgrade_gitlab {
|
|||
'' close;
|
||||
}
|
||||
|
||||
## NGINX 'combined' log format with filtered query strings
|
||||
log_format gitlab_access $remote_addr - $remote_user [$time_local] "$request_method $gitlab_filtered_request_uri $server_protocol" $status $body_bytes_sent "$gitlab_filtered_http_referer" "$http_user_agent";
|
||||
|
||||
## Remove private_token from the request URI
|
||||
# In: /foo?private_token=unfiltered&authenticity_token=unfiltered&rss_token=unfiltered&...
|
||||
# Out: /foo?private_token=[FILTERED]&authenticity_token=unfiltered&rss_token=unfiltered&...
|
||||
map $request_uri $gitlab_temp_request_uri_1 {
|
||||
default $request_uri;
|
||||
~(?i)^(?<start>.*)(?<temp>[\?&]private[\-_]token)=[^&]*(?<rest>.*)$ "$start$temp=[FILTERED]$rest";
|
||||
}
|
||||
|
||||
## Remove authenticity_token from the request URI
|
||||
# In: /foo?private_token=[FILTERED]&authenticity_token=unfiltered&rss_token=unfiltered&...
|
||||
# Out: /foo?private_token=[FILTERED]&authenticity_token=[FILTERED]&rss_token=unfiltered&...
|
||||
map $gitlab_temp_request_uri_1 $gitlab_temp_request_uri_2 {
|
||||
default $gitlab_temp_request_uri_1;
|
||||
~(?i)^(?<start>.*)(?<temp>[\?&]authenticity[\-_]token)=[^&]*(?<rest>.*)$ "$start$temp=[FILTERED]$rest";
|
||||
}
|
||||
|
||||
## Remove rss_token from the request URI
|
||||
# In: /foo?private_token=[FILTERED]&authenticity_token=[FILTERED]&rss_token=unfiltered&...
|
||||
# Out: /foo?private_token=[FILTERED]&authenticity_token=[FILTERED]&rss_token=[FILTERED]&...
|
||||
map $gitlab_temp_request_uri_2 $gitlab_filtered_request_uri {
|
||||
default $gitlab_temp_request_uri_2;
|
||||
~(?i)^(?<start>.*)(?<temp>[\?&]rss[\-_]token)=[^&]*(?<rest>.*)$ "$start$temp=[FILTERED]$rest";
|
||||
}
|
||||
|
||||
## A version of the referer without the query string
|
||||
map $http_referer $gitlab_filtered_http_referer {
|
||||
default $http_referer;
|
||||
~^(?<temp>.*)\? $temp;
|
||||
}
|
||||
|
||||
## Normal HTTP host
|
||||
server {
|
||||
## Either remove "default_server" from the listen line below,
|
||||
|
@ -46,7 +79,7 @@ server {
|
|||
# set_real_ip_from YOUR_TRUSTED_ADDRESS; ## Replace this with something like 192.168.1.0/24
|
||||
|
||||
## Individual nginx logs for this GitLab vhost
|
||||
access_log /var/log/nginx/gitlab_access.log;
|
||||
access_log /var/log/nginx/gitlab_access.log gitlab_access;
|
||||
error_log /var/log/nginx/gitlab_error.log;
|
||||
|
||||
location / {
|
||||
|
|
|
@ -18,8 +18,11 @@ server {
|
|||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
proxy_cache off;
|
||||
|
||||
# The same address as passed to GitLab Pages: `-listen-proxy`
|
||||
proxy_pass http://localhost:8090/;
|
||||
proxy_pass http://localhost:8090/;
|
||||
}
|
||||
|
||||
# Define custom error pages
|
||||
|
|
|
@ -67,8 +67,11 @@ server {
|
|||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
proxy_cache off;
|
||||
|
||||
# The same address as passed to GitLab Pages: `-listen-proxy`
|
||||
proxy_pass http://localhost:8090/;
|
||||
proxy_pass http://localhost:8090/;
|
||||
}
|
||||
|
||||
# Define custom error pages
|
||||
|
|
|
@ -29,6 +29,41 @@ map $http_upgrade $connection_upgrade_gitlab_ssl {
|
|||
'' close;
|
||||
}
|
||||
|
||||
|
||||
## NGINX 'combined' log format with filtered query strings
|
||||
log_format gitlab_ssl_access $remote_addr - $remote_user [$time_local] "$request_method $gitlab_ssl_filtered_request_uri $server_protocol" $status $body_bytes_sent "$gitlab_ssl_filtered_http_referer" "$http_user_agent";
|
||||
|
||||
## Remove private_token from the request URI
|
||||
# In: /foo?private_token=unfiltered&authenticity_token=unfiltered&rss_token=unfiltered&...
|
||||
# Out: /foo?private_token=[FILTERED]&authenticity_token=unfiltered&rss_token=unfiltered&...
|
||||
map $request_uri $gitlab_ssl_temp_request_uri_1 {
|
||||
default $request_uri;
|
||||
~(?i)^(?<start>.*)(?<temp>[\?&]private[\-_]token)=[^&]*(?<rest>.*)$ "$start$temp=[FILTERED]$rest";
|
||||
}
|
||||
|
||||
## Remove authenticity_token from the request URI
|
||||
# In: /foo?private_token=[FILTERED]&authenticity_token=unfiltered&rss_token=unfiltered&...
|
||||
# Out: /foo?private_token=[FILTERED]&authenticity_token=[FILTERED]&rss_token=unfiltered&...
|
||||
map $gitlab_ssl_temp_request_uri_1 $gitlab_ssl_temp_request_uri_2 {
|
||||
default $gitlab_ssl_temp_request_uri_1;
|
||||
~(?i)^(?<start>.*)(?<temp>[\?&]authenticity[\-_]token)=[^&]*(?<rest>.*)$ "$start$temp=[FILTERED]$rest";
|
||||
}
|
||||
|
||||
## Remove rss_token from the request URI
|
||||
# In: /foo?private_token=[FILTERED]&authenticity_token=[FILTERED]&rss_token=unfiltered&...
|
||||
# Out: /foo?private_token=[FILTERED]&authenticity_token=[FILTERED]&rss_token=[FILTERED]&...
|
||||
map $gitlab_ssl_temp_request_uri_2 $gitlab_ssl_filtered_request_uri {
|
||||
default $gitlab_ssl_temp_request_uri_2;
|
||||
~(?i)^(?<start>.*)(?<temp>[\?&]rss[\-_]token)=[^&]*(?<rest>.*)$ "$start$temp=[FILTERED]$rest";
|
||||
}
|
||||
|
||||
## A version of the referer without the query string
|
||||
map $http_referer $gitlab_ssl_filtered_http_referer {
|
||||
default $http_referer;
|
||||
~^(?<temp>.*)\? $temp;
|
||||
}
|
||||
|
||||
|
||||
## Redirects all HTTP traffic to the HTTPS host
|
||||
server {
|
||||
## Either remove "default_server" from the listen line below,
|
||||
|
@ -40,7 +75,7 @@ server {
|
|||
server_name YOUR_SERVER_FQDN; ## Replace this with something like gitlab.example.com
|
||||
server_tokens off; ## Don't show the nginx version number, a security best practice
|
||||
return 301 https://$http_host$request_uri;
|
||||
access_log /var/log/nginx/gitlab_access.log;
|
||||
access_log /var/log/nginx/gitlab_access.log gitlab_ssl_access;
|
||||
error_log /var/log/nginx/gitlab_error.log;
|
||||
}
|
||||
|
||||
|
@ -93,7 +128,7 @@ server {
|
|||
# set_real_ip_from YOUR_TRUSTED_ADDRESS; ## Replace this with something like 192.168.1.0/24
|
||||
|
||||
## Individual nginx logs for this GitLab vhost
|
||||
access_log /var/log/nginx/gitlab_access.log;
|
||||
access_log /var/log/nginx/gitlab_access.log gitlab_ssl_access;
|
||||
error_log /var/log/nginx/gitlab_error.log;
|
||||
|
||||
location / {
|
||||
|
|
|
@ -41,8 +41,6 @@ namespace :gitlab do
|
|||
end
|
||||
|
||||
namespace :gitlab_shell do
|
||||
include SystemCheck::Helpers
|
||||
|
||||
desc "GitLab | Check the configuration of GitLab Shell"
|
||||
task check: :environment do
|
||||
warn_user_is_not_gitlab
|
||||
|
@ -249,8 +247,6 @@ namespace :gitlab do
|
|||
end
|
||||
|
||||
namespace :sidekiq do
|
||||
include SystemCheck::Helpers
|
||||
|
||||
desc "GitLab | Check the configuration of Sidekiq"
|
||||
task check: :environment do
|
||||
warn_user_is_not_gitlab
|
||||
|
@ -309,8 +305,6 @@ namespace :gitlab do
|
|||
end
|
||||
|
||||
namespace :incoming_email do
|
||||
include SystemCheck::Helpers
|
||||
|
||||
desc "GitLab | Check the configuration of Reply by email"
|
||||
task check: :environment do
|
||||
warn_user_is_not_gitlab
|
||||
|
@ -444,8 +438,6 @@ namespace :gitlab do
|
|||
end
|
||||
|
||||
namespace :ldap do
|
||||
include SystemCheck::Helpers
|
||||
|
||||
task :check, [:limit] => :environment do |_, args|
|
||||
# Only show up to 100 results because LDAP directories can be very big.
|
||||
# This setting only affects the `rake gitlab:check` script.
|
||||
|
@ -501,8 +493,6 @@ namespace :gitlab do
|
|||
end
|
||||
|
||||
namespace :repo do
|
||||
include SystemCheck::Helpers
|
||||
|
||||
desc "GitLab | Check the integrity of the repositories managed by GitLab"
|
||||
task check: :environment do
|
||||
Gitlab.config.repositories.storages.each do |name, repository_storage|
|
||||
|
@ -517,8 +507,6 @@ namespace :gitlab do
|
|||
end
|
||||
|
||||
namespace :user do
|
||||
include SystemCheck::Helpers
|
||||
|
||||
desc "GitLab | Check the integrity of a specific user's repositories"
|
||||
task :check_repos, [:username] => :environment do |t, args|
|
||||
username = args[:username] || prompt("Check repository integrity for fsername? ".color(:blue))
|
||||
|
|
|
@ -4,5 +4,5 @@ require 'tasks/gitlab/task_helpers'
|
|||
StateMachines::Machine.ignore_method_conflicts = true if ENV['CRON']
|
||||
|
||||
namespace :gitlab do
|
||||
include Gitlab::TaskHelpers
|
||||
extend SystemCheck::Helpers
|
||||
end
|
||||
|
|
|
@ -5,6 +5,8 @@ module Gitlab
|
|||
TaskAbortedByUserError = Class.new(StandardError)
|
||||
|
||||
module TaskHelpers
|
||||
extend self
|
||||
|
||||
# Ask if the user wants to continue
|
||||
#
|
||||
# Returns "yes" the user chose to continue
|
||||
|
|
|
@ -417,7 +417,7 @@ msgstr[0] "Fourche"
|
|||
msgstr[1] "Fourches"
|
||||
|
||||
msgid "ForkedFromProjectPath|Forked from"
|
||||
msgstr "Fouché depuis"
|
||||
msgstr "Fourché depuis"
|
||||
|
||||
msgid "From issue creation until deploy to production"
|
||||
msgstr "Depuis la création de l'incident jusqu'au déploiement en production"
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue