Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
468bcfb9c6
commit
6a7fcb14aa
39 changed files with 267 additions and 148 deletions
12
CHANGELOG.md
12
CHANGELOG.md
|
@ -4,7 +4,9 @@ entry.
|
|||
|
||||
## 14.7.1 (2022-02-03)
|
||||
|
||||
No changes.
|
||||
### Security
|
||||
|
||||
See https://about.gitlab.com/releases/2022/02/03/security-release-gitlab-14-7-1-released/
|
||||
|
||||
## 14.7.0 (2022-01-21)
|
||||
|
||||
|
@ -445,7 +447,9 @@ No changes.
|
|||
|
||||
## 14.6.4 (2022-02-03)
|
||||
|
||||
No changes.
|
||||
### Security
|
||||
|
||||
See https://about.gitlab.com/releases/2022/02/03/security-release-gitlab-14-7-1-released/
|
||||
|
||||
## 14.6.3 (2022-01-18)
|
||||
|
||||
|
@ -847,7 +851,9 @@ No changes.
|
|||
|
||||
## 14.5.4 (2022-02-03)
|
||||
|
||||
No changes.
|
||||
### Security
|
||||
|
||||
See https://about.gitlab.com/releases/2022/02/03/security-release-gitlab-14-7-1-released/
|
||||
|
||||
## 14.5.3 (2022-01-11)
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
87a19146fdc01d0132a278b661017705514207cf
|
||||
6a00f3acce45365ac71798296667385efe8a72bc
|
||||
|
|
|
@ -14,31 +14,36 @@ export function isHTTPS() {
|
|||
export const FLOW_AUTHENTICATE = 'authenticate';
|
||||
export const FLOW_REGISTER = 'register';
|
||||
|
||||
// adapted from https://stackoverflow.com/a/21797381/8204697
|
||||
function base64ToBuffer(base64) {
|
||||
const binaryString = window.atob(base64);
|
||||
const len = binaryString.length;
|
||||
const bytes = new Uint8Array(len);
|
||||
for (let i = 0; i < len; i += 1) {
|
||||
bytes[i] = binaryString.charCodeAt(i);
|
||||
/**
|
||||
* Converts a base64 string to an ArrayBuffer
|
||||
*
|
||||
* @param {String} str - A base64 encoded string
|
||||
* @returns {ArrayBuffer}
|
||||
*/
|
||||
export const base64ToBuffer = (str) => {
|
||||
const rawStr = atob(str);
|
||||
const buffer = new ArrayBuffer(rawStr.length);
|
||||
const arr = new Uint8Array(buffer);
|
||||
for (let i = 0; i < rawStr.length; i += 1) {
|
||||
arr[i] = rawStr.charCodeAt(i);
|
||||
}
|
||||
return bytes.buffer;
|
||||
}
|
||||
return arr.buffer;
|
||||
};
|
||||
|
||||
// adapted from https://stackoverflow.com/a/9458996/8204697
|
||||
function bufferToBase64(buffer) {
|
||||
if (typeof buffer === 'string') {
|
||||
return buffer;
|
||||
/**
|
||||
* Converts ArrayBuffer to a base64-encoded string
|
||||
*
|
||||
* @param {ArrayBuffer, String} str -
|
||||
* @returns {String} - ArrayBuffer to a base64-encoded string.
|
||||
* When input is a string, returns the input as-is.
|
||||
*/
|
||||
export const bufferToBase64 = (input) => {
|
||||
if (typeof input === 'string') {
|
||||
return input;
|
||||
}
|
||||
|
||||
let binary = '';
|
||||
const bytes = new Uint8Array(buffer);
|
||||
const len = bytes.byteLength;
|
||||
for (let i = 0; i < len; i += 1) {
|
||||
binary += String.fromCharCode(bytes[i]);
|
||||
}
|
||||
return window.btoa(binary);
|
||||
}
|
||||
const arr = new Uint8Array(input);
|
||||
return btoa(String.fromCharCode(...arr));
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a copy of the given object with the id property converted to buffer
|
||||
|
|
|
@ -1,7 +1,15 @@
|
|||
<script>
|
||||
import { GlBadge, GlButton, GlCollapse, GlIcon, GlTooltipDirective as GlTooltip } from '@gitlab/ui';
|
||||
import {
|
||||
GlBadge,
|
||||
GlButton,
|
||||
GlCollapse,
|
||||
GlIcon,
|
||||
GlLink,
|
||||
GlTooltipDirective as GlTooltip,
|
||||
} from '@gitlab/ui';
|
||||
import { GlBreakpointInstance } from '@gitlab/ui/dist/utils';
|
||||
import { __, s__ } from '~/locale';
|
||||
import { truncate } from '~/lib/utils/text_utility';
|
||||
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
|
||||
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
|
||||
import DeploymentStatusBadge from './deployment_status_badge.vue';
|
||||
|
@ -16,6 +24,7 @@ export default {
|
|||
GlButton,
|
||||
GlCollapse,
|
||||
GlIcon,
|
||||
GlLink,
|
||||
TimeAgoTooltip,
|
||||
},
|
||||
directives: {
|
||||
|
@ -62,6 +71,15 @@ export default {
|
|||
commit() {
|
||||
return this.deployment?.commit;
|
||||
},
|
||||
user() {
|
||||
return this.deployment?.user;
|
||||
},
|
||||
username() {
|
||||
return truncate(this.user?.username, 25);
|
||||
},
|
||||
userPath() {
|
||||
return this.user?.path;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
toggleCollapse() {
|
||||
|
@ -75,6 +93,7 @@ export default {
|
|||
commitSha: __('Commit SHA'),
|
||||
showDetails: __('Show details'),
|
||||
hideDetails: __('Hide details'),
|
||||
triggerer: s__('Deployment|Triggerer'),
|
||||
},
|
||||
headerClasses: [
|
||||
'gl-display-flex',
|
||||
|
@ -149,6 +168,13 @@ export default {
|
|||
</gl-button>
|
||||
</div>
|
||||
<commit v-if="commit" :commit="commit" class="gl-mt-3" />
|
||||
<gl-collapse :visible="visible" />
|
||||
<gl-collapse :visible="visible">
|
||||
<div class="gl-display-flex gl-align-items-center gl-mt-5">
|
||||
<div v-if="user" class="gl-display-flex gl-flex-direction-column">
|
||||
<span class="gl-text-gray-500 gl-font-weight-bold">{{ $options.i18n.triggerer }}</span>
|
||||
<gl-link :href="userPath" class="gl-font-monospace gl-mt-3"> @{{ username }} </gl-link>
|
||||
</div>
|
||||
</div>
|
||||
</gl-collapse>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -99,8 +99,8 @@ export default {
|
|||
if (!this.lastDeployment) {
|
||||
return [];
|
||||
}
|
||||
const { manualActions = [], scheduledActions = [] } = this.lastDeployment;
|
||||
const combinedActions = [...manualActions, ...scheduledActions];
|
||||
const { manualActions, scheduledActions } = this.lastDeployment;
|
||||
const combinedActions = [...(manualActions ?? []), ...(scheduledActions ?? [])];
|
||||
return combinedActions.map((action) => ({
|
||||
...action,
|
||||
}));
|
||||
|
|
|
@ -70,9 +70,9 @@ export default {
|
|||
},
|
||||
fields: [
|
||||
tableField({ key: 'status', label: s__('Runners|Status') }),
|
||||
tableField({ key: 'summary', label: s__('Runners|Runner ID'), thClasses: ['gl-lg-w-25p'] }),
|
||||
tableField({ key: 'summary', label: s__('Runners|Runner'), thClasses: ['gl-lg-w-25p'] }),
|
||||
tableField({ key: 'version', label: __('Version') }),
|
||||
tableField({ key: 'ipAddress', label: __('IP Address') }),
|
||||
tableField({ key: 'ipAddress', label: __('IP') }),
|
||||
tableField({ key: 'jobCount', label: __('Jobs') }),
|
||||
tableField({ key: 'tagList', label: __('Tags'), thClasses: ['gl-lg-w-25p'] }),
|
||||
tableField({ key: 'contactedAt', label: __('Last contact') }),
|
||||
|
|
|
@ -15,6 +15,8 @@ module Types
|
|||
description: 'Full path of the project.'
|
||||
field :path, GraphQL::Types::String, null: false,
|
||||
description: 'Path of the project.'
|
||||
field :ci_config_path_or_default, GraphQL::Types::String, null: false,
|
||||
description: 'Path of the CI configuration file.'
|
||||
|
||||
field :sast_ci_configuration, Types::CiConfiguration::Sast::Type, null: true,
|
||||
calls_gitaly: true,
|
||||
|
|
|
@ -6,7 +6,7 @@ module InviteMembersHelper
|
|||
def can_invite_members_for_project?(project)
|
||||
# do not use the can_admin_project_member? helper here due to structure of the view and how membership_locked?
|
||||
# is leveraged for inviting groups
|
||||
Feature.enabled?(:invite_members_group_modal, project.group) && can?(current_user, :admin_project_member, project)
|
||||
Feature.enabled?(:invite_members_group_modal, project.group, default_enabled: :yaml) && can?(current_user, :admin_project_member, project)
|
||||
end
|
||||
|
||||
def invite_accepted_notice(member)
|
||||
|
|
|
@ -392,8 +392,7 @@ class Integration < ApplicationRecord
|
|||
end
|
||||
|
||||
def api_field_names
|
||||
fields.map { |field| field[:name] }
|
||||
.reject { |field_name| field_name =~ /(password|token|key|title|description)/ }
|
||||
fields.pluck(:name).grep_v(/password|token|key|title|description/)
|
||||
end
|
||||
|
||||
def global_fields
|
||||
|
|
|
@ -5,9 +5,8 @@ module MergeRequests
|
|||
include Gitlab::Utils::StrongMemoize
|
||||
|
||||
def execute(merge_request)
|
||||
prepare_for_mergeability(merge_request) if early_prepare_for_mergeability?(merge_request)
|
||||
prepare_for_mergeability(merge_request)
|
||||
prepare_merge_request(merge_request)
|
||||
check_mergeability(merge_request) unless early_prepare_for_mergeability?(merge_request)
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -26,11 +25,6 @@ module MergeRequests
|
|||
|
||||
notification_service.new_merge_request(merge_request, current_user)
|
||||
|
||||
unless early_prepare_for_mergeability?(merge_request)
|
||||
create_pipeline_for(merge_request, current_user)
|
||||
merge_request.update_head_pipeline
|
||||
end
|
||||
|
||||
merge_request.diffs(include_stats: false).write_cache
|
||||
merge_request.create_cross_references!(current_user)
|
||||
|
||||
|
@ -49,12 +43,6 @@ module MergeRequests
|
|||
LinkLfsObjectsService.new(project: merge_request.target_project).execute(merge_request)
|
||||
end
|
||||
|
||||
def early_prepare_for_mergeability?(merge_request)
|
||||
strong_memoize("early_prepare_for_mergeability_#{merge_request.target_project_id}".to_sym) do
|
||||
Feature.enabled?(:early_prepare_for_mergeability, merge_request.target_project)
|
||||
end
|
||||
end
|
||||
|
||||
def check_mergeability(merge_request)
|
||||
return unless merge_request.preparing?
|
||||
|
||||
|
|
|
@ -61,6 +61,10 @@ module QuickActions
|
|||
|
||||
private
|
||||
|
||||
def failed_parse(message)
|
||||
raise Gitlab::QuickActions::CommandDefinition::ParseError, message
|
||||
end
|
||||
|
||||
def extractor
|
||||
Gitlab::QuickActions::Extractor.new(self.class.command_definitions)
|
||||
end
|
||||
|
@ -69,6 +73,7 @@ module QuickActions
|
|||
def extract_users(params)
|
||||
return [] if params.nil?
|
||||
|
||||
args = params.split(' ').uniq
|
||||
users = extract_references(params, :user)
|
||||
|
||||
if users.empty?
|
||||
|
@ -76,10 +81,12 @@ module QuickActions
|
|||
if params.strip == 'me'
|
||||
[current_user]
|
||||
else
|
||||
User.where(username: params.split(' ').map(&:strip))
|
||||
User.where(username: args)
|
||||
end
|
||||
end
|
||||
|
||||
failed_parse(format(_("Failed to find users for '%{params}'"), params: params)) unless users.size == args.size
|
||||
|
||||
users
|
||||
end
|
||||
# rubocop: enable CodeReuse/ActiveRecord
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
= _('Group members')
|
||||
%p
|
||||
= html_escape(_('You can invite a new member to %{strong_start}%{group_name}%{strong_end}.')) % { group_name: @group.name, strong_start: '<strong>'.html_safe, strong_end: '</strong>'.html_safe }
|
||||
- if Feature.enabled?(:invite_members_group_modal, @group)
|
||||
- if Feature.enabled?(:invite_members_group_modal, @group, default_enabled: :yaml)
|
||||
.gl-w-half.gl-xs-w-full
|
||||
.gl-display-flex.gl-flex-wrap.gl-justify-content-end.gl-mb-3
|
||||
.js-invite-group-trigger{ data: { classes: 'gl-mt-3 gl-sm-w-auto gl-w-full', display_text: _('Invite a group') } }
|
||||
|
@ -20,7 +20,7 @@
|
|||
trigger_source: 'group-members-page',
|
||||
display_text: _('Invite members') } }
|
||||
= render 'groups/invite_members_modal', group: @group
|
||||
- if can_admin_group_member?(@group) && Feature.disabled?(:invite_members_group_modal, @group)
|
||||
- if can_admin_group_member?(@group) && Feature.disabled?(:invite_members_group_modal, @group, default_enabled: :yaml)
|
||||
%hr.gl-mt-4
|
||||
%ul.nav-links.nav.nav-tabs.gitlab-tabs{ role: 'tablist' }
|
||||
%li.nav-tab{ role: 'presentation' }
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
%p
|
||||
= html_escape(_("Members can be added by project %{i_open}Maintainers%{i_close} or %{i_open}Owners%{i_close}")) % { i_open: '<i>'.html_safe, i_close: '</i>'.html_safe }
|
||||
|
||||
- if Feature.disabled?(:invite_members_group_modal, @project.group) && can?(current_user, :admin_project_member, @project) && project_can_be_shared?
|
||||
- if Feature.disabled?(:invite_members_group_modal, @project.group, default_enabled: :yaml) && can?(current_user, :admin_project_member, @project) && project_can_be_shared?
|
||||
- if !membership_locked? && @project.allowed_to_share_with_group?
|
||||
%ul.nav-links.nav.nav-tabs.gitlab-tabs{ role: 'tablist' }
|
||||
%li.nav-tab{ role: 'presentation' }
|
||||
|
|
|
@ -37,6 +37,6 @@
|
|||
= render 'shared/choose_avatar_button', f: f
|
||||
- if @project.avatar?
|
||||
%hr
|
||||
= link_to _('Remove avatar'), project_avatar_path(@project), data: { confirm: _('Avatar will be removed. Are you sure?')}, method: :delete, class: 'gl-button btn btn-danger-secondary'
|
||||
= link_to _('Remove avatar'), project_avatar_path(@project), aria: { label: _('Remove avatar') }, data: { confirm: _('Avatar will be removed. Are you sure?'), 'confirm-btn-variant': 'danger' }, method: :delete, class: 'gl-button btn btn-danger-secondary'
|
||||
|
||||
= f.submit _('Save changes'), class: "gl-button btn btn-confirm gl-mt-6", data: { qa_selector: 'save_naming_topics_avatar_button' }
|
||||
|
|
|
@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75488
|
|||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/347405
|
||||
milestone: '14.6'
|
||||
type: development
|
||||
group: group::testing
|
||||
group: group::pipeline insights
|
||||
default_enabled: true
|
||||
|
|
|
@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/72406
|
|||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/338165
|
||||
milestone: '14.5'
|
||||
type: development
|
||||
group: group::testing
|
||||
group: group::pipeline insights
|
||||
default_enabled: false
|
||||
|
|
|
@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70235
|
|||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/343465
|
||||
milestone: '14.5'
|
||||
type: development
|
||||
group: group::testing
|
||||
group: group::pipeline insights
|
||||
default_enabled: false
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: early_prepare_for_mergeability
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75402
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/346667
|
||||
milestone: '14.6'
|
||||
type: development
|
||||
group: group::code review
|
||||
default_enabled: false
|
|
@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/247208
|
|||
milestone: '13.5'
|
||||
type: development
|
||||
group: group::expansion
|
||||
default_enabled: false
|
||||
default_enabled: true
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
name: notes_create_service_tracking
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/18890
|
||||
rollout_issue_url:
|
||||
rollout_issue_url:
|
||||
milestone: '12.5'
|
||||
type: development
|
||||
group: group::testing
|
||||
group: group::pipeline insights
|
||||
default_enabled: false
|
||||
|
|
|
@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/50922
|
|||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/296772
|
||||
milestone: '13.8'
|
||||
type: development
|
||||
group: group::testing
|
||||
group: group::pipeline insights
|
||||
default_enabled: true
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
- name: "Deprecate Geo Admin UI Routes"
|
||||
announcement_milestone: "14.8"
|
||||
announcement_date: "2022-02-22"
|
||||
removal_milestone: "15.0"
|
||||
removal_date: "2022-05-22"
|
||||
breaking_change: false
|
||||
reporter: nhxnguyen
|
||||
body: |
|
||||
In GitLab 13.0, we introduced new project and design replication details routes in the Geo Admin UI. These routes are `/admin/geo/replication/projects` and `/admin/geo/replication/designs`. We kept the legacy routes and redirected them to the new routes. In GitLab 15.0, we will remove support for the legacy routes `/admin/geo/projects` and `/admin/geo/designs`. Please update any bookmarks or scripts that may use the legacy routes.
|
||||
stage: "Enablement"
|
||||
tiers: ["Premium", "Ultimate"]
|
||||
issue_url: "https://gitlab.com/gitlab-org/gitlab/-/issues/351345"
|
||||
documentation_url: # (optional) This is a link to the current documentation page
|
||||
image_url: # (optional) This is a link to a thumbnail image depicting the feature
|
||||
video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
|
|
@ -13433,6 +13433,7 @@ Represents vulnerability finding of a security report on the pipeline.
|
|||
| <a id="projectautoclosereferencedissues"></a>`autocloseReferencedIssues` | [`Boolean`](#boolean) | Indicates if issues referenced by merge requests and commits within the default branch are closed automatically. |
|
||||
| <a id="projectavatarurl"></a>`avatarUrl` | [`String`](#string) | URL to avatar image file of the project. |
|
||||
| <a id="projectcicdsettings"></a>`ciCdSettings` | [`ProjectCiCdSetting`](#projectcicdsetting) | CI/CD settings for the project. |
|
||||
| <a id="projectciconfigpathordefault"></a>`ciConfigPathOrDefault` | [`String!`](#string) | Path of the CI configuration file. |
|
||||
| <a id="projectcijobtokenscope"></a>`ciJobTokenScope` | [`CiJobTokenScopeType`](#cijobtokenscopetype) | The CI Job Tokens scope of access. |
|
||||
| <a id="projectclusteragents"></a>`clusterAgents` | [`ClusterAgentConnection`](#clusteragentconnection) | Cluster agents associated with the project. (see [Connections](#connections)) |
|
||||
| <a id="projectcodecoveragesummary"></a>`codeCoverageSummary` | [`CodeCoverageSummary`](#codecoveragesummary) | Code coverage summary associated with the project. |
|
||||
|
|
|
@ -727,6 +727,12 @@ The `merged_by` field in the [merge request API](https://docs.gitlab.com/ee/api/
|
|||
|
||||
## 14.8
|
||||
|
||||
### Deprecate Geo Admin UI Routes
|
||||
|
||||
In GitLab 13.0, we introduced new project and design replication details routes in the Geo Admin UI. These routes are `/admin/geo/replication/projects` and `/admin/geo/replication/designs`. We kept the legacy routes and redirected them to the new routes. In GitLab 15.0, we will remove support for the legacy routes `/admin/geo/projects` and `/admin/geo/designs`. Please update any bookmarks or scripts that may use the legacy routes.
|
||||
|
||||
**Planned removal milestone: 15.0 (2022-05-22)**
|
||||
|
||||
### External status check API breaking changes
|
||||
|
||||
WARNING:
|
||||
|
|
|
@ -206,15 +206,14 @@ Instead of adding users one by one, you can [share a project with an entire grou
|
|||
|
||||
### Add a member modal window
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/247208) in GitLab 13.11.
|
||||
> - [Deployed behind a feature flag](../../feature_flags.md), disabled by default.
|
||||
> - Enabled on GitLab.com.
|
||||
> - Recommended for production use.
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/247208) in GitLab 13.11 [with a flag](../../feature_flags.md). Disabled by default.
|
||||
> - Replaces the existing form with buttons to open a modal window.
|
||||
> - To use in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-modal-window).
|
||||
> - [Enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/247208) in GitLab 14.8.
|
||||
|
||||
WARNING:
|
||||
This feature might not be available to you. Check the **version history** note above for details.
|
||||
FLAG:
|
||||
On self-managed GitLab, by default this feature is available.
|
||||
To hide the feature, ask an administrator to [disable the feature flag](#enable-or-disable-modal-window).
|
||||
On GitLab.com, this feature is available.
|
||||
|
||||
In GitLab 13.11, you can optionally replace the form to add a member with a modal window.
|
||||
To add a member after enabling this feature:
|
||||
|
@ -229,7 +228,7 @@ To add a member after enabling this feature:
|
|||
### Enable or disable modal window **(FREE SELF)**
|
||||
|
||||
The modal window for adding a member is under development and is ready for production use. It is
|
||||
deployed behind a feature flag that is **disabled by default**.
|
||||
deployed behind a feature flag that is **enabled by default**.
|
||||
[GitLab administrators with access to the GitLab Rails console](../../../administration/feature_flags.md)
|
||||
can enable it.
|
||||
|
||||
|
|
|
@ -221,14 +221,23 @@ security-code-scan-sast:
|
|||
image:
|
||||
name: "$SAST_ANALYZER_IMAGE"
|
||||
variables:
|
||||
SAST_ANALYZER_IMAGE_TAG: 2
|
||||
SAST_ANALYZER_IMAGE: "$SECURE_ANALYZERS_PREFIX/security-code-scan:$SAST_ANALYZER_IMAGE_TAG"
|
||||
rules:
|
||||
- if: $SAST_DISABLED
|
||||
when: never
|
||||
- if: $SAST_EXCLUDED_ANALYZERS =~ /security-code-scan/
|
||||
when: never
|
||||
# This rule shim will be removed in %15.0,
|
||||
# See https://gitlab.com/gitlab-org/gitlab/-/issues/350935
|
||||
- if: $CI_COMMIT_BRANCH && $CI_SERVER_VERSION_MAJOR == '14'
|
||||
variables:
|
||||
SAST_ANALYZER_IMAGE_TAG: '2'
|
||||
exists:
|
||||
- '**/*.csproj'
|
||||
- '**/*.vbproj'
|
||||
- if: $CI_COMMIT_BRANCH
|
||||
variables:
|
||||
SAST_ANALYZER_IMAGE_TAG: '3'
|
||||
exists:
|
||||
- '**/*.csproj'
|
||||
- '**/*.vbproj'
|
||||
|
|
|
@ -109,6 +109,8 @@ phpcs-security-audit:
|
|||
|
||||
security-code-scan:
|
||||
extends: .download_images
|
||||
variables:
|
||||
SECURE_BINARIES_ANALYZER_VERSION: "3"
|
||||
only:
|
||||
variables:
|
||||
- $SECURE_BINARIES_DOWNLOAD_IMAGES == "true" &&
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
module Gitlab
|
||||
module QuickActions
|
||||
class CommandDefinition
|
||||
ParseError = Class.new(StandardError)
|
||||
|
||||
attr_accessor :name, :aliases, :description, :explanation, :execution_message,
|
||||
:params, :condition_block, :parse_params_block, :action_block, :warning, :icon, :types
|
||||
|
||||
|
@ -41,7 +43,11 @@ module Gitlab
|
|||
return unless available?(context)
|
||||
|
||||
message = if explanation.respond_to?(:call)
|
||||
execute_block(explanation, context, arg)
|
||||
begin
|
||||
execute_block(explanation, context, arg)
|
||||
rescue ParseError => e
|
||||
format(_('Problem with %{name} command: %{message}.'), name: name, message: e.message)
|
||||
end
|
||||
else
|
||||
explanation
|
||||
end
|
||||
|
@ -63,6 +69,8 @@ module Gitlab
|
|||
return unless available?(context)
|
||||
|
||||
execute_block(action_block, context, arg)
|
||||
rescue ParseError
|
||||
# message propagation is handled in `execution_message`.
|
||||
end
|
||||
|
||||
def execute_message(context, arg)
|
||||
|
@ -74,6 +82,8 @@ module Gitlab
|
|||
else
|
||||
execution_message
|
||||
end
|
||||
rescue ParseError => e
|
||||
format _('Could not apply %{name} command. %{message}.'), name: name, message: e.message
|
||||
end
|
||||
|
||||
def to_h(context)
|
||||
|
|
|
@ -184,7 +184,7 @@ module Gitlab
|
|||
execution_message do |users = nil|
|
||||
reviewers = reviewers_to_add(users)
|
||||
if reviewers.blank?
|
||||
_("Failed to assign a reviewer because no user was found.")
|
||||
_("Failed to assign a reviewer because no user was specified.")
|
||||
else
|
||||
_('Assigned %{reviewer_users_sentence} as %{reviewer_text}.') % { reviewer_users_sentence: reviewer_users_sentence(users),
|
||||
reviewer_text: 'reviewer'.pluralize(reviewers.size) }
|
||||
|
|
|
@ -9953,6 +9953,9 @@ msgstr ""
|
|||
msgid "Could not apply %{name} command."
|
||||
msgstr ""
|
||||
|
||||
msgid "Could not apply %{name} command. %{message}."
|
||||
msgstr ""
|
||||
|
||||
msgid "Could not authorize chat nickname. Try again!"
|
||||
msgstr ""
|
||||
|
||||
|
@ -12148,6 +12151,9 @@ msgstr ""
|
|||
msgid "Deployment|This deployment was created using the API"
|
||||
msgstr ""
|
||||
|
||||
msgid "Deployment|Triggerer"
|
||||
msgstr ""
|
||||
|
||||
msgid "Deployment|Waiting"
|
||||
msgstr ""
|
||||
|
||||
|
@ -12740,6 +12746,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
|
|||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
msgid "Dismiss Alert"
|
||||
msgstr ""
|
||||
|
||||
msgid "Dismiss merge request promotion"
|
||||
msgstr ""
|
||||
|
||||
|
@ -14783,7 +14792,7 @@ msgid_plural "Failed to archive designs. Please try again."
|
|||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
msgid "Failed to assign a reviewer because no user was found."
|
||||
msgid "Failed to assign a reviewer because no user was specified."
|
||||
msgstr ""
|
||||
|
||||
msgid "Failed to assign a user because no user was found."
|
||||
|
@ -14849,6 +14858,9 @@ msgstr ""
|
|||
msgid "Failed to find import label for Jira import."
|
||||
msgstr ""
|
||||
|
||||
msgid "Failed to find users for '%{params}'"
|
||||
msgstr ""
|
||||
|
||||
msgid "Failed to generate export, please try again later."
|
||||
msgstr ""
|
||||
|
||||
|
@ -18071,6 +18083,9 @@ msgstr ""
|
|||
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
|
||||
msgstr ""
|
||||
|
||||
msgid "IP"
|
||||
msgstr ""
|
||||
|
||||
msgid "IP Address"
|
||||
msgstr ""
|
||||
|
||||
|
@ -27321,6 +27336,9 @@ msgstr ""
|
|||
msgid "Private projects can be created in your personal namespace with:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Problem with %{name} command: %{message}."
|
||||
msgstr ""
|
||||
|
||||
msgid "Proceed"
|
||||
msgstr ""
|
||||
|
||||
|
@ -31177,9 +31195,6 @@ msgstr ""
|
|||
msgid "Runners|Runner %{name} was deleted"
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|Runner ID"
|
||||
msgstr ""
|
||||
|
||||
msgid "Runners|Runner assigned to project."
|
||||
msgstr ""
|
||||
|
||||
|
@ -31976,6 +31991,9 @@ msgstr ""
|
|||
msgid "SecurityOrchestration|Add rule"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityOrchestration|All policies"
|
||||
msgstr ""
|
||||
|
||||
|
@ -31991,6 +32009,9 @@ msgstr ""
|
|||
msgid "SecurityOrchestration|Description"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityOrchestration|Don't show the alert anymore"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityOrchestration|Edit policy"
|
||||
msgstr ""
|
||||
|
||||
|
@ -32015,6 +32036,9 @@ msgstr ""
|
|||
msgid "SecurityOrchestration|Latest scan"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityOrchestration|Latest scan run against %{agent}"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityOrchestration|Network"
|
||||
msgstr ""
|
||||
|
||||
|
@ -32120,6 +32144,9 @@ msgstr ""
|
|||
msgid "SecurityOrchestration|This project does not contain any security policies."
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -55,8 +55,8 @@
|
|||
"@babel/preset-env": "^7.10.1",
|
||||
"@gitlab/at.js": "1.5.7",
|
||||
"@gitlab/favicon-overlay": "2.0.0",
|
||||
"@gitlab/svgs": "2.2.0",
|
||||
"@gitlab/ui": "35.0.0",
|
||||
"@gitlab/svgs": "2.3.0",
|
||||
"@gitlab/ui": "35.1.0",
|
||||
"@gitlab/visual-review-tools": "1.6.1",
|
||||
"@rails/actioncable": "6.1.4-1",
|
||||
"@rails/ujs": "6.1.4-1",
|
||||
|
|
19
spec/frontend/authentication/webauthn/util_spec.js
Normal file
19
spec/frontend/authentication/webauthn/util_spec.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
import { base64ToBuffer, bufferToBase64 } from '~/authentication/webauthn/util';
|
||||
|
||||
const encodedString = 'SGVsbG8gd29ybGQh';
|
||||
const stringBytes = [72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33];
|
||||
|
||||
describe('Webauthn utils', () => {
|
||||
it('base64ToBuffer', () => {
|
||||
const toArray = (val) => new Uint8Array(val);
|
||||
|
||||
expect(base64ToBuffer(encodedString)).toBeInstanceOf(ArrayBuffer);
|
||||
|
||||
expect(toArray(base64ToBuffer(encodedString))).toEqual(toArray(stringBytes));
|
||||
});
|
||||
|
||||
it('bufferToBase64', () => {
|
||||
const buffer = base64ToBuffer(encodedString);
|
||||
expect(bufferToBase64(buffer)).toBe(encodedString);
|
||||
});
|
||||
});
|
|
@ -149,7 +149,7 @@ describe('~/environments/components/deployment.vue', () => {
|
|||
});
|
||||
describe('is not present', () => {
|
||||
it('does not show the timestamp', () => {
|
||||
wrapper = createWrapper({ propsData: { deployment: { createdAt: null } } });
|
||||
wrapper = createWrapper({ propsData: { deployment: { ...deployment, createdAt: null } } });
|
||||
const date = wrapper.findByTitle(formatDate(deployment.createdAt));
|
||||
|
||||
expect(date.exists()).toBe(false);
|
||||
|
@ -205,6 +205,10 @@ describe('~/environments/components/deployment.vue', () => {
|
|||
expect(button.text()).toBe(__('Hide details'));
|
||||
expect(button.props('icon')).toBe('expand-up');
|
||||
expect(collapse.attributes('visible')).toBe('visible');
|
||||
|
||||
const username = wrapper.findByRole('link', { name: `@${deployment.user.username}` });
|
||||
|
||||
expect(username.attributes('href')).toBe(deployment.user.path);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -46,9 +46,9 @@ describe('RunnerList', () => {
|
|||
|
||||
expect(headerLabels).toEqual([
|
||||
'Status',
|
||||
'Runner ID',
|
||||
'Runner',
|
||||
'Version',
|
||||
'IP Address',
|
||||
'IP',
|
||||
'Jobs',
|
||||
'Tags',
|
||||
'Last contact',
|
||||
|
|
|
@ -35,7 +35,7 @@ RSpec.describe GitlabSchema.types['Project'] do
|
|||
pipeline_analytics squash_read_only sast_ci_configuration
|
||||
cluster_agent cluster_agents agent_configurations
|
||||
ci_template timelogs merge_commit_template squash_commit_template work_item_types
|
||||
recent_issue_boards
|
||||
recent_issue_boards ci_config_path_or_default
|
||||
]
|
||||
|
||||
expect(described_class).to include_graphql_fields(*expected_fields)
|
||||
|
|
|
@ -710,30 +710,21 @@ RSpec.describe Integration do
|
|||
[
|
||||
{ name: 'token' },
|
||||
{ name: 'api_token' },
|
||||
{ name: 'token_api' },
|
||||
{ name: 'safe_token' },
|
||||
{ name: 'key' },
|
||||
{ name: 'api_key' },
|
||||
{ name: 'password' },
|
||||
{ name: 'password_field' },
|
||||
{ name: 'some_safe_field' },
|
||||
{ name: 'safe_field' }
|
||||
]
|
||||
].shuffle
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
let(:integration) do
|
||||
fake_integration.new(properties: [
|
||||
{ token: 'token-value' },
|
||||
{ api_token: 'api_token-value' },
|
||||
{ key: 'key-value' },
|
||||
{ api_key: 'api_key-value' },
|
||||
{ password: 'password-value' },
|
||||
{ password_field: 'password_field-value' },
|
||||
{ safe_field: 'safe_field-value' }
|
||||
])
|
||||
end
|
||||
|
||||
it 'filters out sensitive fields' do
|
||||
expect(integration.api_field_names).to eq(['safe_field'])
|
||||
expect(fake_integration.new).to have_attributes(api_field_names: match_array(%w[some_safe_field safe_field]))
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -108,17 +108,6 @@ RSpec.describe MergeRequests::AfterCreateService do
|
|||
expect { execute_service }.to raise_error(StandardError)
|
||||
expect(merge_request.reload).to be_preparing
|
||||
end
|
||||
|
||||
context 'when early_prepare_for_mergeability feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(early_prepare_for_mergeability: false)
|
||||
end
|
||||
|
||||
it 'does not mark the merge request as unchecked' do
|
||||
expect { execute_service }.to raise_error(StandardError)
|
||||
expect(merge_request.reload).to be_preparing
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when preparing merge request fails' do
|
||||
|
@ -134,17 +123,6 @@ RSpec.describe MergeRequests::AfterCreateService do
|
|||
expect(merge_request).to receive(:check_mergeability).with(async: true)
|
||||
expect { execute_service }.to raise_error(StandardError)
|
||||
end
|
||||
|
||||
context 'when early_prepare_for_mergeability feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(early_prepare_for_mergeability: false)
|
||||
end
|
||||
|
||||
it 'does not mark the merge request as unchecked' do
|
||||
expect { execute_service }.to raise_error(StandardError)
|
||||
expect(merge_request.reload).to be_preparing
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -485,6 +485,8 @@ RSpec.describe QuickActions::InterpretService do
|
|||
end
|
||||
|
||||
shared_examples 'failed command' do |error_msg|
|
||||
let(:match_msg) { error_msg ? eq(error_msg) : be_empty }
|
||||
|
||||
it 'populates {} if content contains an unsupported command' do
|
||||
_, updates, _ = service.execute(content, issuable)
|
||||
|
||||
|
@ -494,11 +496,7 @@ RSpec.describe QuickActions::InterpretService do
|
|||
it "returns #{error_msg || 'an empty'} message" do
|
||||
_, _, message = service.execute(content, issuable)
|
||||
|
||||
if error_msg
|
||||
expect(message).to eq(error_msg)
|
||||
else
|
||||
expect(message).to be_empty
|
||||
end
|
||||
expect(message).to match_msg
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -887,9 +885,10 @@ RSpec.describe QuickActions::InterpretService do
|
|||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'failed command', "Failed to assign a user because no user was found." do
|
||||
it_behaves_like 'failed command', 'a parse error' do
|
||||
let(:content) { '/assign @abcd1234' }
|
||||
let(:issuable) { issue }
|
||||
let(:match_msg) { eq "Could not apply assign command. Failed to find users for '@abcd1234'." }
|
||||
end
|
||||
|
||||
it_behaves_like 'failed command', "Failed to assign a user because no user was found." do
|
||||
|
@ -953,7 +952,9 @@ RSpec.describe QuickActions::InterpretService do
|
|||
context 'with an incorrect user' do
|
||||
let(:content) { '/assign_reviewer @abcd1234' }
|
||||
|
||||
it_behaves_like 'failed command', "Failed to assign a reviewer because no user was found."
|
||||
it_behaves_like 'failed command', 'a parse error' do
|
||||
let(:match_msg) { eq "Could not apply assign_reviewer command. Failed to find users for '@abcd1234'." }
|
||||
end
|
||||
end
|
||||
|
||||
context 'with the "reviewer" alias' do
|
||||
|
@ -971,13 +972,16 @@ RSpec.describe QuickActions::InterpretService do
|
|||
context 'with no user' do
|
||||
let(:content) { '/assign_reviewer' }
|
||||
|
||||
it_behaves_like 'failed command', "Failed to assign a reviewer because no user was found."
|
||||
it_behaves_like 'failed command', "Failed to assign a reviewer because no user was specified."
|
||||
end
|
||||
|
||||
context 'includes only the user reference with extra text' do
|
||||
let(:content) { "/assign_reviewer @#{developer.username} do it!" }
|
||||
context 'with extra text' do
|
||||
let(:arg) { "@#{developer.username} do it!" }
|
||||
let(:content) { "/assign_reviewer #{arg}" }
|
||||
|
||||
it_behaves_like 'assign_reviewer command'
|
||||
it_behaves_like 'failed command', 'a parse error' do
|
||||
let(:match_msg) { eq "Could not apply assign_reviewer command. Failed to find users for '#{arg}'." }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -2317,12 +2321,41 @@ RSpec.describe QuickActions::InterpretService do
|
|||
end
|
||||
|
||||
describe 'assign command' do
|
||||
let(:content) { "/assign @#{developer.username} do it!" }
|
||||
shared_examples 'assigns developer' do
|
||||
it 'tells us we will assign the developer' do
|
||||
_, explanations = service.explain(content, merge_request)
|
||||
|
||||
it 'includes only the user reference' do
|
||||
_, explanations = service.explain(content, merge_request)
|
||||
expect(explanations).to eq(["Assigns @#{developer.username}."])
|
||||
end
|
||||
end
|
||||
|
||||
expect(explanations).to eq(["Assigns @#{developer.username}."])
|
||||
context 'when using a reference' do
|
||||
let(:content) { "/assign @#{developer.username}" }
|
||||
|
||||
include_examples 'assigns developer'
|
||||
end
|
||||
|
||||
context 'when using a bare username' do
|
||||
let(:content) { "/assign #{developer.username}" }
|
||||
|
||||
include_examples 'assigns developer'
|
||||
end
|
||||
|
||||
context 'when using me' do
|
||||
let(:content) { "/assign me" }
|
||||
|
||||
include_examples 'assigns developer'
|
||||
end
|
||||
|
||||
context 'when there are unparseable arguments' do
|
||||
let(:arg) { "#{developer.username} to this issue" }
|
||||
let(:content) { "/assign #{arg}" }
|
||||
|
||||
it 'tells us why we cannot do that' do
|
||||
_, explanations = service.explain(content, merge_request)
|
||||
|
||||
expect(explanations).to eq ["Problem with assign command: Failed to find users for '#{arg}'."]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
16
yarn.lock
16
yarn.lock
|
@ -957,15 +957,15 @@
|
|||
stylelint-declaration-strict-value "1.8.0"
|
||||
stylelint-scss "4.1.0"
|
||||
|
||||
"@gitlab/svgs@2.2.0":
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-2.2.0.tgz#95cf58d6ae634d535145159f08f5cff6241d4013"
|
||||
integrity sha512-mCwR3KfNPsxRoojtTjMIZwdd4FFlBh5DlR9AeodP+7+k8rILdWGYxTZbJMPNXoPbZx16R94nG8c5bR7toD4QBw==
|
||||
"@gitlab/svgs@2.3.0":
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-2.3.0.tgz#2ddb38c1e27a5f1945863c3093107117c0175be4"
|
||||
integrity sha512-VXryDplnM+sImEleyxDnW4oyDvIwUhSCZ/+hxYmXesysQiK+vm+hEfdc2N+AnlD2xbdbnuMQnegckOL38Ic2/g==
|
||||
|
||||
"@gitlab/ui@35.0.0":
|
||||
version "35.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-35.0.0.tgz#9fb89babddc337830f1245044fe7946b266395b4"
|
||||
integrity sha512-iGGsLFgy/BOnmym2VBT+ByiP7mY/DtJPDSoYjd7QtJbOF17A+MyvOwBFGTUXAJxDtWTYSkMZkEuwZVA3VOEwyQ==
|
||||
"@gitlab/ui@35.1.0":
|
||||
version "35.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-35.1.0.tgz#feebe3e7bc4260b256c92e753201f12dae3d8857"
|
||||
integrity sha512-j0+kXYkWfgxrHUG41WR0xL+ctcPwGhCM2YxinKy0DQmXmHGgw380bk922/r2yXAnQ6A4KDuvjQz1Ue0m1Yj6Cw==
|
||||
dependencies:
|
||||
"@babel/standalone" "^7.0.0"
|
||||
bootstrap-vue "2.20.1"
|
||||
|
|
Loading…
Reference in a new issue