Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
fa91163a5b
commit
5f5a1d09aa
|
|
@ -213,7 +213,7 @@ semgrep-appsec-custom-rules:
|
|||
stage: lint
|
||||
extends:
|
||||
- .semgrep-appsec-custom-rules:rules
|
||||
image: returntocorp/semgrep
|
||||
image: returntocorp/semgrep:1.99.0
|
||||
needs: []
|
||||
script:
|
||||
- git fetch origin master
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ Layout/LineLength:
|
|||
- 'app/controllers/application_controller.rb'
|
||||
- 'app/controllers/groups/milestones_controller.rb'
|
||||
- 'app/controllers/projects/issues_controller.rb'
|
||||
- 'app/controllers/projects/jobs_controller.rb'
|
||||
- 'app/controllers/projects/labels_controller.rb'
|
||||
- 'app/controllers/projects/milestones_controller.rb'
|
||||
- 'app/controllers/projects/notes_controller.rb'
|
||||
|
|
|
|||
|
|
@ -2,14 +2,6 @@
|
|||
# Cop supports --autocorrect.
|
||||
Style/StringConcatenation:
|
||||
Exclude:
|
||||
- 'app/controllers/projects/labels_controller.rb'
|
||||
- 'app/controllers/projects/milestones_controller.rb'
|
||||
- 'app/models/concerns/cross_database_modification.rb'
|
||||
- 'app/models/concerns/from_set_operator.rb'
|
||||
- 'app/models/concerns/routable.rb'
|
||||
- 'app/models/integrations/chat_message/merge_message.rb'
|
||||
- 'app/models/integrations/chat_message/note_message.rb'
|
||||
- 'app/models/namespace.rb'
|
||||
- 'app/models/packages/go/module_version.rb'
|
||||
- 'app/models/pool_repository.rb'
|
||||
- 'app/models/project_wiki.rb'
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
db3ec43472f41609c94a3f0cf5382b26360638e1
|
||||
53cd0a7f9b29bb9c76e294e25e15c2597bcc8800
|
||||
|
|
|
|||
|
|
@ -8,6 +8,16 @@
|
|||
"type": "string",
|
||||
"format": "uri"
|
||||
},
|
||||
"spec": {
|
||||
"type": "object",
|
||||
"markdownDescription": "Specification for pipeline configuration. Must be declared at the top of a configuration file, in a header section separated from the rest of the configuration with `---`. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#spec).",
|
||||
"properties": {
|
||||
"inputs": {
|
||||
"$ref": "#/definitions/inputParameters"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"image": {
|
||||
"$ref": "#/definitions/image",
|
||||
"markdownDescription": "Defining `image` globally is deprecated. Use [`default`](https://docs.gitlab.com/ee/ci/yaml/#default) instead. [Learn more](https://docs.gitlab.com/ee/ci/yaml/#globally-defined-image-services-cache-before_script-after_script)."
|
||||
|
|
@ -389,6 +399,156 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"inputParameters": {
|
||||
"type": "object",
|
||||
"markdownDescription": "Define parameters that can be populated in reusable CI/CD configuration files when added to a pipeline. [Learn More](https://docs.gitlab.com/ee/ci/yaml/inputs).",
|
||||
"patternProperties": {
|
||||
".*": {
|
||||
"markdownDescription": "**Input Configuration**\n\nAvailable properties:\n- `type`: string (default), array, boolean, or number\n- `description`: Human-readable explanation of the parameter (supports Markdown)\n- `options`: List of allowed values\n- `default`: Value to use when not specified (makes input optional)\n- `regex`: Pattern that string values must match",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"markdownDescription": "Force a specific input type. Defaults to 'string' when not specified. [Learn More](https://docs.gitlab.com/ee/ci/yaml/inputs/#input-types).",
|
||||
"enum": [
|
||||
"array",
|
||||
"boolean",
|
||||
"number",
|
||||
"string"
|
||||
],
|
||||
"default": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"markdownDescription": "Give a description to a specific input. The description does not affect the input, but can help people understand the input details or expected values. Supports markdown.",
|
||||
"maxLength": 1024
|
||||
},
|
||||
"options": {
|
||||
"type": "array",
|
||||
"markdownDescription": "Specify a list of allowed values for an input.",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"regex": {
|
||||
"type": "string",
|
||||
"markdownDescription": "Specify a regular expression that the input must match. Only impacts inputs with a `type` of `string`."
|
||||
},
|
||||
"default": {
|
||||
"markdownDescription": "Define default values for inputs when not specified. When you specify a default, the inputs are no longer mandatory."
|
||||
}
|
||||
},
|
||||
"allOf": [
|
||||
{
|
||||
"if": {
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"string"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"then": {
|
||||
"properties": {
|
||||
"default": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": {
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"number"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"then": {
|
||||
"properties": {
|
||||
"default": {
|
||||
"type": [
|
||||
"number",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": {
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"boolean"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"then": {
|
||||
"properties": {
|
||||
"default": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": {
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"array"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"then": {
|
||||
"properties": {
|
||||
"default": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "array"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"include_item": {
|
||||
"oneOf": [
|
||||
{
|
||||
|
|
@ -1760,8 +1920,59 @@
|
|||
"default": false
|
||||
},
|
||||
"inputs": {
|
||||
"markdownDescription": "Used to pass input values to included templates or components. [Learn More](https://docs.gitlab.com/ee/ci/yaml/inputs.html#set-input-values-when-using-include).",
|
||||
"type": "object"
|
||||
"markdownDescription": "Used to pass input values to included templates, components, downstream pipelines, or child pipelines. [Learn More](https://docs.gitlab.com/ee/ci/yaml/inputs.html).",
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"^[a-zA-Z0-9_-]+$": {
|
||||
"description": "Input parameter value that matches parameter names defined in spec:inputs of the included configuration.",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"maxLength": 1024
|
||||
},
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"job": {
|
||||
"allOf": [
|
||||
|
|
|
|||
|
|
@ -9,24 +9,20 @@ import {
|
|||
I18N_ERROR_MESSAGE,
|
||||
} from './constants';
|
||||
|
||||
export const initJwtCiCdJobTokenEnabledToggle = () => {
|
||||
const toggle = () => {
|
||||
const toggleButton = document.querySelector('.js-jwt-ci-cd-job-token-enabled-toggle button');
|
||||
|
||||
toggleButton.click();
|
||||
};
|
||||
|
||||
export const initSettingsToggles = () => {
|
||||
let toastMessage = {};
|
||||
const displayToast = (message, options = {}) => {
|
||||
toastMessage.hide?.();
|
||||
toastMessage = toast(message, options);
|
||||
};
|
||||
|
||||
const el = document.querySelector('.js-jwt-ci-cd-job-token-enabled-toggle');
|
||||
const input = document.querySelector('.js-jwt-ci-cd-job-token-enabled-input');
|
||||
const elements = document.querySelectorAll('.js-setting-toggle');
|
||||
if (!elements.length) return null;
|
||||
|
||||
if (el && input) {
|
||||
return Array.from(elements).map((el) => {
|
||||
const form = el.closest('form');
|
||||
const input = form.querySelector('.js-setting-input');
|
||||
const toggleButton = el.querySelector('button');
|
||||
const toggleElement = initToggle(el);
|
||||
|
||||
toggleElement.$on('change', async (isEnabled) => {
|
||||
|
|
@ -43,7 +39,7 @@ export const initJwtCiCdJobTokenEnabledToggle = () => {
|
|||
displayToast(I18N_SUCCESS_MESSAGE, {
|
||||
action: {
|
||||
text: I18N_UNDO_ACTION_TEXT,
|
||||
onClick: toggle,
|
||||
onClick: () => toggleButton.click(),
|
||||
},
|
||||
});
|
||||
} catch (_) {
|
||||
|
|
@ -53,7 +49,7 @@ export const initJwtCiCdJobTokenEnabledToggle = () => {
|
|||
displayToast(I18N_ERROR_MESSAGE, {
|
||||
action: {
|
||||
text: I18N_RETRY_ACTION_TEXT,
|
||||
onClick: toggle,
|
||||
onClick: () => toggleButton.click(),
|
||||
},
|
||||
});
|
||||
} finally {
|
||||
|
|
@ -62,7 +58,5 @@ export const initJwtCiCdJobTokenEnabledToggle = () => {
|
|||
});
|
||||
|
||||
return toggleElement;
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
};
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import initStaleRunnerCleanupSetting from 'ee_else_ce/group_settings/stale_runner_cleanup';
|
||||
import { initAllowRunnerRegistrationTokenToggle } from '~/group_settings/allow_runner_registration_token_toggle';
|
||||
import { initJwtCiCdJobTokenEnabledToggle } from '~/group_settings/jwt_ci_cd_job_token_enabled_toggle';
|
||||
import { initSettingsToggles } from '~/group_settings/settings_toggles';
|
||||
|
||||
import initPipelineVariablesDefaultRole from '~/group_settings/pipeline_variables_default_role';
|
||||
import initVariableList from '~/ci/ci_variable_list';
|
||||
|
|
@ -12,7 +12,7 @@ import initDeployTokens from '~/deploy_tokens';
|
|||
initSettingsPanels();
|
||||
initDeployTokens();
|
||||
initAllowRunnerRegistrationTokenToggle();
|
||||
initJwtCiCdJobTokenEnabledToggle();
|
||||
initSettingsToggles();
|
||||
initSharedRunnersForm();
|
||||
initStaleRunnerCleanupSetting();
|
||||
initVariableList();
|
||||
|
|
|
|||
|
|
@ -98,7 +98,8 @@ module Groups
|
|||
params.require(:group).permit(
|
||||
:max_artifacts_size,
|
||||
:allow_runner_registration_token,
|
||||
:jwt_ci_cd_job_token_enabled
|
||||
:jwt_ci_cd_job_token_enabled,
|
||||
:job_token_policies_enabled
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ class Projects::JobsController < Projects::ApplicationController
|
|||
include ContinueParams
|
||||
include ProjectStatsRefreshConflictsGuard
|
||||
|
||||
urgency :low, [:index, :show, :trace, :retry, :play, :cancel, :unschedule, :erase, :viewer, :raw, :test_report_summary]
|
||||
urgency :low,
|
||||
[:index, :show, :trace, :retry, :play, :cancel, :unschedule, :erase, :viewer, :raw, :test_report_summary]
|
||||
|
||||
before_action :find_job_as_build, except: [:index, :play, :retry, :show]
|
||||
before_action :find_job_as_processable, only: [:play, :retry, :show]
|
||||
|
|
@ -149,7 +150,8 @@ class Projects::JobsController < Projects::ApplicationController
|
|||
def raw
|
||||
if @build.trace.archived?
|
||||
workhorse_set_content_type!
|
||||
send_upload(@build.job_artifacts_trace.file, send_params: raw_send_params, redirect_params: raw_redirect_params, proxy: params[:proxy])
|
||||
send_upload(@build.job_artifacts_trace.file, send_params: raw_send_params, redirect_params: raw_redirect_params,
|
||||
proxy: params[:proxy])
|
||||
else
|
||||
@build.trace.read do |stream|
|
||||
if stream.file?
|
||||
|
|
@ -161,7 +163,8 @@ class Projects::JobsController < Projects::ApplicationController
|
|||
# to the user but, because we have the trace content, we can calculate
|
||||
# the proper content type and disposition here.
|
||||
raw_data = stream.raw
|
||||
send_data raw_data, type: 'text/plain; charset=utf-8', disposition: raw_trace_content_disposition(raw_data), filename: 'job.log'
|
||||
send_data raw_data, type: 'text/plain; charset=utf-8', disposition: raw_trace_content_disposition(raw_data),
|
||||
filename: 'job.log'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -148,7 +148,8 @@ class Projects::LabelsController < Projects::ApplicationController
|
|||
end
|
||||
|
||||
def flash_notice_for(label, group)
|
||||
''.html_safe + "#{label.title} promoted to " + view_context.link_to('<u>group label</u>'.html_safe, group_labels_path(group)) + '.'
|
||||
safe_link = view_context.link_to('<u>group label</u>'.html_safe, group_labels_path(group))
|
||||
view_context.safe_join([ERB::Util.html_escape(label.title), " promoted to ", safe_link, "."])
|
||||
end
|
||||
|
||||
protected
|
||||
|
|
|
|||
|
|
@ -131,7 +131,8 @@ class Projects::MilestonesController < Projects::ApplicationController
|
|||
end
|
||||
|
||||
def flash_notice_for(milestone, group)
|
||||
''.html_safe + "#{milestone.title} promoted to " + view_context.link_to('<u>group milestone</u>'.html_safe, group_milestone_path(group, milestone.iid)) + '.'
|
||||
safe_link = view_context.link_to('<u>group milestone</u>'.html_safe, group_milestone_path(group, milestone.iid))
|
||||
view_context.safe_join([ERB::Util.html_escape(milestone.title), " promoted to ", safe_link, "."])
|
||||
end
|
||||
|
||||
def destroy
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ module Mutations
|
|||
:extensions_marketplace_opt_in_status,
|
||||
:organization_groups_projects_display,
|
||||
:visibility_pipeline_id_type,
|
||||
:use_work_items_view
|
||||
:use_work_items_view,
|
||||
:merge_request_dashboard_list_type
|
||||
].freeze
|
||||
|
||||
argument :extensions_marketplace_opt_in_status, Types::ExtensionsMarketplaceOptInStatusEnum,
|
||||
|
|
@ -18,6 +19,9 @@ module Mutations
|
|||
argument :issues_sort, Types::IssueSortEnum,
|
||||
required: false,
|
||||
description: 'Sort order for issue lists.'
|
||||
argument :merge_request_dashboard_list_type, Types::MergeRequests::DashboardListTypeEnum,
|
||||
required: false,
|
||||
description: 'Merge request dashboard list rendering type.'
|
||||
argument :merge_requests_sort, Types::MergeRequestSortEnum,
|
||||
required: false,
|
||||
description: 'Sort order for issue lists.'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Types
|
||||
module MergeRequests
|
||||
class DashboardListTypeEnum < BaseEnum
|
||||
graphql_name 'MergeRequestsDashboardListType'
|
||||
description 'Values for merge request dashboard list type'
|
||||
|
||||
value 'ACTION_BASED', 'Action based list rendering.', value: 'action_based'
|
||||
value 'ROLE_BASED', 'Role based list rendering.', value: 'role_based'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -25,6 +25,10 @@ module Types
|
|||
description: 'Use work item view instead of legacy issue view.',
|
||||
null: true
|
||||
|
||||
field :merge_request_dashboard_list_type, Types::MergeRequests::DashboardListTypeEnum,
|
||||
description: 'Merge request dashboard list rendering type.',
|
||||
null: true
|
||||
|
||||
field :projects_sort,
|
||||
Types::Projects::ProjectSortEnum,
|
||||
description: 'Sort order for projects.',
|
||||
|
|
|
|||
|
|
@ -67,8 +67,9 @@ module Ci
|
|||
origin_project_id = authorizations[:origin_project_id]
|
||||
return unless accessed_project_id && origin_project_id
|
||||
|
||||
policies = authorizations.fetch(:policies, []).map(&:to_s)
|
||||
Ci::JobToken::LogAuthorizationWorker # rubocop:disable CodeReuse/Worker -- This method is called from a middleware and it's better tested
|
||||
.perform_in(CAPTURE_DELAY, accessed_project_id, origin_project_id)
|
||||
.perform_in(CAPTURE_DELAY, accessed_project_id, origin_project_id, policies)
|
||||
end
|
||||
|
||||
def self.log_captures!(accessed_project_id:, origin_project_id:, policies: [])
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ module CrossDatabaseModification
|
|||
].freeze
|
||||
|
||||
def self.logger
|
||||
@logger ||= Logger.new(LOG_FILENAME, formatter: ->(_, _, _, msg) { Gitlab::Json.dump(msg) + "\n" })
|
||||
@logger ||= Logger.new(LOG_FILENAME, formatter: ->(_, _, _, msg) { "#{Gitlab::Json.dump(msg)}\n" })
|
||||
end
|
||||
|
||||
def self.log_gitlab_transactions_stack(action: nil, example: nil)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ module FromSetOperator
|
|||
# of UNION, INTERSECT, and EXCEPT as defined by Gitlab::SQL::Union,
|
||||
# Gitlab::SQL::Intersect, and Gitlab::SQL::Except respectively.
|
||||
def define_set_operator(operator)
|
||||
method_name = 'from_' + operator.name.demodulize.downcase
|
||||
method_name = "from_#{operator.name.demodulize.downcase}"
|
||||
method_name = method_name.to_sym
|
||||
|
||||
raise "Trying to redefine method '#{method(method_name)}'" if methods.include?(method_name)
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ module Routable
|
|||
|
||||
def build_full_path
|
||||
if parent && path
|
||||
parent.full_path + '/' + path
|
||||
"#{parent.full_path}/#{path}"
|
||||
else
|
||||
path
|
||||
end
|
||||
|
|
@ -191,7 +191,7 @@ module Routable
|
|||
|
||||
def build_full_name
|
||||
if parent && name
|
||||
parent.human_name + ' / ' + name
|
||||
"#{parent.human_name} / #{name}"
|
||||
else
|
||||
name
|
||||
end
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ module Integrations
|
|||
private
|
||||
|
||||
def format_title(title)
|
||||
'*' + strip_markup(title.lines.first.chomp) + '*'
|
||||
"*#{strip_markup(title.lines.first.chomp)}*"
|
||||
end
|
||||
|
||||
def message
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ module Integrations
|
|||
|
||||
def activity
|
||||
{
|
||||
title: "#{strip_markup(user_combined_name)} #{link('commented on ' + target, note_url)}",
|
||||
title: "#{strip_markup(user_combined_name)} #{link("commented on #{target}", note_url)}",
|
||||
subtitle: "in #{project_link}",
|
||||
text: strip_markup(formatted_title),
|
||||
image: user_avatar
|
||||
|
|
@ -45,7 +45,7 @@ module Integrations
|
|||
private
|
||||
|
||||
def message
|
||||
"#{strip_markup(user_combined_name)} #{link('commented on ' + target, note_url)} in #{project_link}: *#{strip_markup(formatted_title)}*"
|
||||
"#{strip_markup(user_combined_name)} #{link("commented on #{target}", note_url)} in #{project_link}: *#{strip_markup(formatted_title)}*"
|
||||
end
|
||||
|
||||
def format_title(title)
|
||||
|
|
|
|||
|
|
@ -198,7 +198,9 @@ class Namespace < ApplicationRecord
|
|||
:resource_access_token_notify_inherited_locked_by_ancestor?,
|
||||
:resource_access_token_notify_inherited_locked_by_application_setting?,
|
||||
to: :namespace_settings
|
||||
delegate :jwt_ci_cd_job_token_enabled?, to: :namespace_settings
|
||||
delegate :jwt_ci_cd_job_token_enabled?,
|
||||
:job_token_policies_enabled?,
|
||||
to: :namespace_settings
|
||||
|
||||
before_create :sync_share_with_group_lock_with_parent
|
||||
before_update :sync_share_with_group_lock_with_parent, if: :parent_changed?
|
||||
|
|
@ -571,7 +573,7 @@ class Namespace < ApplicationRecord
|
|||
path_before_last_save
|
||||
else
|
||||
previous_parent = Group.find_by(id: parent_id_before_last_save)
|
||||
previous_parent.full_path + '/' + path_before_last_save
|
||||
"#{previous_parent.full_path}/#{path_before_last_save}"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ class NamespaceSetting < ApplicationRecord
|
|||
math_rendering_limits_enabled
|
||||
lock_math_rendering_limits_enabled
|
||||
jwt_ci_cd_job_token_enabled
|
||||
job_token_policies_enabled
|
||||
].freeze
|
||||
|
||||
# matches the size set in the database constraint
|
||||
|
|
|
|||
|
|
@ -3486,7 +3486,8 @@ class Project < ApplicationRecord
|
|||
end
|
||||
|
||||
def job_token_policies_enabled?
|
||||
Feature.enabled?(:add_policies_to_ci_job_token, self)
|
||||
Feature.enabled?(:add_policies_to_ci_job_token, self) ||
|
||||
namespace.root_ancestor.namespace_settings&.job_token_policies_enabled?
|
||||
end
|
||||
strong_memoize_attr :job_token_policies_enabled?
|
||||
|
||||
|
|
|
|||
|
|
@ -63,6 +63,16 @@ class Upload < ApplicationRecord
|
|||
store_class.new.delete_keys_async(keys)
|
||||
end
|
||||
end
|
||||
|
||||
def destroy_for_associations!(records, uploader = AttachmentUploader)
|
||||
return if records.blank?
|
||||
|
||||
for_model_type_and_id(records.klass, records.pluck_primary_key)
|
||||
.for_uploader(uploader)
|
||||
.then { |uploads| [uploads, uploads.begin_fast_destroy] }
|
||||
.tap { |uploads, _| uploads.delete_all }
|
||||
.tap { |_, files| finalize_fast_destroy(files) }
|
||||
end
|
||||
end
|
||||
|
||||
def absolute_path
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ module Uploads
|
|||
|
||||
def delete_keys_async(keys_to_delete)
|
||||
keys_to_delete.each_slice(BATCH_SIZE) do |batch|
|
||||
DeleteStoredFilesWorker.perform_async(self.class, batch)
|
||||
DeleteStoredFilesWorker.perform_async(self.class.name, batch)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -463,6 +463,7 @@ class User < ApplicationRecord
|
|||
:use_work_items_view, :use_work_items_view=,
|
||||
:text_editor, :text_editor=,
|
||||
:default_text_editor_enabled, :default_text_editor_enabled=,
|
||||
:merge_request_dashboard_list_type, :merge_request_dashboard_list_type=,
|
||||
to: :user_preference
|
||||
|
||||
delegate :path, to: :namespace, allow_nil: true, prefix: true
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@ class UserPreference < ApplicationRecord
|
|||
enum :extensions_marketplace_opt_in_status, Enums::WebIde::ExtensionsMarketplaceOptInStatus.statuses
|
||||
enum :organization_groups_projects_display, { projects: 0, groups: 1 }
|
||||
|
||||
enum :merge_request_dashboard_list_type, { action_based: 0, role_based: 1 }
|
||||
|
||||
class << self
|
||||
def notes_filters
|
||||
{
|
||||
|
|
|
|||
|
|
@ -39,6 +39,10 @@ module NamespaceSettings
|
|||
param_key: :enabled_git_access_protocol,
|
||||
user_policy: :update_git_access_protocol
|
||||
)
|
||||
validate_settings_param_for_root_group(
|
||||
param_key: :job_token_policies_enabled,
|
||||
user_policy: :admin_group
|
||||
)
|
||||
|
||||
handle_default_branch_name
|
||||
handle_default_branch_protection unless settings_params[:default_branch_protection].blank?
|
||||
|
|
|
|||
|
|
@ -18,8 +18,19 @@
|
|||
= link_to _('Learn more.'), help_page_path('ci/jobs/ci_job_token.md', anchor: 'use-legacy-format-for-cicd-tokens'), target: '_blank', rel: 'noopener noreferrer'
|
||||
.gl-mb-5
|
||||
= gitlab_ui_form_for group, url: group_settings_ci_cd_path(group, anchor: 'js-general-pipeline-settings') do |f|
|
||||
= f.hidden_field :jwt_ci_cd_job_token_enabled, class: 'js-jwt-ci-cd-job-token-enabled-input', value: group.jwt_ci_cd_job_token_enabled?
|
||||
= render Pajamas::ToggleComponent.new(classes: 'js-jwt-ci-cd-job-token-enabled-toggle',
|
||||
= f.hidden_field :jwt_ci_cd_job_token_enabled, class: 'js-setting-input', value: group.jwt_ci_cd_job_token_enabled?
|
||||
= render Pajamas::ToggleComponent.new(classes: 'js-setting-toggle',
|
||||
label: s_('GroupSettings|Enable JWT format for CI/CD job tokens'),
|
||||
is_checked: group.jwt_ci_cd_job_token_enabled?) do
|
||||
= s_('GroupSettings|Enable JWT format for the CI_JOB_TOKEN variable. When disabled, it uses the legacy database format.')
|
||||
.gl-mb-5
|
||||
= gitlab_ui_form_for group, url: group_settings_ci_cd_path(group, anchor: 'js-general-pipeline-settings') do |f|
|
||||
%span.gl-toggle-label.gl-shrink-0= s_('GroupSettings|Enable fine-grained permissions for CI/CD job tokens')
|
||||
%span= render_if_exists 'shared/experimental_badge_tag'
|
||||
= f.hidden_field :job_token_policies_enabled, class: 'js-setting-input', value: group.job_token_policies_enabled?
|
||||
= render Pajamas::ToggleComponent.new(classes: 'js-setting-toggle gl-mt-3',
|
||||
label: s_('GroupSettings|Enable fine-grained permissions for CI/CD job tokens'),
|
||||
label_position: :hidden,
|
||||
is_checked: group.job_token_policies_enabled?) do
|
||||
= s_('GroupSettings|Enable fine-grained permissions for CI/CD job tokens.')
|
||||
= link_to _('Learn more.'), help_page_path('ci/jobs/fine_grained_permissions.md'), target: '_blank', rel: 'noopener noreferrer'
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
---
|
||||
name: label_keep_around_ref_metrics
|
||||
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/383814
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/145988
|
||||
rollout_issue_url:
|
||||
milestone: '16.10'
|
||||
group: group::gitaly::git
|
||||
type: ops
|
||||
default_enabled: false
|
||||
|
|
@ -1000,6 +1000,9 @@ Gitlab.ee do
|
|||
Settings.cron_jobs['analytics_dump_ai_user_metrics_database_write_buffer_cron_worker'] ||= {}
|
||||
Settings.cron_jobs['analytics_dump_ai_user_metrics_database_write_buffer_cron_worker']['cron'] ||= "*/10 * * * *"
|
||||
Settings.cron_jobs['analytics_dump_ai_user_metrics_database_write_buffer_cron_worker']['job_class'] = 'Analytics::DumpAiUserMetricsWriteBufferCronWorker'
|
||||
Settings.cron_jobs['delete_expired_vulnerability_exports_worker'] ||= {}
|
||||
Settings.cron_jobs['delete_expired_vulnerability_exports_worker']['cron'] ||= '0 4 * * *'
|
||||
Settings.cron_jobs['delete_expired_vulnerability_exports_worker']['job_class'] = 'Vulnerabilities::DeleteExpiredExportsWorker'
|
||||
|
||||
Gitlab.com do
|
||||
Settings.cron_jobs['disable_legacy_open_source_license_for_inactive_projects'] ||= {}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddMergeRequestDashboardListTypeToUserPreferences < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.11'
|
||||
|
||||
def change
|
||||
add_column :user_preferences, :merge_request_dashboard_list_type, :smallint, default: 0, null: false
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddJobTokenPoliciesEnabledColumnToNamespaceSettings < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.11'
|
||||
enable_lock_retries!
|
||||
|
||||
def change
|
||||
add_column :namespace_settings, :job_token_policies_enabled, :boolean, default: false, null: false
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
821adcb681f8c7618ce7560acb7dfbc36b0004ba6cd9144e76f761536bc574fa
|
||||
|
|
@ -0,0 +1 @@
|
|||
968664b5b33cf194f36a9ba5b28490471405e94272c64668264ec0c11d22a672
|
||||
|
|
@ -17475,6 +17475,7 @@ CREATE TABLE namespace_settings (
|
|||
jwt_ci_cd_job_token_enabled boolean DEFAULT false NOT NULL,
|
||||
jwt_ci_cd_job_token_opted_out boolean DEFAULT false NOT NULL,
|
||||
require_dpop_for_manage_api_endpoints boolean DEFAULT true NOT NULL,
|
||||
job_token_policies_enabled boolean DEFAULT false NOT NULL,
|
||||
CONSTRAINT check_0ba93c78c7 CHECK ((char_length(default_branch_name) <= 255)),
|
||||
CONSTRAINT namespace_settings_unique_project_download_limit_alertlist_size CHECK ((cardinality(unique_project_download_limit_alertlist) <= 100)),
|
||||
CONSTRAINT namespace_settings_unique_project_download_limit_allowlist_size CHECK ((cardinality(unique_project_download_limit_allowlist) <= 100))
|
||||
|
|
@ -23498,6 +23499,7 @@ CREATE TABLE user_preferences (
|
|||
dpop_enabled boolean DEFAULT false NOT NULL,
|
||||
use_work_items_view boolean DEFAULT false NOT NULL,
|
||||
text_editor_type smallint DEFAULT 0 NOT NULL,
|
||||
merge_request_dashboard_list_type smallint DEFAULT 0 NOT NULL,
|
||||
CONSTRAINT check_1d670edc68 CHECK ((time_display_relative IS NOT NULL)),
|
||||
CONSTRAINT check_89bf269f41 CHECK ((char_length(diffs_deletion_color) <= 7)),
|
||||
CONSTRAINT check_b1306f8875 CHECK ((char_length(organization_groups_projects_sort) <= 64)),
|
||||
|
|
|
|||
|
|
@ -59,10 +59,10 @@ The following table lists the GitLab Duo features, and whether they are availabl
|
|||
| [Refactor Code](../../user/gitlab_duo_chat/examples.md#refactor-code-in-the-ide) | {{< icon name="check-circle-filled" >}} Yes | GitLab 17.9 and later |
|
||||
| [Fix Code](../../user/gitlab_duo_chat/examples.md#fix-code-in-the-ide) | {{< icon name="check-circle-filled" >}} Yes | GitLab 17.9 and later |
|
||||
| [AI Impact Dashboard](../../user/analytics/ai_impact_analytics.md) | {{< icon name="check-circle-dashed" >}} Beta | GitLab 17.9 and later |
|
||||
| [Root Cause Analysis](../../user/gitlab_duo_chat/examples.md#troubleshoot-failed-cicd-jobs-with-root-cause-analysis) | {{< icon name="check-circle-dashed" >}} Beta | GitLab 17.10 and later |
|
||||
| [Discussion Summary](../../user/discussions/_index.md#summarize-issue-discussions-with-duo-chat) | {{< icon name="dash-circle" >}} No | Not applicable |
|
||||
| [GitLab Duo for the CLI](../../editor_extensions/gitlab_cli/_index.md#gitlab-duo-for-the-cli) | {{< icon name="dash-circle" >}} No | Not applicable |
|
||||
| [Merge Commit Message Generation](../../user/project/merge_requests/duo_in_merge_requests.md#generate-a-merge-commit-message) | {{< icon name="dash-circle" >}} No | Not applicable |
|
||||
| [Root Cause Analysis](../../user/gitlab_duo_chat/examples.md#troubleshoot-failed-cicd-jobs-with-root-cause-analysis) | {{< icon name="dash-circle" >}} No | Not applicable |
|
||||
| [Vulnerability Explanation](../../user/application_security/vulnerabilities/_index.md#explaining-a-vulnerability) | {{< icon name="dash-circle" >}} No | Not applicable |
|
||||
| [Vulnerability Resolution](../../user/application_security/vulnerabilities/_index.md#vulnerability-resolution) | {{< icon name="dash-circle" >}} No | Not applicable |
|
||||
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ Configure the GitLab Duo feature and sub-feature to send queries to the configur
|
|||
1. Select the **AI-powered features** tab.
|
||||
1. For the feature and sub-feature you want to configure, from the dropdown list, choose the self-hosted model you want to use.
|
||||
|
||||
For example, for the the code generation sub-feature under GitLab Duo Code Suggestions, you can select **claude sonnet on bedrock (Claude 3)**.
|
||||
For example, for the code generation sub-feature under GitLab Duo Code Suggestions, you can select **claude sonnet on bedrock (Claude 3)**.
|
||||
|
||||

|
||||
|
||||
|
|
|
|||
|
|
@ -11816,6 +11816,7 @@ Input type: `UserPreferencesUpdateInput`
|
|||
| <a id="mutationuserpreferencesupdateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
|
||||
| <a id="mutationuserpreferencesupdateextensionsmarketplaceoptinstatus"></a>`extensionsMarketplaceOptInStatus` | [`ExtensionsMarketplaceOptInStatus`](#extensionsmarketplaceoptinstatus) | Status of the Web IDE Extension Marketplace opt-in for the user. |
|
||||
| <a id="mutationuserpreferencesupdateissuessort"></a>`issuesSort` | [`IssueSort`](#issuesort) | Sort order for issue lists. |
|
||||
| <a id="mutationuserpreferencesupdatemergerequestdashboardlisttype"></a>`mergeRequestDashboardListType` | [`MergeRequestsDashboardListType`](#mergerequestsdashboardlisttype) | Merge request dashboard list rendering type. |
|
||||
| <a id="mutationuserpreferencesupdatemergerequestssort"></a>`mergeRequestsSort` | [`MergeRequestSort`](#mergerequestsort) | Sort order for issue lists. |
|
||||
| <a id="mutationuserpreferencesupdateorganizationgroupsprojectsdisplay"></a>`organizationGroupsProjectsDisplay` {{< icon name="warning-solid" >}} | [`OrganizationGroupProjectDisplay`](#organizationgroupprojectdisplay) | **Deprecated:** **Status**: Experiment. Introduced in GitLab 17.2. |
|
||||
| <a id="mutationuserpreferencesupdateorganizationgroupsprojectssort"></a>`organizationGroupsProjectsSort` {{< icon name="warning-solid" >}} | [`OrganizationGroupProjectSort`](#organizationgroupprojectsort) | **Deprecated:** **Status**: Experiment. Introduced in GitLab 17.2. |
|
||||
|
|
@ -39103,6 +39104,7 @@ fields relate to interactions between the two entities.
|
|||
| ---- | ---- | ----------- |
|
||||
| <a id="userpreferencesextensionsmarketplaceoptinstatus"></a>`extensionsMarketplaceOptInStatus` | [`ExtensionsMarketplaceOptInStatus!`](#extensionsmarketplaceoptinstatus) | Status of the Web IDE Extension Marketplace opt-in for the user. |
|
||||
| <a id="userpreferencesissuessort"></a>`issuesSort` | [`IssueSort`](#issuesort) | Sort order for issue lists. |
|
||||
| <a id="userpreferencesmergerequestdashboardlisttype"></a>`mergeRequestDashboardListType` | [`MergeRequestsDashboardListType`](#mergerequestsdashboardlisttype) | Merge request dashboard list rendering type. |
|
||||
| <a id="userpreferencesorganizationgroupsprojectsdisplay"></a>`organizationGroupsProjectsDisplay` {{< icon name="warning-solid" >}} | [`OrganizationGroupProjectDisplay!`](#organizationgroupprojectdisplay) | **Introduced** in GitLab 17.2. **Status**: Experiment. Default list view for organization groups and projects. |
|
||||
| <a id="userpreferencesorganizationgroupsprojectssort"></a>`organizationGroupsProjectsSort` {{< icon name="warning-solid" >}} | [`OrganizationGroupProjectSort`](#organizationgroupprojectsort) | **Introduced** in GitLab 17.2. **Status**: Experiment. Sort order for organization groups and projects. |
|
||||
| <a id="userpreferencesprojectssort"></a>`projectsSort` | [`ProjectSort`](#projectsort) | Sort order for projects. |
|
||||
|
|
@ -43174,6 +43176,15 @@ State of a GitLab merge request.
|
|||
| <a id="mergerequeststatemerged"></a>`merged` | Merge request has been merged. |
|
||||
| <a id="mergerequeststateopened"></a>`opened` | Opened merge request. |
|
||||
|
||||
### `MergeRequestsDashboardListType`
|
||||
|
||||
Values for merge request dashboard list type.
|
||||
|
||||
| Value | Description |
|
||||
| ----- | ----------- |
|
||||
| <a id="mergerequestsdashboardlisttypeaction_based"></a>`ACTION_BASED` | Action based list rendering. |
|
||||
| <a id="mergerequestsdashboardlisttyperole_based"></a>`ROLE_BASED` | Role based list rendering. |
|
||||
|
||||
### `MergeStatus`
|
||||
|
||||
Representation of whether a GitLab merge request can be merged.
|
||||
|
|
|
|||
|
|
@ -29,33 +29,26 @@ Status: Experiment
|
|||
|
||||
{{< /history >}}
|
||||
|
||||
{{< alert type="flag" >}}
|
||||
|
||||
The availability of this feature is controlled by a feature flag.
|
||||
For more information, see the history.
|
||||
This feature is available for testing, but not ready for production use.
|
||||
|
||||
{{< /alert >}}
|
||||
|
||||
You can use fine-grained permissions to explicitly allow access to a limited set of API endpoints.
|
||||
These permissions are applied to the CI/CD job tokens in a specified project.
|
||||
This feature is an [experiment](../../policy/development_stages_support.md#experiment).
|
||||
|
||||
## Enable fine-grained permissions
|
||||
This feature is an [experiment](../../policy/development_stages_support.md#experiment) and subject to change without notice. This feature is not ready for production use. If you want to use this feature, you should test outside of production first.
|
||||
|
||||
### On GitLab Self-Managed
|
||||
## Enable fine-grained permissions for projects
|
||||
|
||||
1. Start the GitLab Rails console. For information, see [Enable and disable GitLab features deployed behind feature flags](../../administration/feature_flags.md#enable-or-disable-the-feature)
|
||||
1. Turn on the [feature flag](../../administration/feature_flags.md):
|
||||
Prerequisites:
|
||||
|
||||
```ruby
|
||||
# You must include a specific project ID with this command.
|
||||
Feature.enable(:add_policies_to_ci_job_token, <project_id>)
|
||||
```
|
||||
- You must have the Owner role for a group.
|
||||
|
||||
### On GitLab.com
|
||||
You must turn on fine-grained permissions at the group level. Then, each project in the group can
|
||||
apply fine-grained permissions for CI/CD job tokens to grant access to individual resources.
|
||||
|
||||
Add a comment on this [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/519575) with your project ID.
|
||||
To enable fine-grained permissions for all projects in a group:
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your group.
|
||||
1. On the left sidebar, select **Settings > CI/CD**.
|
||||
1. Expand **General pipelines**.
|
||||
1. Turn on the **Enable fine-grained permissions for CI/CD job tokens** toggle.
|
||||
|
||||
## Available API endpoints
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ Please refer to [the documentation](../code_review.md#reviewer-roulette)
|
|||
|
||||
### Ask for help
|
||||
|
||||
If contributors have questions or need additional help with Python-specific reviews, direct them to the GitLab #python or #python_maintainers Slack channels for assistance.
|
||||
If contributors have questions or need additional help with Python-specific reviews, direct them to the GitLab `#python` or `#python_maintainers` Slack channels for assistance.
|
||||
|
||||
## How to find a project to review
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,8 @@ To auto-format this table, use the VS Code Markdown Table formatter: `https://do
|
|||
|
||||
| Command | Issue | Merge request | Epic | Action |
|
||||
|:------------------------------------------------------------------------------------------------|:-----------------------|:-----------------------|:-----------------------|:-------|
|
||||
| `/add_contacts [contact:email1@example.com] [contact:email2@example.com]` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Add one or more active [CRM contacts](../crm/_index.md) ([introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73413) in GitLab 14.6). |
|
||||
| `/add_child <item>` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | Add `<item>` as a child item. The `<item>` value should be in the format of `#item`, `group/project#item`, or a URL to the item. For issues, you can add tasks and OKRs. Your administrator must have [enabled the new look for issues](../project/issues/issue_work_items.md). For epics, you can add issues, tasks, and OKRs. Multiple work items can be added as child items at the same time. Your administrator must have [enabled the new look for epics](../group/epics/epic_work_items.md). |
|
||||
| `/add_contacts [contact:email1@example.com] [contact:email2@example.com]` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Add one or more active [CRM contacts](../crm/_index.md). |
|
||||
| `/add_email email1 email2` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Add up to six [email participants](service_desk/external_participants.md). This action is behind the feature flag `issue_email_participants`. Not supported in [issue templates](description_templates.md). |
|
||||
| `/approve` | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Approve the merge request. |
|
||||
| `/assign @user1 @user2` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Assign one or more users. |
|
||||
|
|
@ -110,6 +111,7 @@ To auto-format this table, use the VS Code Markdown Table formatter: `https://do
|
|||
| `/rebase` | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Rebase source branch on the latest commit of the target branch. For help, see [troubleshooting information](../../topics/git/troubleshooting_git.md). |
|
||||
| `/relabel ~label1 ~label2` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | Replace current labels with those specified. |
|
||||
| `/relate <item1> <item2>` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Mark items as related. The `<item>` value should be in the format of `#item`, `group/project#item`, or the full URL. |
|
||||
| `/remove_child <item>` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | Remove `<item>` as child. The `<item>` value should be in the format of `#item`, `group/project#item`, or a URL to the item. For issues, your administrator must have [enabled the new look for issues](../project/issues/issue_work_items.md). For epics, your administrator must have [enabled the new look for epics](../group/epics/epic_work_items.md). |
|
||||
| `/remove_child_epic <epic>` | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | Remove child epic from `<epic>`. The `<epic>` value should be in the format of `&epic`, `group&epic`, or a URL to an epic. |
|
||||
| `/remove_contacts [contact:email1@example.com] [contact:email2@example.com]` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Remove one or more [CRM contacts](../crm/_index.md) |
|
||||
| `/remove_due_date` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Remove due date. |
|
||||
|
|
@ -118,6 +120,7 @@ To auto-format this table, use the VS Code Markdown Table formatter: `https://do
|
|||
| `/remove_estimate` or `/remove_time_estimate` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Remove time estimate. Alias `/remove_time_estimate` [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/16501) in GitLab 15.6. |
|
||||
| `/remove_iteration` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Remove iteration. |
|
||||
| `/remove_milestone` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Remove milestone. |
|
||||
| `/remove_parent` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | Remove the parent from item. For issues, your administrator must have [enabled the new look for issues](../project/issues/issue_work_items.md). For epics, your administrator must have [enabled the new look for epics](../group/epics/epic_work_items.md). |
|
||||
| `/remove_parent_epic` | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | Remove parent epic from epic. |
|
||||
| `/remove_time_spent` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Remove time spent. |
|
||||
| `/remove_zoom` | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | {{< icon name="dotted-circle" >}} No | Remove Zoom meeting from this issue. |
|
||||
|
|
@ -169,7 +172,7 @@ To auto-format this table, use the VS Code Markdown Table formatter: `https://do
|
|||
|:--------------------------------------------------------------|:-----------------------|:-----------------------|:-----------------------|:-------|
|
||||
| `/assign @user1 @user2` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | Assign one or more users. |
|
||||
| `/assign me` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | Assign yourself. |
|
||||
| `/add_child <work_item>` | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Add child to `<work_item>`. The `<work_item>` value should be in the format of `#item`, `group/project#item`, or a URL to a work item. Multiple work items can be added as children at the same time. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/420797) in GitLab 16.5. |
|
||||
| `/add_child <work_item>` | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Add child to `<work_item>`. The `<work_item>` value should be in the format of `#item`, `group/project#item`, or a URL to a work item. Multiple work items can be added as child items at the same time. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/420797) in GitLab 16.5. |
|
||||
| `/award :emoji:` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | Toggle an emoji reaction. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/412275) in GitLab 16.5 |
|
||||
| `/cc @user` | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | Mention a user. In GitLab 15.0 and later, this command performs no action. You can instead type `CC @user` or only `@user`. |
|
||||
| `/checkin_reminder <cadence>` | {{< icon name="dotted-circle" >}} No| {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Schedule [check-in reminders](../okrs.md#schedule-okr-check-in-reminders). Options are `weekly`, `twice-monthly`, `monthly`, or `never` (default). [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/422761) in GitLab 16.4 with flags named `okrs_mvc` and `okr_checkin_reminders`. |
|
||||
|
|
|
|||
|
|
@ -161,6 +161,13 @@ For additional information, see [Approval rules](../../merge_requests/approvals/
|
|||
|
||||
### Edit squash commits option
|
||||
|
||||
{{< details >}}
|
||||
|
||||
- Tier: Premium, Ultimate
|
||||
- Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
|
||||
|
||||
{{< /details >}}
|
||||
|
||||
{{< history >}}
|
||||
|
||||
- [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/181370) in GitLab 17.9 with a flag named `branch_rule_squash_settings`. Disabled by default.
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ module Gitlab
|
|||
def execute(shas, source:)
|
||||
return if disabled?
|
||||
|
||||
labels = project_labels.merge(source: source)
|
||||
labels = { source: source }
|
||||
|
||||
shas.uniq.each do |sha|
|
||||
next unless sha.present? && commit_by(oid: sha)
|
||||
|
|
@ -61,17 +61,6 @@ module Gitlab
|
|||
|
||||
private
|
||||
|
||||
def project_labels
|
||||
return { full_path: '' } unless add_project_labels?
|
||||
|
||||
{ full_path: @repository.full_path }
|
||||
end
|
||||
|
||||
def add_project_labels?
|
||||
Feature.enabled?(:label_keep_around_ref_metrics, @repository, type: :ops) ||
|
||||
(@repository.project && Feature.enabled?(:label_keep_around_ref_metrics, @repository.project, type: :ops))
|
||||
end
|
||||
|
||||
def disabled?
|
||||
Feature.enabled?(:disable_keep_around_refs, @repository, type: :ops) ||
|
||||
(@repository.project && Feature.enabled?(:disable_keep_around_refs, @repository.project, type: :ops))
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ module Gitlab
|
|||
provider_arguments.concat arguments
|
||||
provider_arguments << defaults unless defaults.empty?
|
||||
when Hash, GitlabSettings::Options
|
||||
verify_saml_cert_arguments!(provider['name'], arguments)
|
||||
hash_arguments = merge_hash_defaults_and_args(defaults, arguments)
|
||||
normalized = normalize_hash_arguments(hash_arguments)
|
||||
|
||||
|
|
@ -104,6 +105,33 @@ module Gitlab
|
|||
args
|
||||
end
|
||||
|
||||
def verify_saml_cert_arguments!(provider_name, arguments)
|
||||
return arguments unless AuthHelper.saml_providers.include?(provider_name.to_sym)
|
||||
|
||||
fingerprint = arguments['idp_cert_fingerprint']
|
||||
algorithm = arguments['idp_cert_fingerprint_algorithm']
|
||||
|
||||
return arguments unless fingerprint.present? && algorithm.nil?
|
||||
|
||||
algorithm = detect_fingerprint_algorithm(fingerprint)
|
||||
|
||||
return arguments unless algorithm.present?
|
||||
|
||||
arguments['idp_cert_fingerprint_algorithm'] = algorithm
|
||||
arguments
|
||||
end
|
||||
|
||||
def detect_fingerprint_algorithm(fingerprint)
|
||||
case fingerprint.scan(/[0-9A-Fa-f]{2}/i).length
|
||||
when 20
|
||||
# v2.x will change to RubySaml::XML::SHA1
|
||||
XMLSecurity::Document::SHA1
|
||||
when 32
|
||||
# v2.x will change to RubySaml::XML::SHA256
|
||||
XMLSecurity::Document::SHA256
|
||||
end
|
||||
end
|
||||
|
||||
def provider_defaults(provider)
|
||||
self.class.default_arguments_for(provider['name'])
|
||||
end
|
||||
|
|
|
|||
|
|
@ -26213,6 +26213,9 @@ msgstr ""
|
|||
msgid "Geo|Container repositories synchronization concurrency limit"
|
||||
msgstr ""
|
||||
|
||||
msgid "Geo|Created: %{timeAgo}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Geo|Data replication lag"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -26282,6 +26285,9 @@ msgstr ""
|
|||
msgid "Geo|Go to the primary site"
|
||||
msgstr ""
|
||||
|
||||
msgid "Geo|GraphQL ID: %{id}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Geo|Groups to synchronize"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -26387,6 +26393,12 @@ msgstr ""
|
|||
msgid "Geo|Re-verification interval"
|
||||
msgstr ""
|
||||
|
||||
msgid "Geo|Registry ID: %{id}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Geo|Registry information"
|
||||
msgstr ""
|
||||
|
||||
msgid "Geo|Remove %{siteType} site"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -26396,6 +26408,9 @@ msgstr ""
|
|||
msgid "Geo|Removing a Geo site stops the synchronization to and from that site. Are you sure?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Geo|Replicable ID: %{id}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Geo|Replicated data is verified with the secondary site(s) using checksums"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -28816,6 +28831,12 @@ msgstr ""
|
|||
msgid "GroupSettings|Enable extension marketplace"
|
||||
msgstr ""
|
||||
|
||||
msgid "GroupSettings|Enable fine-grained permissions for CI/CD job tokens"
|
||||
msgstr ""
|
||||
|
||||
msgid "GroupSettings|Enable fine-grained permissions for CI/CD job tokens."
|
||||
msgstr ""
|
||||
|
||||
msgid "GroupSettings|Enable overview background aggregation for Value Streams Dashboard"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -65328,6 +65349,9 @@ msgstr ""
|
|||
msgid "Vulnerability|Scanner:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Vulnerability|Scanner: %{scannerName}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Vulnerability|Search or filter vulnerabilities..."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -12,14 +12,17 @@ class SemgrepResultProcessor
|
|||
|
||||
ALLOWED_PROJECT_DIRS = %w[/builds/gitlab-org/gitlab].freeze
|
||||
ALLOWED_API_URLS = %w[https://gitlab.com/api/v4].freeze
|
||||
|
||||
UNIQUE_COMMENT_RULES_IDS = %w[builds.sast-custom-rules.appsec-pings.glappsec_ci-job-token builds.sast-custom-rules.secure-coding-guidelines.ruby.glappsec_insecure-regex].freeze
|
||||
# Remove this when the feature is fully working
|
||||
APPSEC_HANDLE = "@gitlab-com/gl-security/appsec"
|
||||
|
||||
MESSAGE_SCG_PING_APPSEC = "#{APPSEC_HANDLE} please review this finding, which is a potential violation of [GitLab's secure coding guidelines](https://docs.gitlab.com/development/secure_coding_guidelines/).".freeze
|
||||
MESSAGE_S1_PING_APPSEC = "#{APPSEC_HANDLE} please review this finding. This MR potentially reintroduces code from a past S1 issue.".freeze
|
||||
|
||||
MESSAGE_FOOTER = <<~FOOTER
|
||||
|
||||
|
||||
<small>
|
||||
This AppSec automation is currently under testing.
|
||||
This automation belongs to AppSec.
|
||||
Use ~"appsec-sast::helpful" or ~"appsec-sast::unhelpful" for quick feedback.
|
||||
To stop the bot from further commenting, you can use the ~"appsec-sast::stop" label.
|
||||
For any detailed feedback, [add a comment here](https://gitlab.com/gitlab-com/gl-security/product-security/appsec/sast-custom-rules/-/issues/38).
|
||||
|
|
@ -132,8 +135,18 @@ class SemgrepResultProcessor
|
|||
message_header = "<!-- #{header_information} -->"
|
||||
new_line = finding[:line]
|
||||
message = finding[:message]
|
||||
check_id = finding[:check_id]
|
||||
uri = URI.parse("#{ENV['CI_API_V4_URL']}/projects/#{ENV['CI_MERGE_REQUEST_PROJECT_ID']}/merge_requests/#{ENV['CI_MERGE_REQUEST_IID']}/discussions")
|
||||
message_from_bot = "#{message_header}\n#{message}\n#{MESSAGE_FOOTER}"
|
||||
suffix = if check_id&.start_with?("builds.sast-custom-rules.secure-coding-guidelines")
|
||||
"\n#{MESSAGE_SCG_PING_APPSEC}"
|
||||
elsif check_id&.start_with?("builds.sast-custom-rules.s1")
|
||||
"\n#{MESSAGE_S1_PING_APPSEC}"
|
||||
else
|
||||
""
|
||||
end
|
||||
|
||||
message_from_bot = "#{message_header}\n#{message}#{suffix}\n#{MESSAGE_FOOTER}"
|
||||
|
||||
request = Net::HTTP::Post.new(uri)
|
||||
request["PRIVATE-TOKEN"] = ENV['CUSTOM_SAST_RULES_BOT_PAT']
|
||||
request.set_form_data(
|
||||
|
|
|
|||
|
|
@ -543,27 +543,29 @@ function log_disk_usage() {
|
|||
|
||||
# all functions below are for customizing CI job exit code
|
||||
function run_with_custom_exit_code() {
|
||||
set -o pipefail # Take the exit status of the rightmost command that failed
|
||||
set +e # temporarily disable exit on error to prevent premature exit
|
||||
"$@"
|
||||
|
||||
local trace_file="/tmp/stdout_stderr_log.out"
|
||||
|
||||
# Run the command and tee output to both the terminal and the file
|
||||
"$@" 2>&1 | tee "$trace_file"
|
||||
initial_exit_code=$?
|
||||
|
||||
echo "initial_exit_code: $initial_exit_code"
|
||||
# set -o pipefail # Take the exit status of the rightmost command that failed
|
||||
# set +e # temporarily disable exit on error to prevent premature exit
|
||||
|
||||
find_custom_exit_code "$initial_exit_code" "$trace_file"
|
||||
new_exit_code=$?
|
||||
# local trace_file="/tmp/stdout_stderr_log.out"
|
||||
|
||||
echo "new_exit_code=$new_exit_code"
|
||||
# # Run the command and tee output to both the terminal and the file
|
||||
# "$@" 2>&1 | tee "$trace_file"
|
||||
# initial_exit_code=$?
|
||||
|
||||
# Restore shell default behavior
|
||||
set -e
|
||||
set +o pipefail
|
||||
# echo "initial_exit_code: $initial_exit_code"
|
||||
|
||||
exit "$new_exit_code"
|
||||
# find_custom_exit_code "$initial_exit_code" "$trace_file"
|
||||
# new_exit_code=$?
|
||||
|
||||
# echo "new_exit_code=$new_exit_code"
|
||||
|
||||
# # Restore shell default behavior
|
||||
# set -e
|
||||
# set +o pipefail
|
||||
|
||||
# exit "$new_exit_code"
|
||||
}
|
||||
|
||||
function find_custom_exit_code() {
|
||||
|
|
|
|||
|
|
@ -175,6 +175,15 @@ RSpec.describe Groups::Settings::CiCdController, feature_category: :continuous_i
|
|||
.from(false).to(true)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when updating `job_token_policies_enabled`' do
|
||||
let(:params) { { group_id: group, group: { job_token_policies_enabled: true } } }
|
||||
|
||||
it 'can update `job_token_policies_enabled`' do
|
||||
expect { perform_request }.to change { group.reload.namespace_settings.job_token_policies_enabled }
|
||||
.from(false).to(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is a group maintainer' do
|
||||
|
|
@ -199,6 +208,16 @@ RSpec.describe Groups::Settings::CiCdController, feature_category: :continuous_i
|
|||
expect(response).to have_gitlab_http_status(:not_found)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when updating `job_token_policies_enabled`' do
|
||||
let(:params) { { group_id: group, group: { job_token_policies_enabled: true } } }
|
||||
|
||||
it 'cannot update `job_token_policies_enabled`' do
|
||||
expect { perform_request }.not_to change { group.reload.namespace_settings.job_token_policies_enabled }
|
||||
|
||||
expect(response).to have_gitlab_http_status(:not_found)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is an admin' do
|
||||
|
|
@ -227,6 +246,15 @@ RSpec.describe Groups::Settings::CiCdController, feature_category: :continuous_i
|
|||
.from(false).to(true)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when updating `job_token_policies_enabled`' do
|
||||
let(:params) { { group_id: group, group: { job_token_policies_enabled: true } } }
|
||||
|
||||
it 'can update `job_token_policies_enabled`' do
|
||||
expect { perform_request }.to change { group.reload.namespace_settings.job_token_policies_enabled }
|
||||
.from(false).to(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when admin mode is enabled', :enable_admin_mode do
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import RulesYaml from './yaml_tests/positive_tests/rules.yml';
|
|||
import RulesNeedsYaml from './yaml_tests/positive_tests/rules_needs.yml';
|
||||
import RunYaml from './yaml_tests/positive_tests/run.yml';
|
||||
import ProjectPathYaml from './yaml_tests/positive_tests/project_path.yml';
|
||||
import SpecInputsYaml from './yaml_tests/positive_tests/spec_inputs.yml';
|
||||
import VariablesYaml from './yaml_tests/positive_tests/variables.yml';
|
||||
import JobWhenYaml from './yaml_tests/positive_tests/job_when.yml';
|
||||
import IdTokensYaml from './yaml_tests/positive_tests/id_tokens.yml';
|
||||
|
|
@ -63,6 +64,7 @@ import ProjectPathIncludeTailSlashYaml from './yaml_tests/negative_tests/project
|
|||
import RulesNegativeYaml from './yaml_tests/negative_tests/rules.yml';
|
||||
import RulesNeedsNegativeYaml from './yaml_tests/negative_tests/rules_needs.yml';
|
||||
import RunNegativeYaml from './yaml_tests/negative_tests/run.yml';
|
||||
import SpecInputsNegativeYaml from './yaml_tests/negative_tests/spec_inputs.yml';
|
||||
import TriggerNegativeYaml from './yaml_tests/negative_tests/trigger.yml';
|
||||
import VariablesInvalidOptionsYaml from './yaml_tests/negative_tests/variables/invalid_options.yml';
|
||||
import VariablesInvalidSyntaxDescYaml from './yaml_tests/negative_tests/variables/invalid_syntax_desc.yml';
|
||||
|
|
@ -113,25 +115,26 @@ describe('positive tests', () => {
|
|||
CacheYaml,
|
||||
MultipleCachesYaml,
|
||||
FilterYaml,
|
||||
HooksYaml,
|
||||
IdTokensYaml,
|
||||
IncludeYaml,
|
||||
JobWhenYaml,
|
||||
HooksYaml,
|
||||
NeedsParallelMatrixYaml,
|
||||
ParallelYaml,
|
||||
ProjectPathYaml,
|
||||
RetryYaml,
|
||||
RulesYaml,
|
||||
RulesNeedsYaml,
|
||||
RunYaml,
|
||||
VariablesYaml,
|
||||
ProjectPathYaml,
|
||||
IdTokensYaml,
|
||||
ServicesYaml,
|
||||
SecretsYaml,
|
||||
NeedsParallelMatrixYaml,
|
||||
ScriptYaml,
|
||||
SecretsYaml,
|
||||
ServicesYaml,
|
||||
SpecInputsYaml,
|
||||
StagesYaml,
|
||||
TriggerYaml,
|
||||
VariablesYaml,
|
||||
WorkflowRulesAutoCancelOnJobFailureYaml,
|
||||
WorkflowRulesAutoCancelOnNewCommitYaml,
|
||||
StagesYaml,
|
||||
RetryYaml,
|
||||
ParallelYaml,
|
||||
TriggerYaml,
|
||||
}),
|
||||
)('schema validates %s', (_, input) => {
|
||||
// We construct a new "JSON" from each main key that is inside a
|
||||
|
|
@ -170,43 +173,44 @@ describe('negative tests', () => {
|
|||
Object.entries({
|
||||
// JSON
|
||||
DefaultNoAdditionalPropertiesJson,
|
||||
JobVariablesMustNotContainObjectsJson,
|
||||
InheritDefaultNoAdditionalPropertiesJson,
|
||||
JobVariablesMustNotContainObjectsJson,
|
||||
ReleaseAssetsLinksJson,
|
||||
RetryUnknownWhenJson,
|
||||
|
||||
// YAML
|
||||
ArtifactsNegativeYaml,
|
||||
ImageNegativeYaml,
|
||||
CacheKeyNeative,
|
||||
MultipleCachesYamlNegative,
|
||||
HooksNegative,
|
||||
IdTokensNegativeYaml,
|
||||
ImageNegativeYaml,
|
||||
IncludeNegativeYaml,
|
||||
JobWhenNegativeYaml,
|
||||
RulesNegativeYaml,
|
||||
RulesNeedsNegativeYaml,
|
||||
RunNegativeYaml,
|
||||
TriggerNegativeYaml,
|
||||
VariablesInvalidOptionsYaml,
|
||||
VariablesInvalidSyntaxDescYaml,
|
||||
VariablesWrongSyntaxUsageExpand,
|
||||
MultipleCachesYamlNegative,
|
||||
NeedsParallelMatrixNumericYaml,
|
||||
NeedsParallelMatrixWrongMatrixValueYaml,
|
||||
NeedsParallelMatrixWrongParallelValueYaml,
|
||||
ParallelNegativeYaml,
|
||||
ProjectPathIncludeEmptyYaml,
|
||||
ProjectPathIncludeInvalidVariableYaml,
|
||||
ProjectPathIncludeLeadSlashYaml,
|
||||
ProjectPathIncludeNoSlashYaml,
|
||||
ProjectPathIncludeTailSlashYaml,
|
||||
RetryNegativeYaml,
|
||||
RulesNeedsNegativeYaml,
|
||||
RulesNegativeYaml,
|
||||
RunNegativeYaml,
|
||||
ScriptNegativeYaml,
|
||||
SecretsNegativeYaml,
|
||||
ServicesNegativeYaml,
|
||||
NeedsParallelMatrixNumericYaml,
|
||||
NeedsParallelMatrixWrongParallelValueYaml,
|
||||
NeedsParallelMatrixWrongMatrixValueYaml,
|
||||
ScriptNegativeYaml,
|
||||
SpecInputsNegativeYaml,
|
||||
StagesNegativeYaml,
|
||||
TriggerNegativeYaml,
|
||||
VariablesInvalidOptionsYaml,
|
||||
VariablesInvalidSyntaxDescYaml,
|
||||
VariablesWrongSyntaxUsageExpand,
|
||||
WorkflowRulesAutoCancelOnJobFailureNegativeYaml,
|
||||
WorkflowRulesAutoCancelOnNewCommitNegativeYaml,
|
||||
StagesNegativeYaml,
|
||||
RetryNegativeYaml,
|
||||
ParallelNegativeYaml,
|
||||
}),
|
||||
)('schema validates %s', (_, input) => {
|
||||
// We construct a new "JSON" from each main key that is inside a
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
# Type mismatch: string type with number default
|
||||
type_mismatch_string:
|
||||
spec:
|
||||
inputs:
|
||||
string_with_number_default:
|
||||
type: string
|
||||
default: 123
|
||||
|
||||
# Type mismatch: number type with string default
|
||||
type_mismatch_number:
|
||||
spec:
|
||||
inputs:
|
||||
number_with_string_default:
|
||||
type: number
|
||||
default: "not a number"
|
||||
|
||||
# Type mismatch: boolean type with string default
|
||||
type_mismatch_boolean:
|
||||
spec:
|
||||
inputs:
|
||||
boolean_with_string_default:
|
||||
type: boolean
|
||||
default: "not a boolean"
|
||||
|
||||
# Type mismatch: array type with object default
|
||||
type_mismatch_array:
|
||||
spec:
|
||||
inputs:
|
||||
array_with_object_default:
|
||||
type: array
|
||||
default:
|
||||
key: "value"
|
||||
|
||||
# Invalid input type
|
||||
invalid_input_type:
|
||||
spec:
|
||||
inputs:
|
||||
invalid_type_input:
|
||||
type: "object"
|
||||
default: {}
|
||||
|
||||
# Invalid property on input
|
||||
invalid_property:
|
||||
spec:
|
||||
inputs:
|
||||
input_with_invalid_property:
|
||||
type: string
|
||||
invalid_property: "value"
|
||||
|
||||
# Include with invalid input name
|
||||
include_invalid_input_name:
|
||||
include:
|
||||
- local: "template.yml"
|
||||
inputs:
|
||||
invalid/name: "value"
|
||||
|
||||
# Trigger with invalid input value type
|
||||
trigger_invalid_input:
|
||||
trigger_job:
|
||||
trigger:
|
||||
project: "group/project"
|
||||
inputs:
|
||||
number_input: "not a number"
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
# Global component: spec section with inputs
|
||||
spec:
|
||||
inputs:
|
||||
string_input:
|
||||
type: string
|
||||
description: "String input"
|
||||
number_input:
|
||||
type: number
|
||||
description: "Number input"
|
||||
boolean_input:
|
||||
type: boolean
|
||||
description: "Boolean input"
|
||||
array_input:
|
||||
type: array
|
||||
description: "Array input"
|
||||
|
||||
# Global component: include with inputs
|
||||
include:
|
||||
- local: "template.yml"
|
||||
inputs:
|
||||
environment: "production"
|
||||
version: "v2.0.0"
|
||||
debug: false
|
||||
workers: 4
|
||||
|
||||
# Job: trigger with downstream inputs
|
||||
trigger_job:
|
||||
trigger:
|
||||
project: "group/project"
|
||||
strategy: depend
|
||||
inputs:
|
||||
environment: "production"
|
||||
version: "v2.1.0"
|
||||
debug: false
|
||||
matrix:
|
||||
- browser: "chrome"
|
||||
device: "desktop"
|
||||
|
||||
# Job: trigger with child pipeline inputs
|
||||
child_pipeline_job:
|
||||
trigger:
|
||||
include:
|
||||
- local: "child.yml"
|
||||
inputs:
|
||||
environment: "staging"
|
||||
version: "v1.5.0"
|
||||
- project: "group/project"
|
||||
file: "template.yml"
|
||||
inputs:
|
||||
debug: true
|
||||
workers: 8
|
||||
|
|
@ -5,11 +5,11 @@ import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
|
|||
import axios from '~/lib/utils/axios_utils';
|
||||
import toast from '~/vue_shared/plugins/global_toast';
|
||||
|
||||
import { initJwtCiCdJobTokenEnabledToggle } from '~/group_settings/jwt_ci_cd_job_token_enabled_toggle';
|
||||
import { initSettingsToggles } from '~/group_settings/settings_toggles';
|
||||
|
||||
jest.mock('~/vue_shared/plugins/global_toast');
|
||||
|
||||
describe('initJwtCiCdJobTokenEnabledToggle', () => {
|
||||
describe('initSettingsToggles', () => {
|
||||
let form;
|
||||
let wrapper;
|
||||
let requestSubmitMock;
|
||||
|
|
@ -26,12 +26,12 @@ describe('initJwtCiCdJobTokenEnabledToggle', () => {
|
|||
} = {}) => {
|
||||
setHTMLFixture(`
|
||||
<form action="${action}">
|
||||
<input class="js-jwt-ci-cd-job-token-enabled-input" value="${hiddenInputValue}" type="hidden" name="group[jwt_ci_cd_job_token_enabled]"/>
|
||||
<span class="js-jwt-ci-cd-job-token-enabled-toggle" data-disabled="${toggleDisabled}" data-is-checked="${toggleIsChecked}" data-is-loading="false" data-label="${toggleLabel}"></span>
|
||||
<input class="js-setting-input" value="${hiddenInputValue}" type="hidden" name="group[setting]"/>
|
||||
<span class="js-setting-toggle" data-disabled="${toggleDisabled}" data-is-checked="${toggleIsChecked}" data-is-loading="false" data-label="${toggleLabel}"></span>
|
||||
</form>
|
||||
`);
|
||||
|
||||
const toggle = initJwtCiCdJobTokenEnabledToggle();
|
||||
const toggle = initSettingsToggles()[0];
|
||||
|
||||
form = document.querySelector('form');
|
||||
wrapper = createWrapper(toggle);
|
||||
|
|
@ -44,7 +44,7 @@ describe('initJwtCiCdJobTokenEnabledToggle', () => {
|
|||
);
|
||||
};
|
||||
|
||||
const findInput = () => form.querySelector('[name="group[jwt_ci_cd_job_token_enabled]"]');
|
||||
const findInput = () => form.querySelector('[name="group[setting]"]');
|
||||
const findToggle = () => wrapper.findComponent(GlToggle);
|
||||
|
||||
afterEach(() => {
|
||||
|
|
@ -15,6 +15,7 @@ RSpec.describe Types::UserPreferencesType, feature_category: :user_profile do
|
|||
organization_groups_projects_sort
|
||||
organization_groups_projects_display
|
||||
timezone
|
||||
merge_request_dashboard_list_type
|
||||
]
|
||||
|
||||
expect(described_class).to have_graphql_fields(*expected_fields)
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Git::KeepAround do
|
||||
RSpec.describe Gitlab::Git::KeepAround, feature_category: :gitaly do
|
||||
include RepoHelpers
|
||||
|
||||
let(:repository) { create(:project, :repository).repository }
|
||||
let(:service) { described_class.new(repository) }
|
||||
let(:keep_around_ref_name) { "refs/#{::Repository::REF_KEEP_AROUND}/#{sample_commit.id}" }
|
||||
let(:metric_labels) { { full_path: repository.full_path, source: 'keeparound_spec' } }
|
||||
let(:metric_labels) { { source: 'keeparound_spec' } }
|
||||
|
||||
def expect_metrics_change(requested, created, &block)
|
||||
requested_metric = Gitlab::Metrics.registry.get(:gitlab_keeparound_refs_requested_total)
|
||||
|
|
@ -67,33 +67,4 @@ RSpec.describe Gitlab::Git::KeepAround do
|
|||
expect(service.kept_around?(another_sample_commit.id)).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
context 'when disable_keep_around_refs feature flag is enabled' do
|
||||
before do
|
||||
stub_feature_flags(disable_keep_around_refs: true)
|
||||
end
|
||||
|
||||
it 'does not create keep-around refs' do
|
||||
expect_metrics_change(0, 0) do
|
||||
service.execute([sample_commit.id], source: 'keeparound_spec')
|
||||
end
|
||||
|
||||
expect(service.kept_around?(sample_commit.id)).to be_truthy
|
||||
expect(repository.list_refs([keep_around_ref_name])).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context 'when label_keep_around_ref_metrics feature flag is disabled' do
|
||||
let(:metric_labels) { { full_path: '', source: 'keeparound_spec' } }
|
||||
|
||||
before do
|
||||
stub_feature_flags(label_keep_around_ref_metrics: false)
|
||||
end
|
||||
|
||||
it 'does not label keep-around refs' do
|
||||
expect_metrics_change(1, 1) do
|
||||
service.execute([sample_commit.id], source: 'keeparound_spec')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -281,6 +281,82 @@ RSpec.describe Gitlab::OmniauthInitializer, feature_category: :system_access do
|
|||
end
|
||||
end
|
||||
|
||||
context 'for SAML certificate settings' do
|
||||
subject(:init) { initializer.execute(Gitlab.config.omniauth.providers) }
|
||||
|
||||
def stub_saml_config_fingerprint(fingerprint)
|
||||
stub_omniauth_config(
|
||||
providers: [
|
||||
{
|
||||
name: 'saml',
|
||||
args: {
|
||||
idp_cert_fingerprint: fingerprint
|
||||
}
|
||||
}
|
||||
]
|
||||
)
|
||||
end
|
||||
|
||||
it 'sets SHA1 algorithm for SHA1 fingerprint' do
|
||||
stub_saml_config_fingerprint("DD:80:B1:FA:A9:A7:8D:9D:41:7E:09:10:D8:6F:7D:0A:7E:58:4C:C4")
|
||||
|
||||
expect(devise_config).to receive(:omniauth).with(
|
||||
:saml,
|
||||
{
|
||||
attribute_statements: ::Gitlab::Auth::Saml::Config.default_attribute_statements,
|
||||
idp_cert_fingerprint: "DD:80:B1:FA:A9:A7:8D:9D:41:7E:09:10:D8:6F:7D:0A:7E:58:4C:C4",
|
||||
idp_cert_fingerprint_algorithm: "http://www.w3.org/2000/09/xmldsig#sha1"
|
||||
}
|
||||
)
|
||||
|
||||
init
|
||||
end
|
||||
|
||||
it 'sets SHA256 algoritihm for SHA256 fingerprint' do
|
||||
stub_saml_config_fingerprint(
|
||||
"73:2D:28:C2:D2:D0:34:9F:F8:9A:9C:74:23:BF:0A:CB:66:75:78:9B:01:4D:1F:7D:60:8F:AD:47:A2:30:D7:4A"
|
||||
)
|
||||
|
||||
expect(devise_config).to receive(:omniauth).with(
|
||||
:saml,
|
||||
{
|
||||
attribute_statements: ::Gitlab::Auth::Saml::Config.default_attribute_statements,
|
||||
idp_cert_fingerprint:
|
||||
"73:2D:28:C2:D2:D0:34:9F:F8:9A:9C:74:23:BF:0A:CB:66:75:78:9B:01:4D:1F:7D:60:8F:AD:47:A2:30:D7:4A",
|
||||
idp_cert_fingerprint_algorithm: "http://www.w3.org/2001/04/xmlenc#sha256"
|
||||
}
|
||||
)
|
||||
|
||||
init
|
||||
end
|
||||
|
||||
it 'does nothing for explicitly configured algorithm' do
|
||||
stub_omniauth_config(
|
||||
providers: [
|
||||
{
|
||||
name: 'saml',
|
||||
args: {
|
||||
# Mismatched fingerprint and algo to verify we do not mess with explicitly configured values
|
||||
idp_cert_fingerprint: "DD:80:B1:FA:A9:A7:8D:9D:41:7E:09:10:D8:6F:7D:0A:7E:58:4C:C4",
|
||||
idp_cert_fingerprint_algorithm: "http://www.w3.org/2001/04/xmlenc#sha256"
|
||||
}
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
expect(devise_config).to receive(:omniauth).with(
|
||||
:saml,
|
||||
{
|
||||
attribute_statements: ::Gitlab::Auth::Saml::Config.default_attribute_statements,
|
||||
idp_cert_fingerprint: "DD:80:B1:FA:A9:A7:8D:9D:41:7E:09:10:D8:6F:7D:0A:7E:58:4C:C4",
|
||||
idp_cert_fingerprint_algorithm: "http://www.w3.org/2001/04/xmlenc#sha256"
|
||||
}
|
||||
)
|
||||
|
||||
init
|
||||
end
|
||||
end
|
||||
|
||||
it 'configures defaults args for multiple SAML providers' do
|
||||
stub_omniauth_config(
|
||||
providers: [
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ RSpec.describe Ci::JobToken::Authorization, feature_category: :secrets_managemen
|
|||
context 'when authorization is cross project' do
|
||||
it 'schedules the log' do
|
||||
expect(::Ci::JobToken::LogAuthorizationWorker)
|
||||
.to receive(:perform_in).with(5.minutes, accessed_project.id, origin_project.id)
|
||||
.to receive(:perform_in).with(5.minutes, accessed_project.id, origin_project.id, [])
|
||||
|
||||
log_captures_async
|
||||
end
|
||||
|
|
|
|||
|
|
@ -9993,4 +9993,28 @@ RSpec.describe Project, factory_default: :keep, feature_category: :groups_and_pr
|
|||
expect(project.container_registry_protection_tag_rules).to have_received(:for_actions_and_access).with(%w[push], :maintainer).once
|
||||
end
|
||||
end
|
||||
|
||||
describe '#job_token_policies_enabled?' do
|
||||
let_it_be(:project) { build_stubbed(:project) }
|
||||
|
||||
subject { project.job_token_policies_enabled? }
|
||||
|
||||
where(:flag_enabled, :setting_enabled, :result) do
|
||||
true | true | true
|
||||
true | false | true
|
||||
false | true | true
|
||||
false | false | false
|
||||
end
|
||||
|
||||
before do
|
||||
project.clear_memoization(:job_token_policies_enabled?)
|
||||
stub_feature_flags(add_policies_to_ci_job_token: flag_enabled)
|
||||
allow(project).to receive_message_chain(:namespace, :root_ancestor, :namespace_settings,
|
||||
:job_token_policies_enabled?).and_return(setting_enabled)
|
||||
end
|
||||
|
||||
with_them do
|
||||
it { is_expected.to eq(result) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -114,6 +114,9 @@ RSpec.describe User, feature_category: :user_profile do
|
|||
it { is_expected.to delegate_method(:use_work_items_view).to(:user_preference) }
|
||||
it { is_expected.to delegate_method(:use_work_items_view=).to(:user_preference).with_arguments(:args) }
|
||||
|
||||
it { is_expected.to delegate_method(:merge_request_dashboard_list_type).to(:user_preference) }
|
||||
it { is_expected.to delegate_method(:merge_request_dashboard_list_type=).to(:user_preference).with_arguments(:args) }
|
||||
|
||||
it { is_expected.to delegate_method(:text_editor).to(:user_preference) }
|
||||
it { is_expected.to delegate_method(:text_editor=).to(:user_preference).with_arguments(:args) }
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ RSpec.describe Mutations::UserPreferences::Update, feature_category: :user_profi
|
|||
'organizationGroupsProjectsDisplay' => 'GROUPS',
|
||||
'organizationGroupsProjectsSort' => 'NAME_DESC',
|
||||
'visibilityPipelineIdType' => 'IID',
|
||||
'useWorkItemsView' => true
|
||||
'useWorkItemsView' => true,
|
||||
'mergeRequestDashboardListType' => 'ROLE_BASED'
|
||||
}
|
||||
end
|
||||
|
||||
|
|
@ -36,12 +37,14 @@ RSpec.describe Mutations::UserPreferences::Update, feature_category: :user_profi
|
|||
expect(mutation_response['userPreferences']['organizationGroupsProjectsSort']).to eq('NAME_DESC')
|
||||
expect(mutation_response['userPreferences']['visibilityPipelineIdType']).to eq('IID')
|
||||
expect(mutation_response['userPreferences']['useWorkItemsView']).to eq(true)
|
||||
expect(mutation_response['userPreferences']['mergeRequestDashboardListType']).to eq('ROLE_BASED')
|
||||
|
||||
expect(current_user.user_preference.persisted?).to eq(true)
|
||||
expect(current_user.user_preference.extensions_marketplace_opt_in_status).to eq('enabled')
|
||||
expect(current_user.user_preference.issues_sort).to eq(Types::IssueSortEnum.values[sort_value].value.to_s)
|
||||
expect(current_user.user_preference.visibility_pipeline_id_type).to eq('iid')
|
||||
expect(current_user.user_preference.use_work_items_view).to eq(true)
|
||||
expect(current_user.user_preference.merge_request_dashboard_list_type).to eq('role_based')
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -54,7 +57,8 @@ RSpec.describe Mutations::UserPreferences::Update, feature_category: :user_profi
|
|||
organization_groups_projects_display: Types::Organizations::GroupsProjectsDisplayEnum.values['GROUPS'].value,
|
||||
organization_groups_projects_sort: 'NAME_DESC',
|
||||
visibility_pipeline_id_type: 'id',
|
||||
use_work_items_view: false
|
||||
use_work_items_view: false,
|
||||
merge_request_dashboard_list_type: 'action_based'
|
||||
}
|
||||
end
|
||||
|
||||
|
|
@ -77,6 +81,7 @@ RSpec.describe Mutations::UserPreferences::Update, feature_category: :user_profi
|
|||
expect(current_user.user_preference.issues_sort).to eq(Types::IssueSortEnum.values[sort_value].value.to_s)
|
||||
expect(current_user.user_preference.visibility_pipeline_id_type).to eq('iid')
|
||||
expect(current_user.user_preference.use_work_items_view).to eq(true)
|
||||
expect(current_user.user_preference.merge_request_dashboard_list_type).to eq('role_based')
|
||||
end
|
||||
|
||||
context 'when input has nil attributes' do
|
||||
|
|
|
|||
|
|
@ -309,6 +309,7 @@ RSpec.describe NamespaceSettings::AssignAttributesService, feature_category: :gr
|
|||
:new_user_signups_cap | nil | 100
|
||||
:seat_control | 'off' | 'user_cap'
|
||||
:enabled_git_access_protocol | 'all' | 'ssh'
|
||||
:job_token_policies_enabled | false | true
|
||||
end
|
||||
|
||||
with_them do
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ RSpec.describe Projects::ImportExport::PruneExpiredExportJobsService, feature_ca
|
|||
it 'deletes stored upload files' do
|
||||
old_upload_file_paths = Uploads::Local.new.keys(old_uploads)
|
||||
|
||||
expect(DeleteStoredFilesWorker).to receive(:perform_async).with(Uploads::Local, old_upload_file_paths)
|
||||
expect(DeleteStoredFilesWorker).to receive(:perform_async).with(Uploads::Local.name, old_upload_file_paths)
|
||||
|
||||
described_class.execute
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,6 +3,15 @@
|
|||
RSpec.shared_examples 'enforcing job token policies' do |policies, expected_success_status: :success,
|
||||
allow_public_access_for_enabled_project_features: nil|
|
||||
|
||||
shared_examples 'capturing job token policies' do
|
||||
it 'captures the policies' do
|
||||
expect(::Ci::JobToken::Authorization).to receive(:capture_job_token_policies)
|
||||
.with(Array(policies)).and_call_original
|
||||
|
||||
do_request
|
||||
end
|
||||
end
|
||||
|
||||
context 'when authenticating with a CI job token from another project' do
|
||||
let(:source_project) { project }
|
||||
let(:job_user) { user }
|
||||
|
|
@ -58,8 +67,12 @@ RSpec.shared_examples 'enforcing job token policies' do |policies, expected_succ
|
|||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'capturing job token policies'
|
||||
|
||||
context 'when the policies are not allowed' do
|
||||
let(:allowed_policies) { [] }
|
||||
let(:allowed_policies) do
|
||||
(::Ci::JobToken::Policies::POLICIES - Array(policies)).take(1)
|
||||
end
|
||||
|
||||
it { is_expected.to have_gitlab_http_status(:forbidden) }
|
||||
|
||||
|
|
@ -82,6 +95,8 @@ RSpec.shared_examples 'enforcing job token policies' do |policies, expected_succ
|
|||
let(:default_permissions) { true }
|
||||
|
||||
it { is_expected.to have_gitlab_http_status(expected_success_status) }
|
||||
|
||||
it_behaves_like 'capturing job token policies'
|
||||
end
|
||||
|
||||
context 'when job token policies are disabled' do
|
||||
|
|
@ -92,6 +107,8 @@ RSpec.shared_examples 'enforcing job token policies' do |policies, expected_succ
|
|||
end
|
||||
|
||||
it { is_expected.to have_gitlab_http_status(expected_success_status) }
|
||||
|
||||
it_behaves_like 'capturing job token policies'
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ RSpec.shared_examples 'logs inbound authorizations via job token' do |success_st
|
|||
.and_call_original
|
||||
|
||||
expect(Ci::JobToken::LogAuthorizationWorker)
|
||||
.to receive(:perform_in).with(5.minutes, accessed_project.id, origin_project.id)
|
||||
.to receive(:perform_in).with(5.minutes, accessed_project.id, origin_project.id, anything)
|
||||
|
||||
perform_request
|
||||
|
||||
|
|
|
|||
|
|
@ -29,33 +29,26 @@ Status: Experiment
|
|||
|
||||
{{< /history >}}
|
||||
|
||||
{{< alert type="flag" >}}
|
||||
|
||||
The availability of this feature is controlled by a feature flag.
|
||||
For more information, see the history.
|
||||
This feature is available for testing, but not ready for production use.
|
||||
|
||||
{{< /alert >}}
|
||||
|
||||
You can use fine-grained permissions to explicitly allow access to a limited set of API endpoints.
|
||||
These permissions are applied to the CI/CD job tokens in a specified project.
|
||||
This feature is an [experiment](../../policy/development_stages_support.md#experiment).
|
||||
|
||||
## Enable fine-grained permissions
|
||||
This feature is an [experiment](../../policy/development_stages_support.md#experiment) and subject to change without notice. This feature is not ready for production use. If you want to use this feature, you should test outside of production first.
|
||||
|
||||
### On GitLab Self-Managed
|
||||
## Enable fine-grained permissions for projects
|
||||
|
||||
1. Start the GitLab Rails console. For information, see [Enable and disable GitLab features deployed behind feature flags](../../administration/feature_flags.md#enable-or-disable-the-feature)
|
||||
1. Turn on the [feature flag](../../administration/feature_flags.md):
|
||||
Prerequisites:
|
||||
|
||||
```ruby
|
||||
# You must include a specific project ID with this command.
|
||||
Feature.enable(:add_policies_to_ci_job_token, <project_id>)
|
||||
```
|
||||
- You must have the Owner role for a group.
|
||||
|
||||
### On GitLab.com
|
||||
You must turn on fine-grained permissions at the group level. Then, each project in the group can
|
||||
apply fine-grained permissions for CI/CD job tokens to grant access to individual resources.
|
||||
|
||||
Add a comment on this [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/519575) with your project ID.
|
||||
To enable fine-grained permissions for all projects in a group:
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your group.
|
||||
1. On the left sidebar, select **Settings > CI/CD**.
|
||||
1. Expand **General pipelines**.
|
||||
1. Turn on the **Enable fine-grained permissions for CI/CD job tokens** toggle.
|
||||
|
||||
## Available API endpoints
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ require (
|
|||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/stretchr/testify v1.10.0
|
||||
gitlab.com/gitlab-org/gitaly/v16 v16.11.0-rc1.0.20250313033925-4cbd999aaf5d
|
||||
gitlab.com/gitlab-org/labkit v1.23.1
|
||||
gitlab.com/gitlab-org/labkit v1.23.2
|
||||
go.uber.org/goleak v1.3.0
|
||||
gocloud.dev v0.40.1-0.20241107185025-56954848c3aa
|
||||
golang.org/x/image v0.20.0
|
||||
|
|
|
|||
|
|
@ -599,8 +599,8 @@ gitlab.com/gitlab-org/gitaly/v16 v16.11.0-rc1.0.20250313033925-4cbd999aaf5d h1:v
|
|||
gitlab.com/gitlab-org/gitaly/v16 v16.11.0-rc1.0.20250313033925-4cbd999aaf5d/go.mod h1:i9SSlTe8PnTQoSTnLlx+FYHurZWg11BosyClhJHhdqI=
|
||||
gitlab.com/gitlab-org/go/reopen v1.0.0 h1:6BujZ0lkkjGIejTUJdNO1w56mN1SI10qcVQyQlOPM+8=
|
||||
gitlab.com/gitlab-org/go/reopen v1.0.0/go.mod h1:D6OID8YJDzEVZNYW02R/Pkj0v8gYFSIhXFTArAsBQw8=
|
||||
gitlab.com/gitlab-org/labkit v1.23.1 h1:KvHn1lAykOjeYA3uO/luBDIO8gLmWQreKPvKrsh2PO4=
|
||||
gitlab.com/gitlab-org/labkit v1.23.1/go.mod h1:pikea0zSNSfV3wuMrFST4REaM3yrSjnccIfMyCmlrkw=
|
||||
gitlab.com/gitlab-org/labkit v1.23.2 h1:7KhXddq6+3pi7ozYEVGSQBpAs2SNFuw8wmh0RSgygO0=
|
||||
gitlab.com/gitlab-org/labkit v1.23.2/go.mod h1:pikea0zSNSfV3wuMrFST4REaM3yrSjnccIfMyCmlrkw=
|
||||
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
||||
go.etcd.io/etcd/raft/v3 v3.5.18 h1:gueCda+9U76Lvk6rINjNc/mXalUp0u8OK5CVESDZh4I=
|
||||
go.etcd.io/etcd/raft/v3 v3.5.18/go.mod h1:XBaZHTJt3nLnpS8hMDR55Sxrq76cEC4xWYMBYSY3jcs=
|
||||
|
|
|
|||
Loading…
Reference in New Issue