Skip to content
Snippets Groups Projects
Commit 63894d59 authored by GitLab Bot's avatar GitLab Bot
Browse files

Add latest changes from gitlab-org/gitlab@master

parent cd15d0e6
No related branches found
No related tags found
No related merge requests found
Showing
with 258 additions and 32 deletions
import $ from 'jquery';
import { rstrip } from './lib/utils/common_utils';
 
function openConfirmDangerModal($form, text) {
const $input = $('.js-confirm-danger-input');
function openConfirmDangerModal($form, $modal, text) {
const $input = $('.js-confirm-danger-input', $modal);
$input.val('');
 
$('.js-confirm-text').text(text || '');
$('#modal-confirm-danger').modal('show');
$('.js-confirm-text', $modal).text(text || '');
$modal.modal('show');
 
const confirmTextMatch = $('.js-confirm-danger-match').text();
const $submit = $('.js-confirm-danger-submit');
const confirmTextMatch = $('.js-confirm-danger-match', $modal).text();
const $submit = $('.js-confirm-danger-submit', $modal);
$submit.disable();
$input.focus();
 
$('.js-confirm-danger-input')
.off('input')
.on('input', function handleInput() {
const confirmText = rstrip($(this).val());
if (confirmText === confirmTextMatch) {
$submit.enable();
} else {
$submit.disable();
}
});
$('.js-confirm-danger-submit')
$input.off('input').on('input', function handleInput() {
const confirmText = rstrip($(this).val());
if (confirmText === confirmTextMatch) {
$submit.enable();
} else {
$submit.disable();
}
});
$('.js-confirm-danger-submit', $modal)
.off('click')
.on('click', () => $form.submit());
}
 
function getModal($btn) {
const $modal = $btn.prev('.modal');
if ($modal.length) {
return $modal;
}
return $('#modal-confirm-danger');
}
export default function initConfirmDangerModal() {
$(document).on('click', '.js-confirm-danger', e => {
e.preventDefault();
const $btn = $(e.target);
const $form = $btn.closest('form');
const text = $btn.data('confirmDangerMessage');
openConfirmDangerModal($form, text);
const checkFieldName = $btn.data('checkFieldName');
const checkFieldCompareValue = $btn.data('checkCompareValue');
const checkFieldVal = parseInt($(`[name="${checkFieldName}"]`).val(), 10);
if (!checkFieldName || checkFieldVal < checkFieldCompareValue) {
e.preventDefault();
const $form = $btn.closest('form');
const $modal = getModal($btn);
const text = $btn.data('confirmDangerMessage');
openConfirmDangerModal($form, $modal, text);
}
});
}
Loading
Loading
@@ -3,8 +3,9 @@ import _ from 'underscore';
import successSvg from 'icons/_icon_status_success.svg';
import warningSvg from 'icons/_icon_status_warning.svg';
import simplePoll from '~/lib/utils/simple_poll';
import { __ } from '~/locale';
import { __, sprintf } from '~/locale';
import readyToMergeMixin from 'ee_else_ce/vue_merge_request_widget/mixins/ready_to_merge';
import { GlIcon } from '@gitlab/ui';
import MergeRequest from '../../../merge_request';
import { refreshUserMergeRequestCounts } from '~/commons/nav/user_merge_requests';
import Flash from '../../../flash';
Loading
Loading
@@ -24,6 +25,7 @@ export default {
CommitsHeader,
CommitEdit,
CommitMessageDropdown,
GlIcon,
},
mixins: [readyToMergeMixin],
props: {
Loading
Loading
@@ -111,6 +113,18 @@ export default {
shouldShowMergeEdit() {
return !this.mr.ffOnlyEnabled;
},
shaMismatchLink() {
const href = this.mr.mergeRequestDiffsPath;
return sprintf(
__('New changes were added. %{linkStart}Reload the page to review them%{linkEnd}'),
{
linkStart: `<a href="${href}">`,
linkEnd: '</a>',
},
false,
);
},
},
methods: {
updateMergeCommitMessage(includeDescription) {
Loading
Loading
@@ -123,7 +137,7 @@ export default {
}
 
const options = {
sha: this.mr.sha,
sha: this.mr.latestSHA || this.mr.sha,
commit_message: this.commitMessage,
auto_merge_strategy: useAutoMerge ? this.mr.preferredAutoMergeStrategy : undefined,
should_remove_source_branch: this.removeSourceBranch === true,
Loading
Loading
@@ -314,6 +328,10 @@ export default {
</template>
</div>
</div>
<div v-if="mr.isSHAMismatch" class="d-flex align-items-center mt-2 js-sha-mismatch">
<gl-icon name="warning-solid" class="text-warning mr-1" />
<span class="text-warning" v-html="shaMismatchLink"></span>
</div>
</div>
</div>
<template v-if="shouldShowMergeControls">
Loading
Loading
Loading
Loading
@@ -25,7 +25,6 @@ import NothingToMergeState from './components/states/nothing_to_merge.vue';
import MissingBranchState from './components/states/mr_widget_missing_branch.vue';
import NotAllowedState from './components/states/mr_widget_not_allowed.vue';
import ReadyToMergeState from './components/states/ready_to_merge.vue';
import ShaMismatchState from './components/states/sha_mismatch.vue';
import UnresolvedDiscussionsState from './components/states/unresolved_discussions.vue';
import PipelineBlockedState from './components/states/mr_widget_pipeline_blocked.vue';
import PipelineFailedState from './components/states/pipeline_failed.vue';
Loading
Loading
@@ -63,7 +62,7 @@ export default {
'mr-widget-not-allowed': NotAllowedState,
'mr-widget-missing-branch': MissingBranchState,
'mr-widget-ready-to-merge': ReadyToMergeState,
'sha-mismatch': ShaMismatchState,
'sha-mismatch': ReadyToMergeState,
'mr-widget-checking': CheckingState,
'mr-widget-unresolved-discussions': UnresolvedDiscussionsState,
'mr-widget-pipeline-blocked': PipelineBlockedState,
Loading
Loading
Loading
Loading
@@ -48,6 +48,7 @@ export default class MergeRequestStore {
this.commits = data.commits_without_merge_commits || [];
this.squashCommitMessage = data.default_squash_commit_message;
this.rebaseInProgress = data.rebase_in_progress;
this.mergeRequestDiffsPath = data.diffs_path;
 
if (data.issues_links) {
const links = data.issues_links;
Loading
Loading
@@ -81,6 +82,7 @@ export default class MergeRequestStore {
this.isOpen = data.state === 'opened';
this.hasMergeableDiscussionsState = data.mergeable_discussions_state === false;
this.isSHAMismatch = this.sha !== data.diff_head_sha;
this.latestSHA = data.diff_head_sha;
this.canBeMerged = data.can_be_merged || false;
this.isMergeAllowed = data.mergeable || false;
this.mergeOngoing = data.merge_ongoing;
Loading
Loading
@@ -170,6 +172,7 @@ export default class MergeRequestStore {
this.conflictsDocsPath = data.conflicts_docs_path;
this.ciEnvironmentsStatusPath = data.ci_environments_status_path;
this.securityApprovalsHelpPagePath = data.security_approvals_help_page_path;
this.eligibleApproversDocsPath = data.eligible_approvers_docs_path;
}
 
get isNothingToMergeState() {
Loading
Loading
Loading
Loading
@@ -699,4 +699,8 @@ module ProjectsHelper
def vue_file_list_enabled?
Feature.enabled?(:vue_file_list, @project)
end
def show_visibility_confirm_modal?(project)
project.unlink_forks_upon_visibility_decrease_enabled? && project.visibility_level > Gitlab::VisibilityLevel::PRIVATE && project.forks_count > 0
end
end
Loading
Loading
@@ -70,6 +70,10 @@ class MergeRequestPollCachedWidgetEntity < IssuableEntity
presenter(merge_request).source_branch_with_namespace_link
end
 
expose :diffs_path do |merge_request|
diffs_project_merge_request_path(merge_request.project, merge_request)
end
private
 
delegate :current_user, to: :request
Loading
Loading
- strong_start = "<strong>".html_safe
- strong_end = "</strong>".html_safe
.modal.js-confirm-project-visiblity{ tabindex: -1 }
.modal-dialog
.modal-content
.modal-header
%h3.page-title= _('Reduce this project’s visibility?')
%button.close{ type: "button", "data-dismiss": "modal", "aria-label" => _('Close') }
%span{ "aria-hidden": true }= sprite_icon("close", size: 16)
.modal-body
%p
- if @project.group
= _("You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end} in %{strong_start}%{group_name}%{strong_end}.").html_safe % { project_name: @project.name, group_name: @project.group.name, strong_start: strong_start, strong_end: strong_end }
- else
= _("You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end}.").html_safe % { project_name: @project.name, strong_start: strong_start, strong_end: strong_end }
%p
= _('Once you confirm and press "Reduce project visibility":')
%ul
%li
= ("Current forks will keep their visibility level but their fork relationship with this project will be %{strong_start}removed%{strong_end}.").html_safe % { strong_start: strong_start, strong_end: strong_end }
%label{ for: "confirm_path_input" }
= ("To confirm, type %{phrase_code}").html_safe % { phrase_code: '<code class="js-confirm-danger-match">%{phrase_name}</code>'.html_safe % { phrase_name: @project.full_path } }
.form-group
= text_field_tag 'confirm_path_input', '', class: 'form-control js-confirm-danger-input qa-confirm-input'
.form-actions.clearfix
.pull-right
%button.btn.btn-default{ type: "button", "data-dismiss": "modal" }
= _('Cancel')
= submit_tag _('Reduce project visibility'), class: "btn btn-danger js-confirm-danger-submit qa-confirm-button", disabled: true
Loading
Loading
@@ -21,7 +21,9 @@
%input{ name: 'update_section', type: 'hidden', value: 'js-shared-permissions' }
%template.js-project-permissions-form-data{ type: "application/json" }= project_permissions_panel_data_json(@project)
.js-project-permissions-form
= f.submit _('Save changes'), class: "btn btn-success", data: { qa_selector: 'visibility_features_permissions_save_button' }
- if show_visibility_confirm_modal?(@project)
= render "visibility_modal"
= f.submit _('Save changes'), class: "btn btn-success #{('js-confirm-danger' if show_visibility_confirm_modal?(@project))}", data: { qa_selector: 'visibility_features_permissions_save_button', check_field_name: ("project[visibility_level]" if show_visibility_confirm_modal?(@project)), check_compare_value: @project.visibility_level }
 
%section.qa-merge-request-settings.rspec-merge-request-settings.settings.merge-requests-feature.no-animate#js-merge-request-settings{ class: [('expanded' if expanded), ('hidden' if @project.project_feature.send(:merge_requests_access_level) == 0)] }
.settings-header
Loading
Loading
Loading
Loading
@@ -9,5 +9,6 @@
window.gl.mrWidgetData.squash_before_merge_help_path = '#{help_page_path("user/project/merge_requests/squash_and_merge")}';
window.gl.mrWidgetData.troubleshooting_docs_path = '#{help_page_path('user/project/merge_requests/index.md', anchor: 'troubleshooting')}';
window.gl.mrWidgetData.security_approvals_help_page_path = '#{help_page_path('user/application_security/index.html', anchor: 'security-approvals-in-merge-requests-ultimate')}';
window.gl.mrWidgetData.eligible_approvers_docs_path = '#{help_page_path('user/project/merge_requests/merge_request_approvals', anchor: 'eligible-approvers')}';
 
#js-vue-mr-widget.mr-widget
---
title: Add upvote/downvotes attributes to GraphQL Epic query
merge_request: 14311
author:
type: added
---
title: Allow merge without refresh when new commits are pushed
merge_request: 19725
author:
type: changed
---
title: Resolve Add missing popover and remove none in MR widget
merge_request: 21095
author:
type: other
---
title: Asks for confirmation before changing project visibility level
merge_request: 20170
author:
type: added
---
title: Remove action buttons from designs tab if there are no designs
merge_request: 21186
author:
type: fixed
Loading
Loading
@@ -1230,6 +1230,11 @@ type Epic implements Noteable {
"""
last: Int
): DiscussionConnection!
"""
Number of downvotes the epic has received
"""
downvotes: Int!
dueDate: Time
dueDateFixed: Time
dueDateFromMilestones: Time
Loading
Loading
@@ -1360,6 +1365,11 @@ type Epic implements Noteable {
title: String
updatedAt: Time
 
"""
Number of upvotes the epic has received
"""
upvotes: Int!
"""
Permissions for the current user on the resource
"""
Loading
Loading
Loading
Loading
@@ -3630,6 +3630,24 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "downvotes",
"description": "Number of downvotes the epic has received",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "dueDate",
"description": null,
Loading
Loading
@@ -4181,6 +4199,24 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "upvotes",
"description": "Number of upvotes the epic has received",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "userPermissions",
"description": "Permissions for the current user on the resource",
Loading
Loading
Loading
Loading
@@ -211,6 +211,8 @@ The API can be explored interactively using the [GraphiQL IDE](../index.md#graph
| `dueDateIsFixed` | Boolean | |
| `dueDateFixed` | Time | |
| `dueDateFromMilestones` | Time | |
| `upvotes` | Int! | Number of upvotes the epic has received |
| `downvotes` | Int! | Number of downvotes the epic has received |
| `closedAt` | Time | |
| `createdAt` | Time | |
| `updatedAt` | Time | |
Loading
Loading
Loading
Loading
@@ -277,14 +277,81 @@ Here are the steps to gate a new feature in Gitaly behind a feature flag.
 
### GitLab Rails
 
1. Add feature flag to `lib/gitlab/gitaly_client.rb` (in GitLab Rails):
1. In GitLab Rails:
 
```ruby
SERVER_FEATURE_FLAGS = %w[go-find-all-tags].freeze
```
1. Add the feature flag to `SERVER_FEATURE_FLAGS` in `lib/feature/gitaly.rb`:
```ruby
SERVER_FEATURE_FLAGS = %w[go-find-all-tags].freeze
```
1. Search for `["gitaly"]["features"]` (currently in `spec/requests/api/internal/base_spec.rb`)
and fix the expected results for the tests by adding the new feature flag into it:
```ruby
expect(json_response["gitaly"]["features"]).to eq('gitaly-feature-get-all-lfs-pointers-go' => 'true', 'gitaly-feature-go-find-all-tags' => 'true')
```
 
1. Test in rails console by setting feature flag:
1. Test in a Rails console by setting the feature flag:
NOTE: **Note:**
Pay attention to the name of the flag and the one used in the Rails console.
There is a difference between them (dashes replaced by underscores and name
prefix is changed).
 
```ruby
Feature.enable('gitaly_go-find-all-tags')
Feature.enable('gitaly_go_find_all_tags')
```
### Testing with GDK
To be sure that the flag is set correctly and it goes into Gitaly, you can check
the integration by using GDK:
1. The state of the flag must be observable. To check it, you need to enable it
by fetching the Prometheus metrics:
1. Navigate to GDK's root directory.
1. Make sure you have the proper branch checked out for Gitaly.
1. Recompile it with `make gitaly-setup` and restart the service with `gdk restart gitaly`.
1. Make sure your setup is runnig: `gdk status | grep praefect`.
1. Check what config file is used: `cat ./services/praefect/run | grep praefect` value of the `-config` flag
1. Uncomment `prometheus_listen_addr` in the configuration file and run `gdk restart gitaly`.
1. Make sure that the flag is not enabled yet:
1. Perform whatever action is required to trigger your changes (project creation,
submitting commit, observing history, etc.).
1. Check that the list of current metrics has the new counter for the feature flag:
```sh
curl --silent http://localhost:9236/metrics | grep go_find_all_tags
```
1. Once you observe the metrics for the new feature flag and it increments, you
can enable the new feature:
1. Navigate to GDK's root directory.
1. Start a Rails console:
```sh
bundle install && bundle exec rails console
```
1. Check the list of feature flags:
```ruby
Feature::Gitaly.server_feature_flags
```
It should be disabled `"gitaly-feature-go-find-all-tags"=>"false"`.
1. Enable it:
```ruby
Feature.enable('gitaly_go_find_all_tags')
```
1. Exit the Rails console and perform whatever action is required to trigger
your changes (project creation, submitting commit, observing history, etc.).
1. Verify the feature is on by observing the metrics for it:
```sh
curl --silent http://localhost:9236/metrics | grep go_find_all_tags
```
doc/public_access/img/project_visibility_confirmation_v12_6.png

99.1 KiB

Loading
Loading
@@ -77,6 +77,16 @@ by accident. The restricted visibility settings do not apply to admin users.
 
For details, see [Restricted visibility levels](../user/admin_area/settings/visibility_and_access_controls.md#restricted-visibility-levels).
 
## Reducing visibility
> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/33358) in GitLab 12.6.
Reducing a project's visibility level will remove the fork relationship between the project and
any forked project. This is a potentially destructive action which requires confirmation before
this can be saved.
![Project visibility change confirmation](img/project_visibility_confirmation_v12_6.png)
<!-- ## Troubleshooting
 
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment