diff options
author | Filipa Lacerda <filipa@gitlab.com> | 2018-08-10 13:57:24 +0100 |
---|---|---|
committer | Filipa Lacerda <filipa@gitlab.com> | 2018-08-10 13:57:24 +0100 |
commit | ab44f531995d272e0a85d16a683e92c2e1c2f656 (patch) | |
tree | 8a4440cf3a07dcceeb878b1ed6ad36e23a319afe /app | |
parent | b4f9379e319d7a19af7f141b529a2fa6bdab04bf (diff) | |
parent | 91795dcd1c0d12d2350e0d00489d89be9fa29b32 (diff) | |
download | gitlab-ce-ab44f531995d272e0a85d16a683e92c2e1c2f656.tar.gz |
Merge branch 'master' into 25990-web-terminal-improvements
* master: (66 commits)
Allows to cancel a Created job
Enable frozen string in rest of app/models/**/*.rb
docs: removed duplicate `git_ssh_url` field from build event example
Bump pry to 0.11.3; pry-byebug to 3.4.3
Update GitLab Shell to v8.1.1 to fix regressions
Rails5 fix specs duplicate key value violates unique constraint 'index_gpg_signatures_on_commit_sha'
Add mock data for spam logs
Disable danger in preparation branches
[ci-skip] add changelog
Add default avatar to group
Fix label item height when no desc
Fix docs linting
Fix missed port
Consistent padding but correct label-actions-list positioning and label-links margin
Phase 2: #47282 Improving Contributor On-Boarding Documentation
Fix label item height when no desc
Resolve "docs update api for usage with an array of hashes"
removed un-used commits for currentProject & currentBranchId
Allow the Web IDE to open empty merge requests
Add rubocop check for add_reference to require index.
...
Diffstat (limited to 'app')
88 files changed, 420 insertions, 143 deletions
diff --git a/app/assets/javascripts/ide/ide_router.js b/app/assets/javascripts/ide/ide_router.js index c6d7d218e81..82f6f981e7a 100644 --- a/app/assets/javascripts/ide/ide_router.js +++ b/app/assets/javascripts/ide/ide_router.js @@ -117,7 +117,7 @@ router.beforeEach((to, from, next) => { mergeRequestId: to.params.mrid, }) .then(mr => { - store.dispatch('updateActivityBarView', activityBarViews.review); + store.dispatch('setCurrentBranchId', mr.source_branch); store.dispatch('getBranchData', { projectId: fullProjectId, @@ -144,6 +144,10 @@ router.beforeEach((to, from, next) => { }), ) .then(mrChanges => { + if (mrChanges.changes.length) { + store.dispatch('updateActivityBarView', activityBarViews.review); + } + mrChanges.changes.forEach((change, ind) => { const changeTreeEntry = store.state.entries[change.new_path]; diff --git a/app/assets/javascripts/ide/stores/actions/file.js b/app/assets/javascripts/ide/stores/actions/file.js index 9e3f5da4676..c9795750d65 100644 --- a/app/assets/javascripts/ide/stores/actions/file.js +++ b/app/assets/javascripts/ide/stores/actions/file.js @@ -54,9 +54,6 @@ export const setFileActive = ({ commit, state, getters, dispatch }, path) => { commit(types.SET_FILE_ACTIVE, { path, active: true }); dispatch('scrollToTab'); - - commit(types.SET_CURRENT_PROJECT, file.projectId); - commit(types.SET_CURRENT_BRANCH, file.branchId); }; export const getFileData = ({ state, commit, dispatch }, { path, makeFileActive = true }) => { diff --git a/app/assets/javascripts/pages/projects/settings/repository/show/index.js b/app/assets/javascripts/pages/projects/settings/repository/show/index.js index ffc84dc106b..78cf5406e43 100644 --- a/app/assets/javascripts/pages/projects/settings/repository/show/index.js +++ b/app/assets/javascripts/pages/projects/settings/repository/show/index.js @@ -1,3 +1,9 @@ import initForm from '../form'; +import MirrorRepos from './mirror_repos'; -document.addEventListener('DOMContentLoaded', initForm); +document.addEventListener('DOMContentLoaded', () => { + initForm(); + + const mirrorReposContainer = document.querySelector('.js-mirror-settings'); + if (mirrorReposContainer) new MirrorRepos(mirrorReposContainer).init(); +}); diff --git a/app/assets/javascripts/pages/projects/settings/repository/show/mirror_repos.js b/app/assets/javascripts/pages/projects/settings/repository/show/mirror_repos.js new file mode 100644 index 00000000000..4c56af20cc3 --- /dev/null +++ b/app/assets/javascripts/pages/projects/settings/repository/show/mirror_repos.js @@ -0,0 +1,94 @@ +import $ from 'jquery'; +import _ from 'underscore'; +import { __ } from '~/locale'; +import Flash from '~/flash'; +import axios from '~/lib/utils/axios_utils'; + +export default class MirrorRepos { + constructor(container) { + this.$container = $(container); + this.$form = $('.js-mirror-form', this.$container); + this.$urlInput = $('.js-mirror-url', this.$form); + this.$protectedBranchesInput = $('.js-mirror-protected', this.$form); + this.$table = $('.js-mirrors-table-body', this.$container); + this.mirrorEndpoint = this.$form.data('projectMirrorEndpoint'); + } + + init() { + this.initMirrorPush(); + this.registerUpdateListeners(); + } + + initMirrorPush() { + this.$passwordGroup = $('.js-password-group', this.$container); + this.$password = $('.js-password', this.$passwordGroup); + this.$authMethod = $('.js-auth-method', this.$form); + + this.$authMethod.on('change', () => this.togglePassword()); + this.$password.on('input.updateUrl', () => this.debouncedUpdateUrl()); + } + + updateUrl() { + let val = this.$urlInput.val(); + + if (this.$password) { + const password = this.$password.val(); + if (password) val = val.replace('@', `:${password}@`); + } + + $('.js-mirror-url-hidden', this.$form).val(val); + } + + updateProtectedBranches() { + const val = this.$protectedBranchesInput.get(0).checked + ? this.$protectedBranchesInput.val() + : '0'; + $('.js-mirror-protected-hidden', this.$form).val(val); + } + + registerUpdateListeners() { + this.debouncedUpdateUrl = _.debounce(() => this.updateUrl(), 200); + this.$urlInput.on('input', () => this.debouncedUpdateUrl()); + this.$protectedBranchesInput.on('change', () => this.updateProtectedBranches()); + this.$table.on('click', '.js-delete-mirror', event => this.deleteMirror(event)); + } + + togglePassword() { + const isPassword = this.$authMethod.val() === 'password'; + + if (!isPassword) { + this.$password.val(''); + this.updateUrl(); + } + this.$passwordGroup.collapse(isPassword ? 'show' : 'hide'); + } + + deleteMirror(event, existingPayload) { + const $target = $(event.currentTarget); + let payload = existingPayload; + + if (!payload) { + payload = { + project: { + remote_mirrors_attributes: { + id: $target.data('mirrorId'), + enabled: 0, + }, + }, + }; + } + + return axios + .put(this.mirrorEndpoint, payload) + .then(() => this.removeRow($target)) + .catch(() => Flash(__('Failed to remove mirror.'))); + } + + /* eslint-disable class-methods-use-this */ + removeRow($target) { + const row = $target.closest('tr'); + $('.js-delete-mirror', row).tooltip('hide'); + row.remove(); + } + /* eslint-enable class-methods-use-this */ +} diff --git a/app/assets/javascripts/reports/components/grouped_test_reports_app.vue b/app/assets/javascripts/reports/components/grouped_test_reports_app.vue index 140475b4dfa..7b37f4e9a97 100644 --- a/app/assets/javascripts/reports/components/grouped_test_reports_app.vue +++ b/app/assets/javascripts/reports/components/grouped_test_reports_app.vue @@ -1,10 +1,10 @@ <script> import { mapActions, mapGetters, mapState } from 'vuex'; import { s__ } from '~/locale'; - import { componentNames } from '~/vue_shared/components/reports/issue_body'; - import ReportSection from '~/vue_shared/components/reports/report_section.vue'; - import SummaryRow from '~/vue_shared/components/reports/summary_row.vue'; - import IssuesList from '~/vue_shared/components/reports/issues_list.vue'; + import { componentNames } from './issue_body'; + import ReportSection from './report_section.vue'; + import SummaryRow from './summary_row.vue'; + import IssuesList from './issues_list.vue'; import Modal from './modal.vue'; import createStore from '../store'; import { summaryTextBuilder, reportTextBuilder, statusIcon } from '../store/utils'; diff --git a/app/assets/javascripts/vue_shared/components/reports/issue_body.js b/app/assets/javascripts/reports/components/issue_body.js index 54dfb7b16bf..8b5af263d50 100644 --- a/app/assets/javascripts/vue_shared/components/reports/issue_body.js +++ b/app/assets/javascripts/reports/components/issue_body.js @@ -1,4 +1,4 @@ -import TestIssueBody from '~/reports/components/test_issue_body.vue'; +import TestIssueBody from './test_issue_body.vue'; export const components = { TestIssueBody, diff --git a/app/assets/javascripts/vue_shared/components/reports/issue_status_icon.vue b/app/assets/javascripts/reports/components/issue_status_icon.vue index f8189117ac3..85811698a37 100644 --- a/app/assets/javascripts/vue_shared/components/reports/issue_status_icon.vue +++ b/app/assets/javascripts/reports/components/issue_status_icon.vue @@ -1,11 +1,10 @@ <script> import Icon from '~/vue_shared/components/icon.vue'; - import { STATUS_FAILED, STATUS_NEUTRAL, STATUS_SUCCESS, -} from '~/vue_shared/components/reports/constants'; +} from '../constants'; export default { name: 'IssueStatusIcon', diff --git a/app/assets/javascripts/vue_shared/components/reports/issues_list.vue b/app/assets/javascripts/reports/components/issues_list.vue index 2545e84f932..dbb8848d1fa 100644 --- a/app/assets/javascripts/vue_shared/components/reports/issues_list.vue +++ b/app/assets/javascripts/reports/components/issues_list.vue @@ -1,10 +1,10 @@ <script> -import IssuesBlock from '~/vue_shared/components/reports/report_issues.vue'; +import IssuesBlock from './report_issues.vue'; import { STATUS_SUCCESS, STATUS_FAILED, STATUS_NEUTRAL, -} from '~/vue_shared/components/reports/constants'; +} from '../constants'; /** * Renders block of issues diff --git a/app/assets/javascripts/vue_shared/components/reports/modal_open_name.vue b/app/assets/javascripts/reports/components/modal_open_name.vue index 4f81cee2a38..4f81cee2a38 100644 --- a/app/assets/javascripts/vue_shared/components/reports/modal_open_name.vue +++ b/app/assets/javascripts/reports/components/modal_open_name.vue diff --git a/app/assets/javascripts/vue_shared/components/reports/report_issues.vue b/app/assets/javascripts/reports/components/report_issues.vue index 1f13e555b31..884f55c8dec 100644 --- a/app/assets/javascripts/vue_shared/components/reports/report_issues.vue +++ b/app/assets/javascripts/reports/components/report_issues.vue @@ -1,6 +1,6 @@ <script> -import IssueStatusIcon from '~/vue_shared/components/reports/issue_status_icon.vue'; -import { components, componentNames } from '~/vue_shared/components/reports/issue_body'; +import IssueStatusIcon from './issue_status_icon.vue'; +import { components, componentNames } from './issue_body'; export default { name: 'ReportIssues', diff --git a/app/assets/javascripts/vue_shared/components/reports/report_link.vue b/app/assets/javascripts/reports/components/report_link.vue index 74d68f9f439..74d68f9f439 100644 --- a/app/assets/javascripts/vue_shared/components/reports/report_link.vue +++ b/app/assets/javascripts/reports/components/report_link.vue diff --git a/app/assets/javascripts/vue_shared/components/reports/report_section.vue b/app/assets/javascripts/reports/components/report_section.vue index a6dbf21092b..dc609d6f90e 100644 --- a/app/assets/javascripts/vue_shared/components/reports/report_section.vue +++ b/app/assets/javascripts/reports/components/report_section.vue @@ -1,8 +1,8 @@ <script> import { __ } from '~/locale'; import StatusIcon from '~/vue_merge_request_widget/components/mr_widget_status_icon.vue'; +import Popover from '~/vue_shared/components/help_popover.vue'; import IssuesList from './issues_list.vue'; -import Popover from '../help_popover.vue'; const LOADING = 'LOADING'; const ERROR = 'ERROR'; diff --git a/app/assets/javascripts/vue_shared/components/reports/summary_row.vue b/app/assets/javascripts/reports/components/summary_row.vue index 063beab58fc..4456d84c968 100644 --- a/app/assets/javascripts/vue_shared/components/reports/summary_row.vue +++ b/app/assets/javascripts/reports/components/summary_row.vue @@ -1,7 +1,7 @@ <script> import CiIcon from '~/vue_shared/components/ci_icon.vue'; import LoadingIcon from '~/vue_shared/components/loading_icon.vue'; -import Popover from '../help_popover.vue'; +import Popover from '~/vue_shared/components/help_popover.vue'; /** * Renders the summary row for each report diff --git a/app/assets/javascripts/reports/constants.js b/app/assets/javascripts/reports/constants.js index 807ecb1039e..c323dc543f3 100644 --- a/app/assets/javascripts/reports/constants.js +++ b/app/assets/javascripts/reports/constants.js @@ -11,6 +11,8 @@ export const SUCCESS = 'SUCCESS'; export const STATUS_FAILED = 'failed'; export const STATUS_SUCCESS = 'success'; +export const STATUS_NEUTRAL = 'neutral'; + export const ICON_WARNING = 'warning'; export const ICON_SUCCESS = 'success'; export const ICON_NOTFOUND = 'notfound'; diff --git a/app/assets/javascripts/vue_shared/components/reports/constants.js b/app/assets/javascripts/vue_shared/components/reports/constants.js deleted file mode 100644 index dbde648bfdb..00000000000 --- a/app/assets/javascripts/vue_shared/components/reports/constants.js +++ /dev/null @@ -1,3 +0,0 @@ -export const STATUS_FAILED = 'failed'; -export const STATUS_SUCCESS = 'success'; -export const STATUS_NEUTRAL = 'neutral'; diff --git a/app/assets/stylesheets/framework/avatar.scss b/app/assets/stylesheets/framework/avatar.scss index 369556dc24e..4c7c399a3ca 100644 --- a/app/assets/stylesheets/framework/avatar.scss +++ b/app/assets/stylesheets/framework/avatar.scss @@ -103,6 +103,7 @@ display: flex; a { + width: 100%; display: flex; } diff --git a/app/assets/stylesheets/framework/forms.scss b/app/assets/stylesheets/framework/forms.scss index d7149d93622..437fcff5c62 100644 --- a/app/assets/stylesheets/framework/forms.scss +++ b/app/assets/stylesheets/framework/forms.scss @@ -201,7 +201,7 @@ label { } .gl-show-field-errors { - .form-control { + .form-control:not(textarea) { height: 34px; } diff --git a/app/assets/stylesheets/pages/labels.scss b/app/assets/stylesheets/pages/labels.scss index 2b40404971c..b25dc4f419a 100644 --- a/app/assets/stylesheets/pages/labels.scss +++ b/app/assets/stylesheets/pages/labels.scss @@ -253,7 +253,7 @@ text-align: right; padding: 0; position: relative; - top: -3px; + margin: 0; } .label-badge { @@ -274,6 +274,7 @@ .label-links { list-style: none; + margin: 0; padding: 0; white-space: nowrap; } diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss index 944421604fe..6eaa0523387 100644 --- a/app/assets/stylesheets/pages/projects.scss +++ b/app/assets/stylesheets/pages/projects.scss @@ -823,10 +823,6 @@ pre.light-well { .avatar-container { align-self: flex-start; - - > a { - width: 100%; - } } .project-details { diff --git a/app/assets/stylesheets/pages/settings.scss b/app/assets/stylesheets/pages/settings.scss index 839ac5ba59b..fb03970f64f 100644 --- a/app/assets/stylesheets/pages/settings.scss +++ b/app/assets/stylesheets/pages/settings.scss @@ -301,3 +301,17 @@ margin-bottom: 0; } } + +.mirror-error-badge { + background-color: $error-bg; + border-radius: $border-radius-default; + color: $white-light; +} + +.push-pull-table { + margin-top: 1em; + + .mirror-action-buttons { + padding-right: 0; + } +} diff --git a/app/helpers/avatars_helper.rb b/app/helpers/avatars_helper.rb index d48dae8f06d..494f785e305 100644 --- a/app/helpers/avatars_helper.rb +++ b/app/helpers/avatars_helper.rb @@ -1,28 +1,10 @@ module AvatarsHelper def project_icon(project_id, options = {}) - project = - if project_id.respond_to?(:avatar_url) - project_id - else - Project.find_by_full_path(project_id) - end - - if project.avatar_url - image_tag project.avatar_url, options - else # generated icon - project_identicon(project, options) - end + source_icon(Project, project_id, options) end - def project_identicon(project, options = {}) - bg_key = (project.id % 7) + 1 - options[:class] ||= '' - options[:class] << ' identicon' - options[:class] << " bg#{bg_key}" - - content_tag(:div, class: options[:class]) do - project.name[0, 1].upcase - end + def group_icon(group_id, options = {}) + source_icon(Group, group_id, options) end # Takes both user and email and returns the avatar_icon by @@ -123,4 +105,32 @@ module AvatarsHelper mail_to(options[:user_email], avatar) end end + + private + + def source_icon(klass, source_id, options = {}) + source = + if source_id.respond_to?(:avatar_url) + source_id + else + klass.find_by_full_path(source_id) + end + + if source.avatar_url + image_tag source.avatar_url, options + else + source_identicon(source, options) + end + end + + def source_identicon(source, options = {}) + bg_key = (source.id % 7) + 1 + options[:class] ||= '' + options[:class] << ' identicon' + options[:class] << " bg#{bg_key}" + + content_tag(:div, class: options[:class].strip) do + source.name[0, 1].upcase + end + end end diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb index 3c5c8bbd71b..5b51d2f2425 100644 --- a/app/helpers/groups_helper.rb +++ b/app/helpers/groups_helper.rb @@ -33,11 +33,6 @@ module GroupsHelper .count end - def group_icon(group, options = {}) - img_path = group_icon_url(group, options) - image_tag img_path, options - end - def group_icon_url(group, options = {}) if group.is_a?(String) group = Group.find_by_full_path(group) diff --git a/app/helpers/mirror_helper.rb b/app/helpers/mirror_helper.rb new file mode 100644 index 00000000000..93ed22513ac --- /dev/null +++ b/app/helpers/mirror_helper.rb @@ -0,0 +1,5 @@ +module MirrorHelper + def mirrors_form_data_attributes + { project_mirror_endpoint: project_mirror_path(@project) } + end +end diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index 9292929be98..3c69677baf0 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -226,7 +226,7 @@ module Ci end def cancelable? - active? + active? || created? end def retryable? diff --git a/app/models/programming_language.rb b/app/models/programming_language.rb index 400d6c407a7..0e667dac21e 100644 --- a/app/models/programming_language.rb +++ b/app/models/programming_language.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ProgrammingLanguage < ActiveRecord::Base validates :name, presence: true validates :color, allow_blank: false, color: true diff --git a/app/models/project.rb b/app/models/project.rb index 36089995ed3..7735f23cb9e 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -470,6 +470,24 @@ class Project < ActiveRecord::Base }x end + def reference_postfix + '>' + end + + def reference_postfix_escaped + '>' + end + + # Pattern used to extract `namespace/project>` project references from text. + # '>' or its escaped form ('>') are checked for because '>' is sometimes escaped + # when the reference comes from an external source. + def markdown_reference_pattern + %r{ + #{reference_pattern} + (#{reference_postfix}|#{reference_postfix_escaped}) + }x + end + def trending joins('INNER JOIN trending_projects ON projects.id = trending_projects.project_id') .reorder('trending_projects.id ASC') @@ -908,6 +926,10 @@ class Project < ActiveRecord::Base end end + def to_reference_with_postfix + "#{to_reference(full: true)}#{self.class.reference_postfix}" + end + # `from` argument can be a Namespace or Project. def to_reference(from = nil, full: false) if full || cross_namespace_reference?(from) diff --git a/app/models/project_services/asana_service.rb b/app/models/project_services/asana_service.rb index 4f289e6e215..35c19049c04 100644 --- a/app/models/project_services/asana_service.rb +++ b/app/models/project_services/asana_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'asana' class AsanaService < Service diff --git a/app/models/project_services/assembla_service.rb b/app/models/project_services/assembla_service.rb index 4234b8044e5..60575e45a90 100644 --- a/app/models/project_services/assembla_service.rb +++ b/app/models/project_services/assembla_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AssemblaService < Service prop_accessor :token, :subdomain validates :token, presence: true, if: :activated? diff --git a/app/models/project_services/bamboo_service.rb b/app/models/project_services/bamboo_service.rb index edc5c00d9c4..d502423726c 100644 --- a/app/models/project_services/bamboo_service.rb +++ b/app/models/project_services/bamboo_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class BambooService < CiService include ReactiveService diff --git a/app/models/project_services/bugzilla_service.rb b/app/models/project_services/bugzilla_service.rb index e4e3a80976b..1a2bb6a171b 100644 --- a/app/models/project_services/bugzilla_service.rb +++ b/app/models/project_services/bugzilla_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class BugzillaService < IssueTrackerService validates :project_url, :issues_url, :new_issue_url, presence: true, public_url: true, if: :activated? diff --git a/app/models/project_services/buildkite_service.rb b/app/models/project_services/buildkite_service.rb index 35884c4560c..43edfde851c 100644 --- a/app/models/project_services/buildkite_service.rb +++ b/app/models/project_services/buildkite_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "addressable/uri" class BuildkiteService < CiService diff --git a/app/models/project_services/builds_email_service.rb b/app/models/project_services/builds_email_service.rb index 0c526b53d72..f2295a95b60 100644 --- a/app/models/project_services/builds_email_service.rb +++ b/app/models/project_services/builds_email_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # This class is to be removed with 9.1 # We should also by then remove BuildsEmailService from database class BuildsEmailService < Service diff --git a/app/models/project_services/campfire_service.rb b/app/models/project_services/campfire_service.rb index cb4af73807b..1d7877a1fb5 100644 --- a/app/models/project_services/campfire_service.rb +++ b/app/models/project_services/campfire_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CampfireService < Service prop_accessor :token, :subdomain, :room validates :token, presence: true, if: :activated? @@ -82,7 +84,7 @@ class CampfireService < Service before = push[:before] after = push[:after] - message = "" + message = [] message << "[#{project.full_name}] " message << "#{push[:user_name]} " @@ -95,6 +97,6 @@ class CampfireService < Service message << "#{project.web_url}/compare/#{before}...#{after}" end - message + message.join end end diff --git a/app/models/project_services/chat_message/base_message.rb b/app/models/project_services/chat_message/base_message.rb index f710fa85b5d..8c68ddc40f2 100644 --- a/app/models/project_services/chat_message/base_message.rb +++ b/app/models/project_services/chat_message/base_message.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'slack-notifier' module ChatMessage diff --git a/app/models/project_services/chat_message/issue_message.rb b/app/models/project_services/chat_message/issue_message.rb index 3273f41dbd2..0cdcfcf0237 100644 --- a/app/models/project_services/chat_message/issue_message.rb +++ b/app/models/project_services/chat_message/issue_message.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module ChatMessage class IssueMessage < BaseMessage attr_reader :title diff --git a/app/models/project_services/chat_message/merge_message.rb b/app/models/project_services/chat_message/merge_message.rb index f412b6833d9..58631e09538 100644 --- a/app/models/project_services/chat_message/merge_message.rb +++ b/app/models/project_services/chat_message/merge_message.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module ChatMessage class MergeMessage < BaseMessage attr_reader :merge_request_iid diff --git a/app/models/project_services/chat_message/note_message.rb b/app/models/project_services/chat_message/note_message.rb index 7f9486132e6..741474fb27b 100644 --- a/app/models/project_services/chat_message/note_message.rb +++ b/app/models/project_services/chat_message/note_message.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module ChatMessage class NoteMessage < BaseMessage attr_reader :note diff --git a/app/models/project_services/chat_message/pipeline_message.rb b/app/models/project_services/chat_message/pipeline_message.rb index 96fd23aede3..62aec4351db 100644 --- a/app/models/project_services/chat_message/pipeline_message.rb +++ b/app/models/project_services/chat_message/pipeline_message.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module ChatMessage class PipelineMessage < BaseMessage attr_reader :ref_type diff --git a/app/models/project_services/chat_message/push_message.rb b/app/models/project_services/chat_message/push_message.rb index 8d599c5f116..82be33a12a1 100644 --- a/app/models/project_services/chat_message/push_message.rb +++ b/app/models/project_services/chat_message/push_message.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module ChatMessage class PushMessage < BaseMessage attr_reader :after diff --git a/app/models/project_services/chat_message/wiki_page_message.rb b/app/models/project_services/chat_message/wiki_page_message.rb index d84b80f2de2..b605d289278 100644 --- a/app/models/project_services/chat_message/wiki_page_message.rb +++ b/app/models/project_services/chat_message/wiki_page_message.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module ChatMessage class WikiPageMessage < BaseMessage attr_reader :title diff --git a/app/models/project_services/chat_notification_service.rb b/app/models/project_services/chat_notification_service.rb index a60b4c7fd0d..c10ee07ccf4 100644 --- a/app/models/project_services/chat_notification_service.rb +++ b/app/models/project_services/chat_notification_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Base class for Chat notifications services # This class is not meant to be used directly, but only to inherit from. class ChatNotificationService < Service diff --git a/app/models/project_services/ci_service.rb b/app/models/project_services/ci_service.rb index 82979c8bd34..f0ef2d925ab 100644 --- a/app/models/project_services/ci_service.rb +++ b/app/models/project_services/ci_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Base class for CI services # List methods you need to implement to get your CI service # working with GitLab Merge Requests diff --git a/app/models/project_services/custom_issue_tracker_service.rb b/app/models/project_services/custom_issue_tracker_service.rb index 456c7f5cee2..b8f8072869c 100644 --- a/app/models/project_services/custom_issue_tracker_service.rb +++ b/app/models/project_services/custom_issue_tracker_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CustomIssueTrackerService < IssueTrackerService validates :project_url, :issues_url, :new_issue_url, presence: true, public_url: true, if: :activated? diff --git a/app/models/project_services/deployment_service.rb b/app/models/project_services/deployment_service.rb index 5b8320158fc..6dae4f3a4a6 100644 --- a/app/models/project_services/deployment_service.rb +++ b/app/models/project_services/deployment_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Base class for deployment services # # These services integrate with a deployment solution like Kubernetes/OpenShift, diff --git a/app/models/project_services/drone_ci_service.rb b/app/models/project_services/drone_ci_service.rb index ab4e46da89f..158ae0bf255 100644 --- a/app/models/project_services/drone_ci_service.rb +++ b/app/models/project_services/drone_ci_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class DroneCiService < CiService include ReactiveService diff --git a/app/models/project_services/emails_on_push_service.rb b/app/models/project_services/emails_on_push_service.rb index b604d860a87..fb73d430fb1 100644 --- a/app/models/project_services/emails_on_push_service.rb +++ b/app/models/project_services/emails_on_push_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class EmailsOnPushService < Service boolean_accessor :send_from_committer_email boolean_accessor :disable_diffs diff --git a/app/models/project_services/external_wiki_service.rb b/app/models/project_services/external_wiki_service.rb index a4b1ef09e93..d2835c6ac82 100644 --- a/app/models/project_services/external_wiki_service.rb +++ b/app/models/project_services/external_wiki_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ExternalWikiService < Service prop_accessor :external_wiki_url diff --git a/app/models/project_services/flowdock_service.rb b/app/models/project_services/flowdock_service.rb index da01ac1b7cf..2545df06f6b 100644 --- a/app/models/project_services/flowdock_service.rb +++ b/app/models/project_services/flowdock_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "flowdock-git-hook" # Flow dock depends on Grit to compute the number of commits between two given diff --git a/app/models/project_services/gemnasium_service.rb b/app/models/project_services/gemnasium_service.rb index 8a6b0ed1a5f..67a92c441b1 100644 --- a/app/models/project_services/gemnasium_service.rb +++ b/app/models/project_services/gemnasium_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "gemnasium/gitlab_service" class GemnasiumService < Service diff --git a/app/models/project_services/gitlab_issue_tracker_service.rb b/app/models/project_services/gitlab_issue_tracker_service.rb index 16e32a4139e..fa9abf58e62 100644 --- a/app/models/project_services/gitlab_issue_tracker_service.rb +++ b/app/models/project_services/gitlab_issue_tracker_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class GitlabIssueTrackerService < IssueTrackerService include Gitlab::Routing diff --git a/app/models/project_services/hangouts_chat_service.rb b/app/models/project_services/hangouts_chat_service.rb index a8512c5f57c..272cd0f4e47 100644 --- a/app/models/project_services/hangouts_chat_service.rb +++ b/app/models/project_services/hangouts_chat_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'hangouts_chat' class HangoutsChatService < ChatNotificationService diff --git a/app/models/project_services/hipchat_service.rb b/app/models/project_services/hipchat_service.rb index dce878e485f..66012f0da99 100644 --- a/app/models/project_services/hipchat_service.rb +++ b/app/models/project_services/hipchat_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class HipchatService < Service include ActionView::Helpers::SanitizeHelper @@ -108,7 +110,7 @@ class HipchatService < Service before = push[:before] after = push[:after] - message = "" + message = [] message << "#{push[:user_name]} " if Gitlab::Git.blank_ref?(before) @@ -132,7 +134,7 @@ class HipchatService < Service end end - message + message.join end def markdown(text, options = {}) @@ -165,11 +167,11 @@ class HipchatService < Service description = obj_attr[:description] issue_link = "<a href=\"#{issue_url}\">issue ##{issue_iid}</a>" - message = "#{user_name} #{state} #{issue_link} in #{project_link}: <b>#{title}</b>" + message = ["#{user_name} #{state} #{issue_link} in #{project_link}: <b>#{title}</b>"] message << "<pre>#{markdown(description)}</pre>" - message + message.join end def create_merge_request_message(data) @@ -184,12 +186,11 @@ class HipchatService < Service merge_request_url = "#{project_url}/merge_requests/#{merge_request_id}" merge_request_link = "<a href=\"#{merge_request_url}\">merge request !#{merge_request_id}</a>" - message = "#{user_name} #{state} #{merge_request_link} in " \ - "#{project_link}: <b>#{title}</b>" + message = ["#{user_name} #{state} #{merge_request_link} in " \ + "#{project_link}: <b>#{title}</b>"] message << "<pre>#{markdown(description)}</pre>" - - message + message.join end def format_title(title) @@ -235,12 +236,11 @@ class HipchatService < Service end subject_html = "<a href=\"#{note_url}\">#{subject_type} #{subject_desc}</a>" - message = "#{user_name} commented on #{subject_html} in #{project_link}: " + message = ["#{user_name} commented on #{subject_html} in #{project_link}: "] message << title message << "<pre>#{markdown(note, ref: commit_id)}</pre>" - - message + message.join end def create_pipeline_message(data) diff --git a/app/models/project_services/irker_service.rb b/app/models/project_services/irker_service.rb index 27bdf708c80..a783a314071 100644 --- a/app/models/project_services/irker_service.rb +++ b/app/models/project_services/irker_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'uri' class IrkerService < Service diff --git a/app/models/project_services/issue_tracker_service.rb b/app/models/project_services/issue_tracker_service.rb index df6dcd90985..c7520d766a8 100644 --- a/app/models/project_services/issue_tracker_service.rb +++ b/app/models/project_services/issue_tracker_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class IssueTrackerService < Service validate :one_issue_tracker, if: :activated?, on: :manual_change diff --git a/app/models/project_services/jira_service.rb b/app/models/project_services/jira_service.rb index 82d438d5378..cc98b3f5a41 100644 --- a/app/models/project_services/jira_service.rb +++ b/app/models/project_services/jira_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class JiraService < IssueTrackerService include Gitlab::Routing include ApplicationHelper diff --git a/app/models/project_services/kubernetes_service.rb b/app/models/project_services/kubernetes_service.rb index 722642f6da7..bda1f67b8ff 100644 --- a/app/models/project_services/kubernetes_service.rb +++ b/app/models/project_services/kubernetes_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + ## # NOTE: # We'll move this class to Clusters::Platforms::Kubernetes, which contains exactly the same logic. diff --git a/app/models/project_services/mattermost_service.rb b/app/models/project_services/mattermost_service.rb index 0362ed172c7..b8bc83b870e 100644 --- a/app/models/project_services/mattermost_service.rb +++ b/app/models/project_services/mattermost_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class MattermostService < ChatNotificationService def title 'Mattermost notifications' diff --git a/app/models/project_services/mattermost_slash_commands_service.rb b/app/models/project_services/mattermost_slash_commands_service.rb index 227d430083d..ca324f68d2d 100644 --- a/app/models/project_services/mattermost_slash_commands_service.rb +++ b/app/models/project_services/mattermost_slash_commands_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class MattermostSlashCommandsService < SlashCommandsService include TriggersHelper diff --git a/app/models/project_services/microsoft_teams_service.rb b/app/models/project_services/microsoft_teams_service.rb index 99500caec0e..5b0e5fed092 100644 --- a/app/models/project_services/microsoft_teams_service.rb +++ b/app/models/project_services/microsoft_teams_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class MicrosoftTeamsService < ChatNotificationService def title 'Microsoft Teams Notification' diff --git a/app/models/project_services/mock_ci_service.rb b/app/models/project_services/mock_ci_service.rb index b89dc07a73e..6883976f0c8 100644 --- a/app/models/project_services/mock_ci_service.rb +++ b/app/models/project_services/mock_ci_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # For an example companion mocking service, see https://gitlab.com/gitlab-org/gitlab-mock-ci-service class MockCiService < CiService ALLOWED_STATES = %w[failed canceled running pending success success_with_warnings skipped not_found].freeze diff --git a/app/models/project_services/mock_deployment_service.rb b/app/models/project_services/mock_deployment_service.rb index 59a3811ce5d..7ab1687f8ba 100644 --- a/app/models/project_services/mock_deployment_service.rb +++ b/app/models/project_services/mock_deployment_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class MockDeploymentService < DeploymentService def title 'Mock deployment' diff --git a/app/models/project_services/mock_monitoring_service.rb b/app/models/project_services/mock_monitoring_service.rb index ed0318c6b27..bcf8f1df5da 100644 --- a/app/models/project_services/mock_monitoring_service.rb +++ b/app/models/project_services/mock_monitoring_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class MockMonitoringService < MonitoringService def title 'Mock monitoring' diff --git a/app/models/project_services/monitoring_service.rb b/app/models/project_services/monitoring_service.rb index 9af68b4e821..1b530a8247b 100644 --- a/app/models/project_services/monitoring_service.rb +++ b/app/models/project_services/monitoring_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Base class for monitoring services # # These services integrate with a deployment solution like Prometheus diff --git a/app/models/project_services/packagist_service.rb b/app/models/project_services/packagist_service.rb index ba62a5b7ac0..003884bb7ac 100644 --- a/app/models/project_services/packagist_service.rb +++ b/app/models/project_services/packagist_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class PackagistService < Service prop_accessor :username, :token, :server diff --git a/app/models/project_services/pipelines_email_service.rb b/app/models/project_services/pipelines_email_service.rb index 4cf149ac044..6f39a5e6e83 100644 --- a/app/models/project_services/pipelines_email_service.rb +++ b/app/models/project_services/pipelines_email_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class PipelinesEmailService < Service prop_accessor :recipients boolean_accessor :notify_only_broken_pipelines diff --git a/app/models/project_services/pivotaltracker_service.rb b/app/models/project_services/pivotaltracker_service.rb index 3476e7d2283..617e502b639 100644 --- a/app/models/project_services/pivotaltracker_service.rb +++ b/app/models/project_services/pivotaltracker_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class PivotaltrackerService < Service API_ENDPOINT = 'https://www.pivotaltracker.com/services/v5/source_commits'.freeze diff --git a/app/models/project_services/prometheus_service.rb b/app/models/project_services/prometheus_service.rb index df4254e0523..509e5b6089b 100644 --- a/app/models/project_services/prometheus_service.rb +++ b/app/models/project_services/prometheus_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class PrometheusService < MonitoringService include PrometheusAdapter diff --git a/app/models/project_services/pushover_service.rb b/app/models/project_services/pushover_service.rb index 8777a44b72f..4e48c348b45 100644 --- a/app/models/project_services/pushover_service.rb +++ b/app/models/project_services/pushover_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class PushoverService < Service BASE_URI = 'https://api.pushover.net/1'.freeze @@ -79,7 +81,7 @@ class PushoverService < Service end if data[:total_commits_count] > 0 - message << "\nTotal commits count: #{data[:total_commits_count]}" + message = [message, "Total commits count: #{data[:total_commits_count]}"].join("\n") end pushover_data = { diff --git a/app/models/project_services/redmine_service.rb b/app/models/project_services/redmine_service.rb index 3721093a6d1..a80be4b06da 100644 --- a/app/models/project_services/redmine_service.rb +++ b/app/models/project_services/redmine_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class RedmineService < IssueTrackerService validates :project_url, :issues_url, :new_issue_url, presence: true, public_url: true, if: :activated? diff --git a/app/models/project_services/slack_service.rb b/app/models/project_services/slack_service.rb index 71da0af75f6..482808255f9 100644 --- a/app/models/project_services/slack_service.rb +++ b/app/models/project_services/slack_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class SlackService < ChatNotificationService def title 'Slack notifications' diff --git a/app/models/project_services/slack_slash_commands_service.rb b/app/models/project_services/slack_slash_commands_service.rb index 1c3892a3f75..6c82e088231 100644 --- a/app/models/project_services/slack_slash_commands_service.rb +++ b/app/models/project_services/slack_slash_commands_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class SlackSlashCommandsService < SlashCommandsService include TriggersHelper diff --git a/app/models/project_services/slash_commands_service.rb b/app/models/project_services/slash_commands_service.rb index 37ea45109ae..e3ab60adefd 100644 --- a/app/models/project_services/slash_commands_service.rb +++ b/app/models/project_services/slash_commands_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Base class for Chat services # This class is not meant to be used directly, but only to inherrit from. class SlashCommandsService < Service diff --git a/app/models/project_services/teamcity_service.rb b/app/models/project_services/teamcity_service.rb index 802678147cf..eeeff5e802a 100644 --- a/app/models/project_services/teamcity_service.rb +++ b/app/models/project_services/teamcity_service.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class TeamcityService < CiService include ReactiveService diff --git a/app/models/protected_branch/merge_access_level.rb b/app/models/protected_branch/merge_access_level.rb index e8d35ac326f..b0d5c64e931 100644 --- a/app/models/protected_branch/merge_access_level.rb +++ b/app/models/protected_branch/merge_access_level.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ProtectedBranch::MergeAccessLevel < ActiveRecord::Base include ProtectedBranchAccess end diff --git a/app/models/protected_branch/push_access_level.rb b/app/models/protected_branch/push_access_level.rb index 7a2e9e5ec5d..b2a88229853 100644 --- a/app/models/protected_branch/push_access_level.rb +++ b/app/models/protected_branch/push_access_level.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ProtectedBranch::PushAccessLevel < ActiveRecord::Base include ProtectedBranchAccess end diff --git a/app/models/protected_tag/create_access_level.rb b/app/models/protected_tag/create_access_level.rb index 6b6ab3d8279..b06e55fb5dd 100644 --- a/app/models/protected_tag/create_access_level.rb +++ b/app/models/protected_tag/create_access_level.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ProtectedTag::CreateAccessLevel < ActiveRecord::Base include ProtectedTagAccess diff --git a/app/models/repository_language.rb b/app/models/repository_language.rb index f467d4eafa3..b18142a2ac4 100644 --- a/app/models/repository_language.rb +++ b/app/models/repository_language.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class RepositoryLanguage < ActiveRecord::Base belongs_to :project belongs_to :programming_language diff --git a/app/models/site_statistic.rb b/app/models/site_statistic.rb index 9c9c3172fe6..daac1c57db9 100644 --- a/app/models/site_statistic.rb +++ b/app/models/site_statistic.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class SiteStatistic < ActiveRecord::Base # prevents the creation of multiple rows default_value_for :id, 1 diff --git a/app/models/storage/hashed_project.rb b/app/models/storage/hashed_project.rb index 26b4b78ac64..90710f73fd3 100644 --- a/app/models/storage/hashed_project.rb +++ b/app/models/storage/hashed_project.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Storage class HashedProject attr_accessor :project diff --git a/app/models/storage/legacy_project.rb b/app/models/storage/legacy_project.rb index 27cb388c702..9f6f19acb41 100644 --- a/app/models/storage/legacy_project.rb +++ b/app/models/storage/legacy_project.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Storage class LegacyProject attr_accessor :project diff --git a/app/serializers/project_mirror_serializer.rb b/app/serializers/project_mirror_serializer.rb new file mode 100644 index 00000000000..7e9ba592252 --- /dev/null +++ b/app/serializers/project_mirror_serializer.rb @@ -0,0 +1,3 @@ +class ProjectMirrorSerializer < BaseSerializer + entity ProjectMirrorEntity +end diff --git a/app/views/projects/forks/_fork_button.html.haml b/app/views/projects/forks/_fork_button.html.haml index 8a549d431ee..12cf40bb65f 100644 --- a/app/views/projects/forks/_fork_button.html.haml +++ b/app/views/projects/forks/_fork_button.html.haml @@ -5,7 +5,7 @@ .bordered-box.fork-thumbnail.text-center.prepend-left-default.append-right-default.prepend-top-default.append-bottom-default.forked = link_to project_path(forked_project) do - if /no_((\w*)_)*avatar/.match(avatar) - = project_identicon(namespace, class: "avatar s100 identicon") + = project_icon(namespace, class: "avatar s100 identicon") - else .avatar-container.s100 = image_tag(avatar, class: "avatar s100") @@ -18,7 +18,7 @@ class: ("disabled has-tooltip" unless can_create_project), title: (_('You have reached your project limit') unless can_create_project) do - if /no_((\w*)_)*avatar/.match(avatar) - = project_identicon(namespace, class: "avatar s100 identicon") + = project_icon(namespace, class: "avatar s100 identicon") - else .avatar-container.s100 = image_tag(avatar, class: "avatar s100") diff --git a/app/views/projects/mirrors/_instructions.html.haml b/app/views/projects/mirrors/_instructions.html.haml index 64f0fde30cf..3d811be3fe3 100644 --- a/app/views/projects/mirrors/_instructions.html.haml +++ b/app/views/projects/mirrors/_instructions.html.haml @@ -1,10 +1,11 @@ .account-well.prepend-top-default.append-bottom-default %ul %li - The repository must be accessible over <code>http://</code>, <code>https://</code>, <code>ssh://</code> or <code>git://</code>. - %li - Include the username in the URL if required: <code>https://username@gitlab.company.com/group/project.git</code>. - %li - The update action will time out after 10 minutes. For big repositories, use a clone/push combination. - %li - The Git LFS objects will <strong>not</strong> be synced. + = _('The repository must be accessible over <code>http://</code>, + <code>https://</code>, <code>ssh://</code> and <code>git://</code>.').html_safe + %li= _('Include the username in the URL if required: <code>https://username@gitlab.company.com/group/project.git</code>.').html_safe + %li= _('The update action will time out after 15 minutes. For big repositories, use a clone/push combination.') + %li= _('The Git LFS objects will <strong>not</strong> be synced.').html_safe + %li + = _('This user will be the author of all events in the activity feed that are the result of an update, + like new branches being created or new commits being pushed to existing branches.') diff --git a/app/views/projects/mirrors/_mirror_repos.html.haml b/app/views/projects/mirrors/_mirror_repos.html.haml new file mode 100644 index 00000000000..53387b3a50c --- /dev/null +++ b/app/views/projects/mirrors/_mirror_repos.html.haml @@ -0,0 +1,63 @@ +- expanded = Rails.env.test? +- protocols = Gitlab::UrlSanitizer::ALLOWED_SCHEMES.join('|') + +%section.settings.project-mirror-settings.js-mirror-settings.no-animate{ class: ('expanded' if expanded) } + .settings-header + %h4= _('Mirroring repositories') + %button.btn.js-settings-toggle + = expanded ? _('Collapse') : _('Expand') + %p + = _('Set up your project to automatically push and/or pull changes to/from another repository. Branches, tags, and commits will be synced automatically.') + = link_to _('Read more'), help_page_path('workflow/repository_mirroring'), target: '_blank' + + .settings-content + = form_for @project, url: project_mirror_path(@project), html: { class: 'gl-show-field-errors js-mirror-form', autocomplete: 'false', data: mirrors_form_data_attributes } do |f| + .panel.panel-default + .panel-heading + %h3.panel-title= _('Mirror a repository') + .panel-body + %div= form_errors(@project) + + .form-group.has-feedback + = label_tag :url, _('Git repository URL'), class: 'label-light' + = text_field_tag :url, nil, class: 'form-control js-mirror-url js-repo-url', placeholder: _('Input your repository URL'), required: true, pattern: "(#{protocols}):\/\/.+" + + = render 'projects/mirrors/instructions' + + = render 'projects/mirrors/mirror_repos_form', f: f + + .form-check.append-bottom-10 + = check_box_tag :only_protected_branches, '1', false, class: 'js-mirror-protected form-check-input' + = label_tag :only_protected_branches, _('Only mirror protected branches'), class: 'form-check-label' + = link_to icon('question-circle'), help_page_path('user/project/protected_branches') + + .panel-footer + = f.submit _('Mirror repository'), class: 'btn btn-create', name: :update_remote_mirror + + .panel.panel-default + .table-responsive + %table.table.push-pull-table + %thead + %tr + %th + = _('Mirrored repositories') + = render_if_exists 'projects/mirrors/mirrored_repositories_count' + %th= _('Direction') + %th= _('Last update') + %th + %th + %tbody.js-mirrors-table-body + = render_if_exists 'projects/mirrors/table_pull_row' + - @project.remote_mirrors.each_with_index do |mirror, index| + - if mirror.enabled + %tr + %td= mirror.safe_url + %td= _('Push') + %td= mirror.last_update_at.present? ? time_ago_with_tooltip(mirror.last_update_at) : _('Never') + %td + - if mirror.last_error.present? + .badge.mirror-error-badge{ data: { toggle: 'tooltip', html: 'true' }, title: html_escape(mirror.last_error.try(:strip)) }= _('Error') + %td.mirror-action-buttons + .btn-group.mirror-actions-group.pull-right{ role: 'group' } + = render 'shared/remote_mirror_update_button', remote_mirror: mirror + %button.js-delete-mirror.btn.btn-danger{ type: 'button', data: { mirror_id: mirror.id, toggle: 'tooltip', container: 'body' }, title: _('Remove') }= icon('trash-o') diff --git a/app/views/projects/mirrors/_mirror_repos_form.html.haml b/app/views/projects/mirrors/_mirror_repos_form.html.haml new file mode 100644 index 00000000000..93994cb30ac --- /dev/null +++ b/app/views/projects/mirrors/_mirror_repos_form.html.haml @@ -0,0 +1,18 @@ +- protocols = Gitlab::UrlSanitizer::ALLOWED_SCHEMES.join('|') + +.form-group + = label_tag :mirror_direction, _('Mirror direction'), class: 'label-light' + = select_tag :mirror_direction, options_for_select([[_('Push'), 'push']]), class: 'form-control js-mirror-direction', disabled: true + += f.fields_for :remote_mirrors, @project.remote_mirrors.build do |rm_f| + = rm_f.hidden_field :enabled, value: '1' + = rm_f.hidden_field :url, class: 'js-mirror-url-hidden', required: true, pattern: "(#{protocols}):\/\/.+" + = rm_f.hidden_field :only_protected_branches, class: 'js-mirror-protected-hidden' + +.form-group + = label_tag :auth_method, _('Authentication method'), class: 'label-bold' + = select_tag :auth_method, options_for_select([[_('None'), 'none'], [_('Password'), 'password']], 'none'), { class: "form-control js-auth-method" } + +.form-group.js-password-group.collapse + = label_tag :password, _('Password'), class: 'label-bold' + = text_field_tag :password, '', class: 'form-control js-password' diff --git a/app/views/projects/mirrors/_push.html.haml b/app/views/projects/mirrors/_push.html.haml deleted file mode 100644 index 08375e09816..00000000000 --- a/app/views/projects/mirrors/_push.html.haml +++ /dev/null @@ -1,50 +0,0 @@ -- expanded = Rails.env.test? -%section.settings.no-animate#js-push-remote-settings{ class: ('expanded' if expanded) } - .settings-header - %h4 - Push to a remote repository - %button.btn.js-settings-toggle - = expanded ? 'Collapse' : 'Expand' - %p - Set up the remote repository that you want to update with the content of the current repository - every time someone pushes to it. - = link_to 'Read more', help_page_path('workflow/repository_mirroring', anchor: 'pushing-to-a-remote-repository'), target: '_blank' - .settings-content - = form_for @project, url: project_mirror_path(@project) do |f| - %div - = form_errors(@project) - = render "shared/remote_mirror_update_button", remote_mirror: @remote_mirror - - if @remote_mirror.last_error.present? - .panel.panel-danger - .panel-heading - - if @remote_mirror.last_update_at - The remote repository failed to update #{time_ago_with_tooltip(@remote_mirror.last_update_at)}. - - else - The remote repository failed to update. - - - if @remote_mirror.last_successful_update_at - Last successful update #{time_ago_with_tooltip(@remote_mirror.last_successful_update_at)}. - .panel-body - %pre - :preserve - #{h(@remote_mirror.last_error.strip)} - = f.fields_for :remote_mirrors, @remote_mirror do |rm_form| - .form-group - = rm_form.check_box :enabled, class: "float-left" - .prepend-left-20 - = rm_form.label :enabled, "Remote mirror repository", class: "label-bold append-bottom-0" - %p.light.append-bottom-0 - Automatically update the remote mirror's branches, tags, and commits from this repository every time someone pushes to it. - .form-group.has-feedback - = rm_form.label :url, "Git repository URL", class: "label-bold" - = rm_form.text_field :url, class: "form-control", placeholder: 'https://username:password@gitlab.company.com/group/project.git' - - = render "projects/mirrors/instructions" - - .form-group - = rm_form.check_box :only_protected_branches, class: 'float-left' - .prepend-left-20 - = rm_form.label :only_protected_branches, class: 'label-bold' - = link_to icon('question-circle'), help_page_path('user/project/protected_branches') - - = f.submit 'Save changes', class: 'btn btn-create', name: 'update_remote_mirror' diff --git a/app/views/projects/mirrors/_show.html.haml b/app/views/projects/mirrors/_show.html.haml index de77701a373..8318d5898a1 100644 --- a/app/views/projects/mirrors/_show.html.haml +++ b/app/views/projects/mirrors/_show.html.haml @@ -1,3 +1 @@ -- if can?(current_user, :admin_remote_mirror, @project) - = render 'projects/mirrors/push' - += render 'projects/mirrors/mirror_repos' diff --git a/app/views/shared/_remote_mirror_update_button.html.haml b/app/views/shared/_remote_mirror_update_button.html.haml index 34de1c0695f..f32cff18fa8 100644 --- a/app/views/shared/_remote_mirror_update_button.html.haml +++ b/app/views/shared/_remote_mirror_update_button.html.haml @@ -1,13 +1,6 @@ -- if @project.has_remote_mirror? - .append-bottom-default - - if remote_mirror.update_in_progress? - %span.btn.disabled - = icon("refresh spin") - Updating… - - else - = link_to update_now_project_mirror_path(@project, sync_remote: true), method: :post, class: "btn" do - = icon("refresh") - Update Now - - if @remote_mirror.last_successful_update_at - %p.inline.prepend-left-10 - Successfully updated #{time_ago_with_tooltip(@remote_mirror.last_successful_update_at)}. +- if remote_mirror.update_in_progress? + %button.btn.disabled{ type: 'button', data: { toggle: 'tooltip', container: 'body' }, title: _('Updating') } + = icon("refresh spin") +- else + = link_to update_now_project_mirror_path(@project, sync_remote: true), method: :post, class: "btn", data: { toggle: 'tooltip', container: 'body' }, title: _('Update now') do + = icon("refresh") |