summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/diffs/components/diff_content.vue4
-rw-r--r--app/assets/javascripts/diffs/components/diff_table_cell.vue28
-rw-r--r--app/assets/javascripts/diffs/components/inline_diff_table_row.vue104
-rw-r--r--app/assets/javascripts/diffs/components/inline_diff_view.vue33
-rw-r--r--app/assets/javascripts/diffs/components/parallel_diff_table_row.vue (renamed from app/assets/javascripts/diffs/components/diff_table_row.vue)71
-rw-r--r--app/assets/javascripts/diffs/components/parallel_diff_view.vue40
-rw-r--r--app/assets/javascripts/diffs/mixins/diff_content.js57
-rw-r--r--app/assets/javascripts/diffs/store/mutation_types.js1
-rw-r--r--app/assets/javascripts/diffs/store/mutations.js6
-rw-r--r--app/assets/stylesheets/framework/header.scss2
-rw-r--r--app/controllers/admin/hooks_controller.rb3
-rw-r--r--app/controllers/projects/hooks_controller.rb3
-rw-r--r--app/controllers/sessions_controller.rb20
-rw-r--r--app/models/hooks/web_hook_log.rb5
-rw-r--r--app/models/project_services/bamboo_service.rb22
-rw-r--r--app/presenters/project_presenter.rb5
-rw-r--r--app/serializers/build_details_entity.rb2
-rw-r--r--app/uploaders/file_uploader.rb28
-rw-r--r--app/views/layouts/header/_default.html.haml2
-rw-r--r--app/workers/all_queues.yml1
-rw-r--r--app/workers/prune_web_hook_logs_worker.rb26
21 files changed, 304 insertions, 159 deletions
diff --git a/app/assets/javascripts/diffs/components/diff_content.vue b/app/assets/javascripts/diffs/components/diff_content.vue
index 48ba967285f..b6af49c7e2e 100644
--- a/app/assets/javascripts/diffs/components/diff_content.vue
+++ b/app/assets/javascripts/diffs/components/diff_content.vue
@@ -39,12 +39,12 @@ export default {
<div class="diff-viewer">
<template v-if="isTextFile">
<inline-diff-view
- v-if="isInlineView"
+ v-show="isInlineView"
:diff-file="diffFile"
:diff-lines="diffFile.highlightedDiffLines || []"
/>
<parallel-diff-view
- v-else-if="isParallelView"
+ v-show="isParallelView"
:diff-file="diffFile"
:diff-lines="diffFile.parallelDiffLines || []"
/>
diff --git a/app/assets/javascripts/diffs/components/diff_table_cell.vue b/app/assets/javascripts/diffs/components/diff_table_cell.vue
index 68fe6787f9b..5b08b161114 100644
--- a/app/assets/javascripts/diffs/components/diff_table_cell.vue
+++ b/app/assets/javascripts/diffs/components/diff_table_cell.vue
@@ -10,6 +10,9 @@ import {
NEW_NO_NEW_LINE_TYPE,
LINE_HOVER_CLASS_NAME,
LINE_UNFOLD_CLASS_NAME,
+ INLINE_DIFF_VIEW_TYPE,
+ LINE_POSITION_LEFT,
+ LINE_POSITION_RIGHT,
} from '../constants';
export default {
@@ -25,6 +28,11 @@ export default {
type: Object,
required: true,
},
+ diffViewType: {
+ type: String,
+ required: false,
+ default: INLINE_DIFF_VIEW_TYPE,
+ },
showCommentButton: {
type: Boolean,
required: false,
@@ -57,13 +65,19 @@ export default {
},
},
computed: {
- ...mapGetters(['isLoggedIn', 'isInlineView']),
+ ...mapGetters(['isLoggedIn']),
normalizedLine() {
- if (this.isInlineView) {
- return this.line;
+ let normalizedLine;
+
+ if (this.diffViewType === INLINE_DIFF_VIEW_TYPE) {
+ normalizedLine = this.line;
+ } else if (this.linePosition === LINE_POSITION_LEFT) {
+ normalizedLine = this.line.left;
+ } else if (this.linePosition === LINE_POSITION_RIGHT) {
+ normalizedLine = this.line.right;
}
- return this.lineType === OLD_LINE_TYPE ? this.line.left : this.line.right;
+ return normalizedLine;
},
isMatchLine() {
return this.normalizedLine.type === MATCH_LINE_TYPE;
@@ -72,10 +86,10 @@ export default {
return this.normalizedLine.type === CONTEXT_LINE_TYPE;
},
isMetaLine() {
+ const { type } = this.normalizedLine;
+
return (
- this.normalizedLine.type === OLD_NO_NEW_LINE_TYPE ||
- this.normalizedLine.type === NEW_NO_NEW_LINE_TYPE ||
- this.normalizedLine.type === EMPTY_CELL_TYPE
+ type === OLD_NO_NEW_LINE_TYPE || type === NEW_NO_NEW_LINE_TYPE || type === EMPTY_CELL_TYPE
);
},
classNameMap() {
diff --git a/app/assets/javascripts/diffs/components/inline_diff_table_row.vue b/app/assets/javascripts/diffs/components/inline_diff_table_row.vue
new file mode 100644
index 00000000000..a2470843ca6
--- /dev/null
+++ b/app/assets/javascripts/diffs/components/inline_diff_table_row.vue
@@ -0,0 +1,104 @@
+<script>
+import { mapGetters } from 'vuex';
+import DiffTableCell from './diff_table_cell.vue';
+import {
+ NEW_LINE_TYPE,
+ OLD_LINE_TYPE,
+ CONTEXT_LINE_TYPE,
+ CONTEXT_LINE_CLASS_NAME,
+ PARALLEL_DIFF_VIEW_TYPE,
+ LINE_POSITION_LEFT,
+ LINE_POSITION_RIGHT,
+} from '../constants';
+
+export default {
+ components: {
+ DiffTableCell,
+ },
+ props: {
+ diffFile: {
+ type: Object,
+ required: true,
+ },
+ line: {
+ type: Object,
+ required: true,
+ },
+ isBottom: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ },
+ data() {
+ return {
+ isHover: false,
+ };
+ },
+ computed: {
+ ...mapGetters(['isInlineView']),
+ isContextLine() {
+ return this.line.type === CONTEXT_LINE_TYPE;
+ },
+ classNameMap() {
+ return {
+ [this.line.type]: this.line.type,
+ [CONTEXT_LINE_CLASS_NAME]: this.isContextLine,
+ [PARALLEL_DIFF_VIEW_TYPE]: this.isParallelView,
+ };
+ },
+ inlineRowId() {
+ const { lineCode, oldLine, newLine } = this.line;
+
+ return lineCode || `${this.diffFile.fileHash}_${oldLine}_${newLine}`;
+ },
+ },
+ created() {
+ this.newLineType = NEW_LINE_TYPE;
+ this.oldLineType = OLD_LINE_TYPE;
+ this.linePositionLeft = LINE_POSITION_LEFT;
+ this.linePositionRight = LINE_POSITION_RIGHT;
+ },
+ methods: {
+ handleMouseMove(e) {
+ // To show the comment icon on the gutter we need to know if we hover the line.
+ // Current table structure doesn't allow us to do this with CSS in both of the diff view types
+ this.isHover = e.type === 'mouseover';
+ },
+ },
+};
+</script>
+
+<template>
+ <tr
+ :id="inlineRowId"
+ :class="classNameMap"
+ class="line_holder"
+ @mouseover="handleMouseMove"
+ @mouseout="handleMouseMove"
+ >
+ <diff-table-cell
+ :diff-file="diffFile"
+ :line="line"
+ :line-type="oldLineType"
+ :is-bottom="isBottom"
+ :is-hover="isHover"
+ :show-comment-button="true"
+ class="diff-line-num old_line"
+ />
+ <diff-table-cell
+ :diff-file="diffFile"
+ :line="line"
+ :line-type="newLineType"
+ :is-bottom="isBottom"
+ :is-hover="isHover"
+ class="diff-line-num new_line"
+ />
+ <diff-table-cell
+ :class="line.type"
+ :diff-file="diffFile"
+ :line="line"
+ :is-content-line="true"
+ />
+ </tr>
+</template>
diff --git a/app/assets/javascripts/diffs/components/inline_diff_view.vue b/app/assets/javascripts/diffs/components/inline_diff_view.vue
index e72f85df77a..b884230fb63 100644
--- a/app/assets/javascripts/diffs/components/inline_diff_view.vue
+++ b/app/assets/javascripts/diffs/components/inline_diff_view.vue
@@ -1,12 +1,39 @@
<script>
-import diffContentMixin from '../mixins/diff_content';
+import { mapGetters } from 'vuex';
+import inlineDiffTableRow from './inline_diff_table_row.vue';
import inlineDiffCommentRow from './inline_diff_comment_row.vue';
+import { trimFirstCharOfLineContent } from '../store/utils';
export default {
components: {
inlineDiffCommentRow,
+ inlineDiffTableRow,
+ },
+ props: {
+ diffFile: {
+ type: Object,
+ required: true,
+ },
+ diffLines: {
+ type: Array,
+ required: true,
+ },
+ },
+ computed: {
+ ...mapGetters(['commit']),
+ normalizedDiffLines() {
+ return this.diffLines.map(line => (line.richText ? trimFirstCharOfLineContent(line) : line));
+ },
+ diffLinesLength() {
+ return this.normalizedDiffLines.length;
+ },
+ commitId() {
+ return this.commit && this.commit.id;
+ },
+ userColorScheme() {
+ return window.gon.user_color_scheme;
+ },
},
- mixins: [diffContentMixin],
};
</script>
@@ -19,7 +46,7 @@ export default {
<template
v-for="(line, index) in normalizedDiffLines"
>
- <diff-table-row
+ <inline-diff-table-row
:diff-file="diffFile"
:line="line"
:is-bottom="index + 1 === diffLinesLength"
diff --git a/app/assets/javascripts/diffs/components/diff_table_row.vue b/app/assets/javascripts/diffs/components/parallel_diff_table_row.vue
index 8716fdaf44d..eb769584d74 100644
--- a/app/assets/javascripts/diffs/components/diff_table_row.vue
+++ b/app/assets/javascripts/diffs/components/parallel_diff_table_row.vue
@@ -35,30 +35,21 @@ export default {
},
data() {
return {
- isHover: false,
isLeftHover: false,
isRightHover: false,
};
},
computed: {
- ...mapGetters(['isInlineView', 'isParallelView']),
+ ...mapGetters(['isParallelView']),
isContextLine() {
- return this.line.left
- ? this.line.left.type === CONTEXT_LINE_TYPE
- : this.line.type === CONTEXT_LINE_TYPE;
+ return this.line.left.type === CONTEXT_LINE_TYPE;
},
classNameMap() {
return {
- [this.line.type]: this.line.type,
[CONTEXT_LINE_CLASS_NAME]: this.isContextLine,
[PARALLEL_DIFF_VIEW_TYPE]: this.isParallelView,
};
},
- inlineRowId() {
- const { lineCode, oldLine, newLine } = this.line;
-
- return lineCode || `${this.diffFile.fileHash}_${oldLine}_${newLine}`;
- },
parallelViewLeftLineType() {
if (this.line.right.type === NEW_NO_NEW_LINE_TYPE) {
return OLD_NO_NEW_LINE_TYPE;
@@ -72,23 +63,19 @@ export default {
this.oldLineType = OLD_LINE_TYPE;
this.linePositionLeft = LINE_POSITION_LEFT;
this.linePositionRight = LINE_POSITION_RIGHT;
+ this.parallelDiffViewType = PARALLEL_DIFF_VIEW_TYPE;
},
methods: {
handleMouseMove(e) {
const isHover = e.type === 'mouseover';
+ const hoveringCell = e.target.closest('td');
+ const allCellsInHoveringRow = Array.from(e.currentTarget.children);
+ const hoverIndex = allCellsInHoveringRow.indexOf(hoveringCell);
- if (this.isInlineView) {
- this.isHover = isHover;
+ if (hoverIndex >= 2) {
+ this.isRightHover = isHover;
} else {
- const hoveringCell = e.target.closest('td');
- const allCellsInHoveringRow = Array.from(e.currentTarget.children);
- const hoverIndex = allCellsInHoveringRow.indexOf(hoveringCell);
-
- if (hoverIndex >= 2) {
- this.isRightHover = isHover;
- } else {
- this.isLeftHover = isHover;
- }
+ this.isLeftHover = isHover;
}
},
// Prevent text selecting on both sides of parallel diff view
@@ -110,40 +97,6 @@ export default {
<template>
<tr
- v-if="isInlineView"
- :id="inlineRowId"
- :class="classNameMap"
- class="line_holder"
- @mouseover="handleMouseMove"
- @mouseout="handleMouseMove"
- >
- <diff-table-cell
- :diff-file="diffFile"
- :line="line"
- :line-type="oldLineType"
- :is-bottom="isBottom"
- :is-hover="isHover"
- :show-comment-button="true"
- class="diff-line-num old_line"
- />
- <diff-table-cell
- :diff-file="diffFile"
- :line="line"
- :line-type="newLineType"
- :is-bottom="isBottom"
- :is-hover="isHover"
- class="diff-line-num new_line"
- />
- <diff-table-cell
- :class="line.type"
- :diff-file="diffFile"
- :line="line"
- :is-content-line="true"
- />
- </tr>
-
- <tr
- v-else
:class="classNameMap"
class="line_holder"
@mouseover="handleMouseMove"
@@ -157,6 +110,7 @@ export default {
:is-bottom="isBottom"
:is-hover="isLeftHover"
:show-comment-button="true"
+ :diff-view-type="parallelDiffViewType"
class="diff-line-num old_line"
/>
<diff-table-cell
@@ -164,7 +118,9 @@ export default {
:diff-file="diffFile"
:line="line"
:is-content-line="true"
+ :line-position="linePositionLeft"
:line-type="parallelViewLeftLineType"
+ :diff-view-type="parallelDiffViewType"
class="line_content parallel left-side"
@mousedown.native="handleParallelLineMouseDown"
/>
@@ -176,6 +132,7 @@ export default {
:is-bottom="isBottom"
:is-hover="isRightHover"
:show-comment-button="true"
+ :diff-view-type="parallelDiffViewType"
class="diff-line-num new_line"
/>
<diff-table-cell
@@ -183,7 +140,9 @@ export default {
:diff-file="diffFile"
:line="line"
:is-content-line="true"
+ :line-position="linePositionRight"
:line-type="line.right.type"
+ :diff-view-type="parallelDiffViewType"
class="line_content parallel right-side"
@mousedown.native="handleParallelLineMouseDown"
/>
diff --git a/app/assets/javascripts/diffs/components/parallel_diff_view.vue b/app/assets/javascripts/diffs/components/parallel_diff_view.vue
index ed92b4ee249..d7280338b68 100644
--- a/app/assets/javascripts/diffs/components/parallel_diff_view.vue
+++ b/app/assets/javascripts/diffs/components/parallel_diff_view.vue
@@ -1,25 +1,53 @@
<script>
-import diffContentMixin from '../mixins/diff_content';
+import { mapGetters } from 'vuex';
+import parallelDiffTableRow from './parallel_diff_table_row.vue';
import parallelDiffCommentRow from './parallel_diff_comment_row.vue';
import { EMPTY_CELL_TYPE } from '../constants';
+import { trimFirstCharOfLineContent } from '../store/utils';
export default {
components: {
+ parallelDiffTableRow,
parallelDiffCommentRow,
},
- mixins: [diffContentMixin],
+ props: {
+ diffFile: {
+ type: Object,
+ required: true,
+ },
+ diffLines: {
+ type: Array,
+ required: true,
+ },
+ },
computed: {
+ ...mapGetters(['commit']),
parallelDiffLines() {
- return this.normalizedDiffLines.map(line => {
- if (!line.left) {
+ return this.diffLines.map(line => {
+ if (line.left) {
+ Object.assign(line, { left: trimFirstCharOfLineContent(line.left) });
+ } else {
Object.assign(line, { left: { type: EMPTY_CELL_TYPE } });
- } else if (!line.right) {
+ }
+
+ if (line.right) {
+ Object.assign(line, { right: trimFirstCharOfLineContent(line.right) });
+ } else {
Object.assign(line, { right: { type: EMPTY_CELL_TYPE } });
}
return line;
});
},
+ diffLinesLength() {
+ return this.parallelDiffLines.length;
+ },
+ commitId() {
+ return this.commit && this.commit.id;
+ },
+ userColorScheme() {
+ return window.gon.user_color_scheme;
+ },
},
};
</script>
@@ -35,7 +63,7 @@ export default {
<template
v-for="(line, index) in parallelDiffLines"
>
- <diff-table-row
+ <parallel-diff-table-row
:diff-file="diffFile"
:line="line"
:is-bottom="index + 1 === diffLinesLength"
diff --git a/app/assets/javascripts/diffs/mixins/diff_content.js b/app/assets/javascripts/diffs/mixins/diff_content.js
deleted file mode 100644
index ebb511d3a7e..00000000000
--- a/app/assets/javascripts/diffs/mixins/diff_content.js
+++ /dev/null
@@ -1,57 +0,0 @@
-import { mapGetters } from 'vuex';
-import diffDiscussions from '../components/diff_discussions.vue';
-import diffLineGutterContent from '../components/diff_line_gutter_content.vue';
-import diffLineNoteForm from '../components/diff_line_note_form.vue';
-import diffTableRow from '../components/diff_table_row.vue';
-import { trimFirstCharOfLineContent } from '../store/utils';
-
-export default {
- props: {
- diffFile: {
- type: Object,
- required: true,
- },
- diffLines: {
- type: Array,
- required: true,
- },
- },
- components: {
- diffDiscussions,
- diffTableRow,
- diffLineNoteForm,
- diffLineGutterContent,
- },
- computed: {
- ...mapGetters(['commit']),
- commitId() {
- return this.commit && this.commit.id;
- },
- userColorScheme() {
- return window.gon.user_color_scheme;
- },
- normalizedDiffLines() {
- return this.diffLines.map(line => {
- if (line.richText) {
- return trimFirstCharOfLineContent(line);
- }
-
- if (line.left) {
- Object.assign(line, { left: trimFirstCharOfLineContent(line.left) });
- }
-
- if (line.right) {
- Object.assign(line, { right: trimFirstCharOfLineContent(line.right) });
- }
-
- return line;
- });
- },
- diffLinesLength() {
- return this.normalizedDiffLines.length;
- },
- fileHash() {
- return this.diffFile.fileHash;
- },
- },
-};
diff --git a/app/assets/javascripts/diffs/store/mutation_types.js b/app/assets/javascripts/diffs/store/mutation_types.js
index 63e9239dce4..2c8e1a1466f 100644
--- a/app/assets/javascripts/diffs/store/mutation_types.js
+++ b/app/assets/javascripts/diffs/store/mutation_types.js
@@ -1,7 +1,6 @@
export const SET_BASE_CONFIG = 'SET_BASE_CONFIG';
export const SET_LOADING = 'SET_LOADING';
export const SET_DIFF_DATA = 'SET_DIFF_DATA';
-export const SET_DIFF_FILES = 'SET_DIFF_FILES';
export const SET_DIFF_VIEW_TYPE = 'SET_DIFF_VIEW_TYPE';
export const SET_MERGE_REQUEST_DIFFS = 'SET_MERGE_REQUEST_DIFFS';
export const ADD_COMMENT_FORM_LINE = 'ADD_COMMENT_FORM_LINE';
diff --git a/app/assets/javascripts/diffs/store/mutations.js b/app/assets/javascripts/diffs/store/mutations.js
index 339a33f8b71..8aa8a114c6f 100644
--- a/app/assets/javascripts/diffs/store/mutations.js
+++ b/app/assets/javascripts/diffs/store/mutations.js
@@ -20,12 +20,6 @@ export default {
});
},
- [types.SET_DIFF_FILES](state, diffFiles) {
- Object.assign(state, {
- diffFiles: convertObjectPropsToCamelCase(diffFiles, { deep: true }),
- });
- },
-
[types.SET_MERGE_REQUEST_DIFFS](state, mergeRequestDiffs) {
Object.assign(state, {
mergeRequestDiffs: convertObjectPropsToCamelCase(mergeRequestDiffs, { deep: true }),
diff --git a/app/assets/stylesheets/framework/header.scss b/app/assets/stylesheets/framework/header.scss
index 5789c3fa1b1..8bcaf5eb6ac 100644
--- a/app/assets/stylesheets/framework/header.scss
+++ b/app/assets/stylesheets/framework/header.scss
@@ -268,8 +268,6 @@
.navbar-sub-nav,
.navbar-nav {
- align-items: center;
-
> li {
> a:hover,
> a:focus {
diff --git a/app/controllers/admin/hooks_controller.rb b/app/controllers/admin/hooks_controller.rb
index fb788c47ef1..6944857bd33 100644
--- a/app/controllers/admin/hooks_controller.rb
+++ b/app/controllers/admin/hooks_controller.rb
@@ -52,8 +52,7 @@ class Admin::HooksController < Admin::ApplicationController
end
def hook_logs
- @hook_logs ||=
- Kaminari.paginate_array(hook.web_hook_logs.order(created_at: :desc)).page(params[:page])
+ @hook_logs ||= hook.web_hook_logs.recent.page(params[:page])
end
def hook_params
diff --git a/app/controllers/projects/hooks_controller.rb b/app/controllers/projects/hooks_controller.rb
index dd7aa1a67b9..6800d742b0a 100644
--- a/app/controllers/projects/hooks_controller.rb
+++ b/app/controllers/projects/hooks_controller.rb
@@ -58,8 +58,7 @@ class Projects::HooksController < Projects::ApplicationController
end
def hook_logs
- @hook_logs ||=
- Kaminari.paginate_array(hook.web_hook_logs.order(created_at: :desc)).page(params[:page])
+ @hook_logs ||= hook.web_hook_logs.recent.page(params[:page])
end
def hook_params
diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
index 7aa277b3614..1de6ae24622 100644
--- a/app/controllers/sessions_controller.rb
+++ b/app/controllers/sessions_controller.rb
@@ -62,7 +62,11 @@ class SessionsController < Devise::SessionsController
return unless captcha_enabled?
return unless Gitlab::Recaptcha.load_configurations!
- unless verify_recaptcha
+ if verify_recaptcha
+ increment_successful_login_captcha_counter
+ else
+ increment_failed_login_captcha_counter
+
self.resource = resource_class.new
flash[:alert] = 'There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.'
flash.delete :recaptcha_error
@@ -71,6 +75,20 @@ class SessionsController < Devise::SessionsController
end
end
+ def increment_failed_login_captcha_counter
+ Gitlab::Metrics.counter(
+ :failed_login_captcha_total,
+ 'Number of failed CAPTCHA attempts for logins'.freeze
+ ).increment
+ end
+
+ def increment_successful_login_captcha_counter
+ Gitlab::Metrics.counter(
+ :successful_login_captcha_total,
+ 'Number of successful CAPTCHA attempts for logins'.freeze
+ ).increment
+ end
+
def log_failed_login
Gitlab::AppLogger.info("Failed Login: username=#{user_params[:login]} ip=#{request.remote_ip}")
end
diff --git a/app/models/hooks/web_hook_log.rb b/app/models/hooks/web_hook_log.rb
index e72c125fb69..59a1f2aed69 100644
--- a/app/models/hooks/web_hook_log.rb
+++ b/app/models/hooks/web_hook_log.rb
@@ -7,6 +7,11 @@ class WebHookLog < ActiveRecord::Base
validates :web_hook, presence: true
+ def self.recent
+ where('created_at >= ?', 2.days.ago.beginning_of_day)
+ .order(created_at: :desc)
+ end
+
def success?
response_status =~ /^2/
end
diff --git a/app/models/project_services/bamboo_service.rb b/app/models/project_services/bamboo_service.rb
index 7f4c47a6d14..edc5c00d9c4 100644
--- a/app/models/project_services/bamboo_service.rb
+++ b/app/models/project_services/bamboo_service.rb
@@ -67,11 +67,11 @@ class BambooService < CiService
def execute(data)
return unless supported_events.include?(data[:object_kind])
- get_path("updateAndBuild.action?buildKey=#{build_key}")
+ get_path("updateAndBuild.action", { buildKey: build_key })
end
def calculate_reactive_cache(sha, ref)
- response = get_path("rest/api/latest/result?label=#{sha}")
+ response = get_path("rest/api/latest/result/byChangeset/#{sha}")
{ build_page: read_build_page(response), commit_status: read_commit_status(response) }
end
@@ -113,18 +113,20 @@ class BambooService < CiService
URI.join("#{bamboo_url}/", path).to_s
end
- def get_path(path)
+ def get_path(path, query_params = {})
url = build_url(path)
if username.blank? && password.blank?
- Gitlab::HTTP.get(url, verify: false)
+ Gitlab::HTTP.get(url, verify: false, query: query_params)
else
- url << '&os_authType=basic'
- Gitlab::HTTP.get(url, verify: false,
- basic_auth: {
- username: username,
- password: password
- })
+ query_params[:os_authType] = 'basic'
+ Gitlab::HTTP.get(url,
+ verify: false,
+ query: query_params,
+ basic_auth: {
+ username: username,
+ password: password
+ })
end
end
end
diff --git a/app/presenters/project_presenter.rb b/app/presenters/project_presenter.rb
index ad655a7b3f4..d4d622d84ab 100644
--- a/app/presenters/project_presenter.rb
+++ b/app/presenters/project_presenter.rb
@@ -27,6 +27,7 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated
def statistics_buttons(show_auto_devops_callout:)
[
+ readme_anchor_data,
changelog_anchor_data,
license_anchor_data,
contribution_guide_anchor_data,
@@ -212,11 +213,11 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated
end
def readme_anchor_data
- if current_user && can_current_user_push_to_default_branch? && repository.readme.blank?
+ if current_user && can_current_user_push_to_default_branch? && repository.readme.nil?
OpenStruct.new(enabled: false,
label: _('Add Readme'),
link: add_readme_path)
- elsif repository.readme.present?
+ elsif repository.readme
OpenStruct.new(enabled: true,
label: _('Readme'),
link: default_view != 'readme' ? readme_path : '#readme')
diff --git a/app/serializers/build_details_entity.rb b/app/serializers/build_details_entity.rb
index ca4480fe2b1..2de9624aed4 100644
--- a/app/serializers/build_details_entity.rb
+++ b/app/serializers/build_details_entity.rb
@@ -35,7 +35,7 @@ class BuildDetailsEntity < JobEntity
def build_failed_issue_options
{ title: "Job Failed ##{build.id}",
- description: "Job [##{build.id}](#{project_job_path(project, build)}) failed for #{build.sha}:\n" }
+ description: "Job [##{build.id}](#{project_job_url(project, build)}) failed for #{build.sha}:\n" }
end
def current_user
diff --git a/app/uploaders/file_uploader.rb b/app/uploaders/file_uploader.rb
index 36bc0a4575a..73606eb9f83 100644
--- a/app/uploaders/file_uploader.rb
+++ b/app/uploaders/file_uploader.rb
@@ -81,6 +81,13 @@ class FileUploader < GitlabUploader
apply_context!(uploader_context)
end
+ def initialize_copy(from)
+ super
+
+ @secret = self.class.generate_secret
+ @upload = nil # calling record_upload would delete the old upload if set
+ end
+
# enforce the usage of Hashed storage when storing to
# remote store as the FileMover doesn't support OS
def base_dir(store = nil)
@@ -144,6 +151,27 @@ class FileUploader < GitlabUploader
@secret ||= self.class.generate_secret
end
+ # return a new uploader with a file copy on another project
+ def self.copy_to(uploader, to_project)
+ moved = uploader.dup.tap do |u|
+ u.model = to_project
+ end
+
+ moved.copy_file(uploader.file)
+ moved
+ end
+
+ def copy_file(file)
+ to_path = if file_storage?
+ File.join(self.class.root, store_path)
+ else
+ store_path
+ end
+
+ self.file = file.copy_to(to_path)
+ record_upload # after_store is not triggered
+ end
+
private
def apply_context!(uploader_context)
diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml
index 5cec443e969..d8e32651b36 100644
--- a/app/views/layouts/header/_default.html.haml
+++ b/app/views/layouts/header/_default.html.haml
@@ -21,7 +21,7 @@
- if current_user
= render 'layouts/header/new_dropdown'
- if header_link?(:search)
- %li.nav-item.d-none.d-sm-none.d-md-block
+ %li.nav-item.d-none.d-sm-none.d-md-block.m-auto
= render 'layouts/search' unless current_controller?(:search)
%li.nav-item.d-inline-block.d-sm-none.d-md-none
= link_to search_path, title: 'Search', aria: { label: "Search" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml
index d06f51b1828..b8b854853b7 100644
--- a/app/workers/all_queues.yml
+++ b/app/workers/all_queues.yml
@@ -20,6 +20,7 @@
- cronjob:ci_archive_traces_cron
- cronjob:trending_projects
- cronjob:issue_due_scheduler
+- cronjob:prune_web_hook_logs
- gcp_cluster:cluster_install_app
- gcp_cluster:cluster_provision
diff --git a/app/workers/prune_web_hook_logs_worker.rb b/app/workers/prune_web_hook_logs_worker.rb
new file mode 100644
index 00000000000..45c7d32f7eb
--- /dev/null
+++ b/app/workers/prune_web_hook_logs_worker.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+# Worker that deletes a fixed number of outdated rows from the "web_hook_logs"
+# table.
+class PruneWebHookLogsWorker
+ include ApplicationWorker
+ include CronjobQueue
+
+ # The maximum number of rows to remove in a single job.
+ DELETE_LIMIT = 50_000
+
+ def perform
+ # MySQL doesn't allow "DELETE FROM ... WHERE id IN ( ... )" if the inner
+ # query refers to the same table. To work around this we wrap the IN body in
+ # another sub query.
+ WebHookLog
+ .where(
+ 'id IN (SELECT id FROM (?) ids_to_remove)',
+ WebHookLog
+ .select(:id)
+ .where('created_at < ?', 90.days.ago.beginning_of_day)
+ .limit(DELETE_LIMIT)
+ )
+ .delete_all
+ end
+end