Commit 28290459 authored by Stan Hu's avatar Stan Hu

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

parents 11dd390c 2f16eab0
image: "dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.4.4-golang-1.9-git-2.17-chrome-67.0-node-8.x-yarn-1.2-postgresql-9.6-graphicsmagick-1.3.29"
image: "dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.4.4-golang-1.9-git-2.18-chrome-67.0-node-8.x-yarn-1.2-postgresql-9.6-graphicsmagick-1.3.29"
.dedicated-runner: &dedicated-runner
retry: 1
......@@ -86,7 +86,9 @@ stages:
.rails5: &rails5
allow_failure: true
only:
- /rails5/
variables:
- $CI_COMMIT_REF_NAME =~ /rails5/
- $RAILS5_ENABLED
variables:
BUNDLE_GEMFILE: "Gemfile.rails5"
RAILS5: "true"
......@@ -327,7 +329,7 @@ cloud-native-image:
cache: {}
script:
- gem install gitlab --no-ri --no-rdoc
- ./scripts/trigger-build cng
- BUILD_TRIGGER_TOKEN=$CI_JOB_TOKEN scripts/trigger-build cng
only:
- tags@gitlab-org/gitlab-ce
- tags@gitlab-org/gitlab-ee
......@@ -348,24 +350,6 @@ retrieve-tests-metadata:
- wget -O $FLAKY_RSPEC_SUITE_REPORT_PATH http://${TESTS_METADATA_S3_BUCKET}.s3.amazonaws.com/$FLAKY_RSPEC_SUITE_REPORT_PATH || rm $FLAKY_RSPEC_SUITE_REPORT_PATH
- '[[ -f $FLAKY_RSPEC_SUITE_REPORT_PATH ]] || echo "{}" > ${FLAKY_RSPEC_SUITE_REPORT_PATH}'
danger-review:
image: registry.gitlab.com/gitlab-org/gitaly/dangercontainer:latest
stage: prepare
before_script:
- source scripts/utils.sh
- retry gem install danger --no-ri --no-rdoc
cache: {}
only:
refs:
- branches@gitlab-org/gitlab-ce
- branches@gitlab-org/gitlab-ee
except:
variables:
- $CI_COMMIT_REF_NAME =~ /^ce-to-ee-.*/
script:
- git version
- danger --fail-on-errors=true
update-tests-metadata:
<<: *tests-metadata-state
<<: *only-canonical-masters
......@@ -454,6 +438,27 @@ setup-test-env:
- config/secrets.yml
- vendor/gitaly-ruby
danger-review:
image: registry.gitlab.com/gitlab-org/gitaly/dangercontainer:latest
stage: test
allow_failure: true
before_script:
- source scripts/utils.sh
- retry gem install danger --no-ri --no-rdoc
cache: {}
only:
refs:
- branches@gitlab-org/gitlab-ce
- branches@gitlab-org/gitlab-ee
except:
refs:
- master
variables:
- $CI_COMMIT_REF_NAME =~ /^ce-to-ee-.*/
script:
- git version
- danger --fail-on-errors=true
rspec-pg 0 30: *rspec-metadata-pg
rspec-pg 1 30: *rspec-metadata-pg
rspec-pg 2 30: *rspec-metadata-pg
......
......@@ -34,17 +34,17 @@ When removing columns, tables, indexes or other structures:
## General checklist
- [ ] [Changelog entry](https://docs.gitlab.com/ee/development/changelog.html) added, if necessary
- [ ] [Documentation created/updated](https://docs.gitlab.com/ee/development/doc_styleguide.html)
- [ ] API support added
- [ ] Tests added for this feature/bug
- Conform by the [code review guidelines](https://docs.gitlab.com/ee/development/code_review.html)
- [ ] Has been reviewed by a Backend maintainer
- [ ] Has been reviewed by a Database specialist
- [ ] Conform by the [merge request performance guides](https://docs.gitlab.com/ee/development/merge_request_performance_guidelines.html)
- [ ] Conform by the [style guides](https://gitlab.com/gitlab-org/gitlab-ee/blob/master/CONTRIBUTING.md#style-guides)
- [ ] [Documentation created/updated](https://docs.gitlab.com/ee/development/documentation/index.html#contributing-to-docs)
- [ ] [API support added](https://docs.gitlab.com/ee/development/api_styleguide.html)
- [ ] [Tests added for this feature/bug](https://docs.gitlab.com/ee/development/testing_guide/index.html)
- Conforms to the [code review guidelines](https://docs.gitlab.com/ee/development/code_review.html)
- [ ] Has been reviewed by a Backend [maintainer](https://about.gitlab.com/handbook/engineering/#maintainer)
- [ ] Has been reviewed by a Database [specialist](https://about.gitlab.com/team/structure/#specialist)
- [ ] Conforms to the [merge request performance guidelines](https://docs.gitlab.com/ee/development/merge_request_performance_guidelines.html)
- [ ] Conforms to the [style guides](https://gitlab.com/gitlab-org/gitlab-ee/blob/master/CONTRIBUTING.md#style-guides)
- [ ] If you have multiple commits, please combine them into a few logically organized commits by [squashing them](https://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits)
- [ ] Internationalization required/considered
- [ ] If paid feature, have we considered GitLab.com plan and how it works for groups and is there a design for promoting it to users who aren't on the correct plan
- [ ] End-to-end tests pass (`package-and-qa` manual pipeline job)
- [ ] [Internationalization required/considered](https://docs.gitlab.com/ee/development/i18n/index.html)
- [ ] For a paid feature, have we considered GitLab.com plans, how it works for groups, and is there a design for promoting it to users who aren't on the correct plan?
- [ ] [End-to-end tests](https://docs.gitlab.com/ee/development/testing_guide/end_to_end_tests.html#testing-code-in-merge-requests) pass (`package-and-qa` manual pipeline job)
/label ~database
<!--See the general Documentation guidelines https://docs.gitlab.com/ce/development/writing_documentation.html -->
<!--See the general Documentation guidelines https://docs.gitlab.com/ee/development/documentation/index.html -->
## What does this MR do?
......@@ -13,17 +13,17 @@ Closes
## Moving docs to a new location?
Read the guidelines:
https://docs.gitlab.com/ce/development/writing_documentation.html#changing-document-location
https://docs.gitlab.com/ee/development/documentation/#changing-document-location
- [ ] Make sure the old link is not removed and has its contents replaced with
a link to the new location.
- [ ] Make sure internal links pointing to the document in question are not broken.
- [ ] Search and replace any links referring to old docs in GitLab Rails app,
specifically under the `app/views/` and `ee/app/views` (for GitLab EE) directories.
- [ ] Make sure to add [`redirect_from`](https://docs.gitlab.com/ce/development/writing_documentation.html#redirections-for-pages-with-disqus-comments)
- [ ] Search and replace any links referring to the old docs in the GitLab Rails app,
specifically under the `app/views/` and `ee/app/views` (for GitLab EE) directories.
- [ ] Make sure to add [`redirect_from`](https://docs.gitlab.com/ee/development/documentation/index.html#redirections-for-pages-with-disqus-comments)
to the new document if there are any Disqus comments on the old document thread.
- [ ] If working on CE and the `ee-compat-check` jobs fails, submit an MR to EE
with the changes as well (https://docs.gitlab.com/ce/development/writing_documentation.html#cherry-picking-from-ce-to-ee).
- [ ] If working on CE and the `ee-compat-check` jobs fails, [submit an MR to EE
with the changes](https://docs.gitlab.com/ee/development/documentation/index.html#cherry-picking-from-ce-to-ee) as well.
- [ ] Ping one of the technical writers for review.
/label ~Documentation
......@@ -85,6 +85,9 @@ export default {
}
return __('Show latest version');
},
canCurrentUserFork() {
return this.currentUser.canFork === true && this.currentUser.canCreateMergeRequest;
},
},
watch: {
diffViewType() {
......@@ -192,7 +195,7 @@ export default {
v-for="file in diffFiles"
:key="file.newPath"
:file="file"
:current-user="currentUser"
:can-current-user-fork="canCurrentUserFork"
/>
</div>
<no-changes v-else />
......
......@@ -18,8 +18,8 @@ export default {
type: Object,
required: true,
},
currentUser: {
type: Object,
canCurrentUserFork: {
type: Boolean,
required: true,
},
},
......@@ -87,7 +87,7 @@ export default {
class="diff-file file-holder"
>
<diff-file-header
:current-user="currentUser"
:can-current-user-fork="canCurrentUserFork"
:diff-file="file"
:collapsible="true"
:expanded="!isCollapsed"
......
......@@ -39,8 +39,8 @@ export default {
required: false,
default: true,
},
currentUser: {
type: Object,
canCurrentUserFork: {
type: Boolean,
required: true,
},
},
......@@ -228,7 +228,7 @@ export default {
<edit-button
v-if="!diffFile.deletedFile"
:current-user="currentUser"
:can-current-user-fork="canCurrentUserFork"
:edit-path="diffFile.editPath"
:can-modify-blob="diffFile.canModifyBlob"
@showForkMessage="showForkMessage"
......
......@@ -13,12 +13,8 @@ export default {
noteForm,
},
props: {
diffFile: {
type: Object,
required: true,
},
diffLines: {
type: Array,
diffFileHash: {
type: String,
required: true,
},
line: {
......@@ -40,6 +36,7 @@ export default {
noteableData: state => state.notes.noteableData,
diffViewType: state => state.diffs.diffViewType,
}),
...mapGetters('diffs', ['getDiffFileByHash']),
...mapGetters(['isLoggedIn', 'noteableType', 'getNoteableData', 'getNotesDataByProp']),
},
mounted() {
......@@ -68,13 +65,14 @@ export default {
});
},
handleSaveNote(note) {
const selectedDiffFile = this.getDiffFileByHash(this.diffFileHash);
const postData = getNoteFormData({
note,
noteableData: this.noteableData,
noteableType: this.noteableType,
noteTargetLine: this.noteTargetLine,
diffViewType: this.diffViewType,
diffFile: this.diffFile,
diffFile: selectedDiffFile,
linePosition: this.position,
});
......
......@@ -24,8 +24,12 @@ export default {
type: Object,
required: true,
},
diffFile: {
type: Object,
fileHash: {
type: String,
required: true,
},
contextLinesPath: {
type: String,
required: true,
},
diffViewType: {
......@@ -120,14 +124,14 @@ export default {
:class="classNameMap"
>
<diff-line-gutter-content
:file-hash="diffFile.fileHash"
:file-hash="fileHash"
:context-lines-path="contextLinesPath"
:line-type="normalizedLine.type"
:line-code="normalizedLine.lineCode"
:line-position="linePosition"
:line-number="lineNumber"
:meta-data="normalizedLine.metaData"
:show-comment-button="showCommentButton"
:context-lines-path="diffFile.contextLinesPath"
:is-bottom="isBottom"
:is-match-line="isMatchLine"
:is-context-line="isContentLine"
......
......@@ -5,8 +5,8 @@ export default {
type: String,
required: true,
},
currentUser: {
type: Object,
canCurrentUserFork: {
type: Boolean,
required: true,
},
canModifyBlob: {
......@@ -17,12 +17,12 @@ export default {
},
methods: {
handleEditClick(evt) {
if (!this.currentUser || this.canModifyBlob) {
if (!this.canCurrentUserFork || this.canModifyBlob) {
// if we can Edit, do default Edit button behavior
return;
}
if (this.currentUser.canFork && this.currentUser.canCreateMergeRequest) {
if (this.canCurrentUserFork) {
evt.preventDefault();
this.$emit('showForkMessage');
}
......
......@@ -13,12 +13,8 @@ export default {
type: Object,
required: true,
},
diffFile: {
type: Object,
required: true,
},
diffLines: {
type: Array,
diffFileHash: {
type: String,
required: true,
},
lineIndex: {
......@@ -58,10 +54,9 @@ export default {
/>
<diff-line-note-form
v-if="diffLineCommentForms[line.lineCode]"
:diff-file="diffFile"
:diff-lines="diffLines"
:diff-file-hash="diffFileHash"
:line="line"
:note-target-line="diffLines[lineIndex]"
:note-target-line="line"
/>
</div>
</td>
......
......@@ -16,8 +16,12 @@ export default {
DiffTableCell,
},
props: {
diffFile: {
type: Object,
fileHash: {
type: String,
required: true,
},
contextLinesPath: {
type: String,
required: true,
},
line: {
......@@ -50,7 +54,7 @@ export default {
inlineRowId() {
const { lineCode, oldLine, newLine } = this.line;
return lineCode || `${this.diffFile.fileHash}_${oldLine}_${newLine}`;
return lineCode || `${this.fileHash}_${oldLine}_${newLine}`;
},
},
created() {
......@@ -78,7 +82,8 @@ export default {
@mouseout="handleMouseMove"
>
<diff-table-cell
:diff-file="diffFile"
:file-hash="fileHash"
:context-lines-path="contextLinesPath"
:line="line"
:line-type="oldLineType"
:is-bottom="isBottom"
......@@ -87,7 +92,8 @@ export default {
class="diff-line-num old_line"
/>
<diff-table-cell
:diff-file="diffFile"
:file-hash="fileHash"
:context-lines-path="contextLinesPath"
:line="line"
:line-type="newLineType"
:is-bottom="isBottom"
......
......@@ -60,15 +60,15 @@ export default {
v-for="(line, index) in normalizedDiffLines"
>
<inline-diff-table-row
:diff-file="diffFile"
:file-hash="diffFile.fileHash"
:context-lines-path="diffFile.contextLinesPath"
:line="line"
:is-bottom="index + 1 === diffLinesLength"
:key="line.lineCode"
/>
<inline-diff-comment-row
v-if="shouldRenderCommentRow(line)"
:diff-file="diffFile"
:diff-lines="normalizedDiffLines"
:diff-file-hash="diffFile.fileHash"
:line="line"
:line-index="index"
:key="index"
......
......@@ -13,12 +13,8 @@ export default {
type: Object,
required: true,
},
diffFile: {
type: Object,
required: true,
},
diffLines: {
type: Array,
diffFileHash: {
type: String,
required: true,
},
lineIndex: {
......@@ -91,10 +87,9 @@ export default {
<diff-line-note-form
v-if="diffLineCommentForms[leftLineCode] &&
diffLineCommentForms[leftLineCode]"
:diff-file="diffFile"
:diff-lines="diffLines"
:diff-file-hash="diffFileHash"
:line="line.left"
:note-target-line="diffLines[lineIndex].left"
:note-target-line="line.left"
position="left"
/>
</td>
......@@ -112,10 +107,9 @@ export default {
<diff-line-note-form
v-if="diffLineCommentForms[rightLineCode] &&
diffLineCommentForms[rightLineCode] && line.right.type"
:diff-file="diffFile"
:diff-lines="diffLines"
:diff-file-hash="diffFileHash"
:line="line.right"
:note-target-line="diffLines[lineIndex].right"
:note-target-line="line.right"
position="right"
/>
</td>
......
......@@ -19,8 +19,12 @@ export default {
DiffTableCell,
},
props: {
diffFile: {
type: Object,
fileHash: {
type: String,
required: true,
},
contextLinesPath: {
type: String,
required: true,
},
line: {
......@@ -103,7 +107,8 @@ export default {
@mouseout="handleMouseMove"
>
<diff-table-cell
:diff-file="diffFile"
:file-hash="fileHash"
:context-lines-path="contextLinesPath"
:line="line"
:line-type="oldLineType"
:line-position="linePositionLeft"
......@@ -123,7 +128,8 @@ export default {
>
</td>
<diff-table-cell
:diff-file="diffFile"
:file-hash="fileHash"
:context-lines-path="contextLinesPath"
:line="line"
:line-type="newLineType"
:line-position="linePositionRight"
......
......@@ -93,17 +93,17 @@ export default {
v-for="(line, index) in parallelDiffLines"
>
<parallel-diff-table-row
:diff-file="diffFile"
:file-hash="diffFile.fileHash"
:context-lines-path="diffFile.contextLinesPath"
:line="line"
:is-bottom="index + 1 === diffLinesLength"
:key="index"
/>
<parallel-diff-comment-row
v-if="shouldRenderCommentRow(line)"
:key="line.left.lineCode || line.right.lineCode"
:key="`dcr-${index}`"
:line="line"
:diff-file="diffFile"
:diff-lines="parallelDiffLines"
:diff-file-hash="diffFile.fileHash"
:line-index="index"
/>
</template>
......
......@@ -57,4 +57,8 @@ export const getDiffFileDiscussions = (state, getters, rootState, rootGetters) =
) || [];
// prevent babel-plugin-rewire from generating an invalid default during karma∂ tests
export const getDiffFileByHash = state => fileHash =>
state.diffFiles.find(file => file.fileHash === fileHash);
// prevent babel-plugin-rewire from generating an invalid default during karma tests
export default () => {};
......@@ -38,6 +38,7 @@ export default {
<button
:aria-label="label"
type="button"
class="btn-blank"
@click.stop.prevent="clicked"
>
<icon
......
<script>
import { mapState, mapActions } from 'vuex';
import imageDiffHelper from '~/image_diff/helpers/index';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import DiffFileHeader from '~/diffs/components/diff_file_header.vue';
import SkeletonLoadingContainer from '~/vue_shared/components/skeleton_loading_container.vue';
import { trimFirstCharOfLineContent } from '~/diffs/store/utils';
import { mapState, mapActions } from 'vuex';
import imageDiffHelper from '~/image_diff/helpers/index';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import DiffFileHeader from '~/diffs/components/diff_file_header.vue';
import SkeletonLoadingContainer from '~/vue_shared/components/skeleton_loading_container.vue';
import { trimFirstCharOfLineContent } from '~/diffs/store/utils';
export default {
components: {
DiffFileHeader,
SkeletonLoadingContainer,
export default {
components: {
DiffFileHeader,
SkeletonLoadingContainer,
},
props: {
discussion: {
type: Object,
required: true,
},
props: {
discussion: {
type: Object,
required: true,
},
},
data() {
return {
error: false,
};
},
computed: {
...mapState({
noteableData: state => state.notes.noteableData,
}),
hasTruncatedDiffLines() {
return this.discussion.truncatedDiffLines && this.discussion.truncatedDiffLines.length !== 0;
},
data() {
return {
error: false,
};
isDiscussionsExpanded() {
return true; // TODO: @fatihacet - Fix this.
},
computed: {
...mapState({
noteableData: state => state.notes.noteableData,
}),
hasTruncatedDiffLines() {
return this.discussion.truncatedDiffLines &&
this.discussion.truncatedDiffLines.length !== 0;
},
isDiscussionsExpanded() {
return true; // TODO: @fatihacet - Fix this.
},
isCollapsed() {
return this.diffFile.collapsed || false;
},
isImageDiff() {
return !this.diffFile.text;
},
diffFileClass() {
const { text } = this.diffFile;
return text ? 'text-file' : 'js-image-file';
},
diffFile() {
return convertObjectPropsToCamelCase(this.discussion.diffFile, { deep: true });
},
imageDiffHtml() {
return this.discussion.imageDiffHtml;
},
currentUser() {
return this.noteableData.current_user;
},
userColorScheme() {
return window.gon.user_color_scheme;
},
normalizedDiffLines() {
if (this.discussion.truncatedDiffLines) {
return this.discussion.truncatedDiffLines.map(line =>
trimFirstCharOfLineContent(convertObjectPropsToCamelCase(line)),
);
}
return [];
},
isCollapsed() {
return this.diffFile.collapsed || false;
},
isImageDiff() {
return !this.diffFile.text;
},
diffFileClass() {
const { text } = this.diffFile;
return text ? 'text-file' : 'js-image-file';
},
diffFile() {
return convertObjectPropsToCamelCase(this.discussion.diffFile, { deep: true });
},
mounted() {
if (this.isImageDiff) {
const canCreateNote = false;
const renderCommentBadge = true;
imageDiffHelper.initImageDiff(this.$refs.fileHolder, canCreateNote, renderCommentBadge);
} else if (!this.hasTruncatedDiffLines) {
this.fetchDiff();
imageDiffHtml() {
return this.discussion.imageDiffHtml;
},
userColorScheme() {
return window.gon.user_color_scheme;
},
normalizedDiffLines() {
if (this.discussion.truncatedDiffLines) {
return this.discussion.truncatedDiffLines.map(line =>
trimFirstCharOfLineContent(convertObjectPropsToCamelCase(line)),
);
}
return [];
},
},
mounted() {
if (this.isImageDiff) {
const canCreateNote = false;
const renderCommentBadge = true;
imageDiffHelper.initImageDiff(this.$refs.fileHolder, canCreateNote, renderCommentBadge);
} else if (!this.hasTruncatedDiffLines) {
this.fetchDiff();
}
},
methods: {
...mapActions(['fetchDiscussionDiffLines']),
rowTag(html) {
return html.outerHTML ? 'tr' : 'template';
},
methods: {
...mapActions(['fetchDiscussionDiffLines']),
rowTag(html) {
return html.outerHTML ? 'tr' : 'template';
},
fetchDiff() {
this.error = false;
this.fetchDiscussionDiffLines(this.discussion)
.then(this.highlight)
.catch(() => {
this.error = true;
});
},
fetchDiff() {
this.error = false;
this.fetchDiscussionDiffLines(this.discussion)
.then(this.highlight)
.catch(() => {
this.error = true;
});
},
};
},
};
</script>
<template>
......@@ -99,7 +95,7 @@
>
<diff-file-header
:diff-file="diffFile"
:current-user="currentUser"
:can-current-user-fork="false"
:discussions-expanded="isDiscussionsExpanded"
:expanded="!isCollapsed"
/>
......
......@@ -175,6 +175,7 @@ export default {
<span
:aria-label="stage.title"
aria-hidden="true"
class="no-pointer-events"
>
<icon :name="borderlessIcon" />
</span>
......
......@@ -126,7 +126,7 @@ export default {
:cx="dotX"
:cy="dotY"
r="1.5"
tranform="translate(0 -1)"
transform="translate(0 -1)"
/>
</svg>
</div>
......
......@@ -110,7 +110,7 @@ code {
padding: 2px 4px;
color: $red-600;
background-color: $red-100;
border-radius: 3px;
border-radius: $border-radius-default;
.code > & {
background-color: inherit;
......@@ -128,7 +128,8 @@ table {
border-spacing: 0;
}
.tooltip {
.tooltip,
.no-pointer-events {
// Fix bootstrap4 bug whereby tooltips flicker when they are hovered over their borders
pointer-events: none;
}
......
......@@ -9,12 +9,8 @@
.gfm-project_member {
padding: 0 2px;
border-radius: #{$border-radius-default / 2};
background-color: $user-mention-bg;
&:hover {
background-color: $user-mention-bg-hover;
}
background-color: $blue-100;
border-radius: $border-radius-default;
}
.gfm-color_chip {
......
......@@ -551,6 +551,7 @@
@include media-breakpoint-up(lg) {
.branch-actions {
align-self: center;
margin-left: $gl-padding;
}
}
}
......
......@@ -116,7 +116,12 @@ class Projects::WikisController < Projects::ApplicationController
# Call #wiki to make sure the Wiki Repo is initialized
@project_wiki.wiki
@sidebar_wiki_entries = WikiPage.group_by_directory(@project_wiki.pages(limit: 15))
@sidebar_page = @project_wiki.find_sidebar(params[:version_id])
unless @sidebar_page # Fallback to default sidebar
@sidebar_wiki_entries = WikiPage.group_by_directory(@project_wiki.pages(limit: 15))
end
rescue ProjectWiki::CouldNotCreateWikiError
flash[:notice] = "Could not create Wiki Repository at this time. Please try again later."
redirect_to project_path(@project)
......
......@@ -16,6 +16,7 @@
# personal: boolean
# search: string
# non_archived: boolean
# archived: 'only' or boolean
#
class ProjectsFinder < UnionFinder
include CustomAttributesFilter
......@@ -130,7 +131,7 @@ class ProjectsFinder < UnionFinder
def by_archived(projects)
if params[:non_archived]
projects.non_archived
elsif params.key?(:archived) # Back-compatibility with the places where `params[:archived]` can be set explicitly to `false`
elsif params.key?(:archived)
if params[:archived] == 'only'
projects.archived
elsif Gitlab::Utils.to_boolean(params[:archived])
......
......@@ -413,20 +413,6 @@ module ProjectsHelper
@ref || @repository.try(:root_ref)
end
# Gitaly migration: https://gitlab.com/gitlab-org/gitaly/issues/1235
def sanitize_repo_path(project, message)
return '' unless message.present?
exports_path = File.join(Settings.shared['path'], 'tmp/project_exports')
filtered_message = message.strip.gsub(exports_path, "[REPO EXPORT PATH]")
disk_path = Gitlab::GitalyClient::StorageSettings.allow_disk_access do
Gitlab.config.repositories.storages[project.repository_storage].legacy_disk_path
end
filtered_message.gsub(disk_path.chomp('/'), "[REPOS PATH]")
end
def project_child_container_class(view_path)
view_path == "projects/issues/issues" ? "prepend-top-default" : "project-show-#{view_path}"
end
......
......@@ -8,7 +8,7 @@ module SubmoduleHelper
url = repository.submodule_url_for(ref, submodule_item.path)
if url == '.' || url == './'
url = File.join(Gitlab.config.gitlab.url, @project.full_path)
url = File.join(Gitlab.config.gitlab.url, repository.project.full_path)
end
if url =~ %r{([^/:]+)/([^/]+(?:\.git)?)\Z}
......@@ -31,7 +31,7 @@ module SubmoduleHelper
[namespace_project_path(namespace, project),
namespace_project_tree_path(namespace, project, submodule_item.id)]
elsif relative_self_url?(url)
relative_self_links(url, submodule_item.id)
relative_self_links(url, submodule_item.id, repository.project)
elsif github_dot_com_url?(url)
standard_links('github.com', namespace, project, submodule_item.id)
elsif gitlab_dot_com_url?(url)
......@@ -73,7 +73,7 @@ module SubmoduleHelper
[base, [base, '/tree/', commit].join('')]
end
def relative_self_links(url, commit)
def relative_self_links(url, commit, project)
url.rstrip!
# Map relative links to a namespace and project
# For example:
......@@ -85,7 +85,7 @@ module SubmoduleHelper
namespace = components.pop.gsub(/^\.\.$/, '')
if namespace.empty?
namespace = @project.namespace.full_path
namespace = project.namespace.full_path
end
begin
......
......@@ -92,10 +92,6 @@ class Deployment < ActiveRecord::Base
@stop_action ||= manual_actions.find_by(name: on_stop)
end
def stop_action?
stop_action.present?
end
def formatted_deployment_time
created_at.to_time.in_time_zone.to_s(:medium)
end
......
......@@ -117,7 +117,7 @@ class Environment < ActiveRecord::Base
external_url.gsub(%r{\A.*?://}, '')
end
def stop_action?
def stop_action_available?
available? && stop_action.present?
end
......
......@@ -202,7 +202,7 @@ class Note < ActiveRecord::Base
end
def hook_attrs
attributes
Gitlab::HookData::NoteBuilder.new(self).build
end
def for_commit?
......
......@@ -2173,10 +2173,13 @@ class Project < ActiveRecord::Base
merge_requests = source_of_merge_requests.opened
.where(allow_collaboration: true)
if branch_name
merge_requests.find_by(source_branch: branch_name)&.can_be_merged_by?(user)
else
merge_requests.any? { |merge_request| merge_request.can_be_merged_by?(user) }
# Issue for N+1: https://gitlab.com/gitlab-org/gitlab-ce/issues/49322
Gitlab::GitalyClient.allow_n_plus_1_calls do
if branch_name
merge_requests.find_by(source_branch: branch_name)&.can_be_merged_by?(user)
else
merge_requests.any? { |merge_request| merge_request.can_be_merged_by?(user) }
end
end
end
......
# frozen_string_literal: true
class ProjectWiki
include Gitlab::ShellAdapter
include Storage::LegacyProjectWiki
......@@ -9,6 +11,7 @@ class ProjectWiki
}.freeze unless defined?(MARKUPS)
CouldNotCreateWikiError = Class.new(StandardError)
SIDEBAR = '_sidebar'
# Returns a string describing what went wrong after
# an operation fails.
......@@ -98,6 +101,10 @@ class ProjectWiki
end
end
def find_sidebar(version = nil)
find_page(SIDEBAR, version)
end
def find_file(name, version = nil)
wiki.file(name, version)
end
......
......@@ -60,7 +60,7 @@ class WikiPage
attr_accessor :attributes
def hook_attrs
attributes
Gitlab::HookData::WikiPageBuilder.new(self).build
end
def initialize(wiki, page = nil, persisted = false)
......
......@@ -2,11 +2,12 @@ class EnvironmentPolicy < BasePolicy
delegate { @subject.project }
condition(:stop_with_deployment_allowed) do
@subject.stop_action? && can?(:create_deployment) && can?(:update_build, @subject.stop_action)
@subject.stop_action_available? &&
can?(:create_deployment) && can?(:update_build, @subject.stop_action)
end
condition(:stop_with_update_allowed) do
!@subject.stop_action? && can?(:update_environment, @subject)
!@subject.stop_action_available? && can?(:update_environment, @subject)
end
rule { stop_with_deployment_allowed | stop_with_update_allowed }.enable :stop_environment
......
......@@ -7,7 +7,7 @@ class EnvironmentEntity < Grape::Entity
expose :external_url
expose :environment_type
expose :last_deployment, using: DeploymentEntity
expose :stop_action?, as: :has_stop_action
expose :stop_action_available?, as: :has_stop_action
expose :metrics_path, if: -> (environment, _) { environment.has_metrics? } do |environment|
metrics_project_environment_path(environment.project, environment)
......
# frozen_string_literal: true
class AccessTokenValidationService
# Results:
VALID = :valid
......
# frozen_string_literal: true
##
# Branch can be deleted either by DeleteBranchService
# or by GitPushService.
......
# frozen_string_literal: true
class AkismetService
attr_accessor :owner, :text, :options
......
# frozen_string_literal: true
module ApplicationSettings
class BaseService < ::BaseService
def initialize(application_setting, user, params = {})
......
# frozen_string_literal: true
module ApplicationSettings
class UpdateService < ApplicationSettings::BaseService
attr_reader :params, :application_setting
......
# frozen_string_literal: true
module Applications
class CreateService
def initialize(current_user, params)
......
# frozen_string_literal: true
class AuditEventService
def initialize(author, entity, details = {})
@author, @entity, @details = author, entity, details
......
# frozen_string_literal: true
module Auth
class ContainerRegistryAuthenticationService < BaseService
AUDIENCE = 'container_registry'.freeze
......
# frozen_string_literal: true
module Badges
class BaseService
protected
......
# frozen_string_literal: true
module Badges
class BuildService < Badges::BaseService
# returns the created badge
......
# frozen_string_literal: true
module Badges
class CreateService < Badges::BaseService
# returns the created badge
......
# frozen_string_literal: true
module Badges
class UpdateService < Badges::BaseService
# returns the updated badge
......
# frozen_string_literal: true
# Base class for services that count a single resource such as the number of
# issues for a project.
class BaseCountService
......
# frozen_string_literal: true
class BaseRenderer
attr_reader :current_user
......
# frozen_string_literal: true
class BaseService
include Gitlab::Allowable
......
# frozen_string_literal: true
module Boards
class BaseService < ::BaseService
# Parent can either a group or a project
......
# frozen_string_literal: true
module Boards
class CreateService < Boards::BaseService
def execute
......
# frozen_string_literal: true
module Boards
module Issues
class CreateService < Boards::BaseService
......
# frozen_string_literal: true
module Boards
module Issues
class ListService < Boards::BaseService
......
# frozen_string_literal: true
module Boards
module Issues
class MoveService < Boards::BaseService
......
# frozen_string_literal: true
module Boards
class ListService < Boards::BaseService
def execute
......
# frozen_string_literal: true
module Boards
module Lists
class CreateService < Boards::BaseService
......
# frozen_string_literal: true
module Boards
module Lists
class DestroyService < Boards::BaseService
......
# frozen_string_literal: true
module Boards
module Lists
class GenerateService < Boards::BaseService
......
# frozen_string_literal: true
module Boards
module Lists
class ListService < Boards::BaseService
......
# frozen_string_literal: true
module Boards
module Lists
class MoveService < Boards::BaseService
......
# frozen_string_literal: true
module ChatNames
class AuthorizeUserService
include Gitlab::Routing
......
# frozen_string_literal: true
module ChatNames
class FindUserService
def initialize(service, params)
......
# frozen_string_literal: true
module Ci
class CreatePipelineScheduleService < BaseService
def execute
......
# frozen_string_literal: true
module Ci
class CreatePipelineService < BaseService
attr_reader :pipeline
......
# frozen_string_literal: true
module Ci
##
# We call this service everytime we persist a CI/CD job.
......
# frozen_string_literal: true
module Ci
class ExtractSectionsFromBuildTraceService < BaseService
def execute(build)
......
# frozen_string_literal: true
##
# TODO:
# Almost components in this class were copied from app/models/project_services/kubernetes_service.rb
......
# frozen_string_literal: true
module Ci
class PipelineTriggerService < BaseService
include Gitlab::Utils::StrongMemoize
......
# frozen_string_literal: true
module Ci
class PlayBuildService < ::BaseService
def execute(build)
......
# frozen_string_literal: true
module Ci
class ProcessPipelineService < BaseService
attr_reader :pipeline
......
# frozen_string_literal: true
module Ci
# This class responsible for assigning
# proper pending build to runner on runner API request
......
# frozen_string_literal: true
module Ci
class RetryBuildService < ::BaseService
CLONE_ACCESSORS = %i[pipeline project ref tag options commands name
......
# frozen_string_literal: true
module Ci
class RetryPipelineService < ::BaseService
include Gitlab::OptimisticLocking
......
# frozen_string_literal: true
module Ci
class StopEnvironmentsService < BaseService
attr_reader :ref
......@@ -8,7 +10,7 @@ module Ci
return unless @ref.present?
environments.each do |environment|
next unless environment.stop_action?
next unless environment.stop_action_available?
next unless can?(current_user, :stop_environment, environment)
environment.stop_with_action!(current_user)
......
# frozen_string_literal: true
module Ci
class UpdateBuildQueueService
def execute(build)
......
# frozen_string_literal: true
module Ci
class UpdateRunnerService
attr_reader :runner
......
# frozen_string_literal: true
module Clusters
module Applications
class BaseHelmService
......
# frozen_string_literal: true
module Clusters
module Applications
class CheckIngressIpAddressService < BaseHelmService
......
# frozen_string_literal: true
module Clusters
module Applications
class CheckInstallationProgressService < BaseHelmService
......
# frozen_string_literal: true
module Clusters
module Applications
class InstallService < BaseHelmService
......
# frozen_string_literal: true
module Clusters
module Applications
class ScheduleInstallationService < ::BaseService
......
# frozen_string_literal: true
module Clusters
class CreateService < BaseService
attr_reader :access_token
......
# frozen_string_literal: true
module Clusters
module Gcp
class FetchOperationService
......
# frozen_string_literal: true
module Clusters
module Gcp
class FinalizeCreationService
......
# frozen_string_literal: true
module Clusters
module Gcp
class ProvisionService
......
# frozen_string_literal: true
module Clusters
module Gcp
class VerifyProvisionStatusService
......
# frozen_string_literal: true
module Clusters
class UpdateService < BaseService
def execute(cluster)
......
# frozen_string_literal: true
class CohortsService
MONTHS_INCLUDED = 12
......
# frozen_string_literal: true
module Commits
class ChangeService < Commits::CreateService
def initialize(*args)
......
# frozen_string_literal: true
module Commits
class CherryPickService < ChangeService
def create_commit!
......
# frozen_string_literal: true
module Commits
class CreateService < ::BaseService
ValidationError = Class.new(StandardError)
......
# frozen_string_literal: true
module Commits
class RevertService < ChangeService
def create_commit!
......
# frozen_string_literal: true
require 'securerandom'
# Compare 2 refs for one repo or between repositories
......
# frozen_string_literal: true
#
# Concern that helps with getting an exclusive lease for running a block
# of code.
......
# frozen_string_literal: true
module Issues
module ResolveDiscussions
include Gitlab::Utils::StrongMemoize
......
# frozen_string_literal: true
module UpdateVisibilityLevel
def valid_visibility_level_change?(target, new_visibility)
# check that user is allowed to set specified visibility_level
......
# frozen_string_literal: true
module Users
module NewUserNotifier
def notify_new_user(user, reset_token)
......
# frozen_string_literal: true
module Users
module ParticipableService
extend ActiveSupport::Concern
......
# frozen_string_literal: true
class CreateBranchService < BaseService
def execute(branch_name, ref)
create_master_branch if project.empty_repo?
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment