Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
7b7daa5813
commit
111d6e2690
|
|
@ -1,6 +1,7 @@
|
|||
.as-if-jh-sandbox-variables:
|
||||
variables:
|
||||
AS_IF_JH_BRANCH: "as-if-jh/${CI_COMMIT_REF_NAME}"
|
||||
JH_MIRROR_REPOSITORY: "https://dummy:${ADD_JH_FILES_TOKEN}@gitlab.com/gitlab-org/gitlab-jh-mirrors/gitlab.git"
|
||||
SANDBOX_REPOSITORY: "https://dummy:${AS_IF_JH_TOKEN}@gitlab.com/gitlab-org-sandbox/gitlab-jh-validation.git"
|
||||
|
||||
.shared-as-if-jh:
|
||||
|
|
@ -13,20 +14,12 @@
|
|||
add-jh-files:
|
||||
extends:
|
||||
- .shared-as-if-jh
|
||||
- .with_secret
|
||||
- .as-if-jh:rules:prepare-as-if-jh
|
||||
image: ${GITLAB_DEPENDENCY_PROXY_ADDRESS}ruby:${RUBY_VERSION}
|
||||
stage: prepare
|
||||
needs: []
|
||||
secrets:
|
||||
ADD_JH_FILES_TOKEN:
|
||||
gcp_secret_manager:
|
||||
name: ADD_JH_FILES_TOKEN
|
||||
token: $GCP_ID_TOKEN
|
||||
before_script:
|
||||
- source ./scripts/utils.sh
|
||||
- export ADD_JH_FILES_TOKEN="$(cat ${ADD_JH_FILES_TOKEN})"
|
||||
- export JH_MIRROR_REPOSITORY="https://dummy:${ADD_JH_FILES_TOKEN}@gitlab.com/gitlab-org/gitlab-jh-mirrors/gitlab.git"
|
||||
- source ./scripts/setup/as-if-jh.sh
|
||||
- install_gitlab_gem
|
||||
script:
|
||||
|
|
|
|||
|
|
@ -514,8 +514,3 @@
|
|||
curl -f --header "Private-Token: ${PROJECT_TOKEN_FOR_CI_SCRIPTS_API_USAGE}" "${url}" --create-dirs --output scripts/utils.sh
|
||||
- source scripts/utils.sh
|
||||
- run_timed_command "download_files ${FILES_TO_DOWNLOAD}"
|
||||
|
||||
.with_secret:
|
||||
id_tokens:
|
||||
GCP_ID_TOKEN:
|
||||
aud: https://iam.googleapis.com/projects/${GCP_PROJECT_NUMBER}/locations/global/workloadIdentityPools/${GCP_WORKLOAD_IDENTITY_FEDERATION_POOL_ID}/providers/${GCP_WORKLOAD_IDENTITY_FEDERATION_PROVIDER_ID}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
<--
|
||||
<!--
|
||||
|
||||
This issue template is sourced from https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab/issue_templates/SAST%20Ruleset%20Enhancement.md and is maintained by the Secure: Vulnerability Research team (https://handbook.gitlab.com/handbook/engineering/development/sec/secure/vulnerability-research/), most of its content is based on the documentation found in the GitLab SAST Rules Project under https://gitlab.com/gitlab-org/security-products/sast-rules/-/blob/main/docs.
|
||||
|
||||
|
|
@ -7,13 +6,13 @@ This issue template is sourced from https://gitlab.com/gitlab-org/gitlab/-/blob/
|
|||
|
||||
## Background and Rationale behind this Work
|
||||
|
||||
<--
|
||||
<!--
|
||||
REPLACE: As per https://gitlab.com/gitlab-org/gitlab/-/issues/425704 and https://gitlab.com/gitlab-org/gitlab/-/issues/425704 we are continuously working towards improving the coverage and efficacy of our SAST rules.
|
||||
-->
|
||||
|
||||
### Desired Change
|
||||
|
||||
<--
|
||||
<!--
|
||||
REPLACE: This issue is aimed at creating, embedding, or enhancing a GitLab SAST rule that detects the issue seen in https://foo.example.com and https://bar.example.com
|
||||
-->
|
||||
|
||||
|
|
@ -21,7 +20,7 @@ REPLACE: This issue is aimed at creating, embedding, or enhancing a GitLab SAST
|
|||
|
||||
## Implementation Plan
|
||||
|
||||
### Assesment
|
||||
### Assessment
|
||||
|
||||
|
||||
#### If Creating a New Rule
|
||||
|
|
@ -95,14 +94,14 @@ If the addition, inclusion or adaptation of a rule addressing the Desired Change
|
|||
- [ ] Clone our [Real World Test Projects](https://gitlab.com/gitlab-org/security-products/tests/sast-rules-apps/) and extend it with your MRE demonstrating the problem. Alternatively, discuss the creation of a new folder or repository if none fits.
|
||||
- [ ] Push the changes to [gitlab-org/security-products/tests/sast-rules-apps](https://gitlab.com/gitlab-org/security-products/tests/sast-rules-apps/) as a feature branch if you have access; otherwise push it to a personal fork of the project
|
||||
- [ ] Create a new MR and mention this issue in it so they are linked.
|
||||
- [ ] A member of the @gitlab-org/secure/vulnerability-research team will assign themselves as reviewer shortly, work with them to finalise and merge your work.
|
||||
- [ ] A member of the `@gitlab-org/secure/vulnerability-research` team will assign themselves as reviewer shortly, work with them to finalise and merge your work.
|
||||
|
||||
|
||||
#### Merge the Rule
|
||||
|
||||
- [ ] Push the changes to `sast-rules` as a feature branch to [gitlab-org/security-products/sast-rules](https://gitlab.com/gitlab-org/security-products/sast-rules/) if you have access; otherwise push it to a personal fork of the project.
|
||||
- [ ] Create the MR and mention this issue in it so they are linked.
|
||||
- [ ] A member of the @gitlab-org/secure/vulnerability-research team will assign themselves as reviewer shortly, work with them to finalise and merge your work.
|
||||
- [ ] A member of the `@gitlab-org/secure/vulnerability-research` team will assign themselves as reviewer shortly, work with them to finalise and merge your work.
|
||||
- [ ] Find the [latest sast-rules release MR](https://gitlab.com/gitlab-org/security-products/sast-rules/-/merge_requests?scope=all&state=opened&search=draft%3A+Release) and add a line to CHANGELOG.md detailing briefly the changes performed, their intent and the MR ID where this work was done.
|
||||
|
||||
```
|
||||
|
|
|
|||
2
Gemfile
2
Gemfile
|
|
@ -560,7 +560,7 @@ gem 'spamcheck', '~> 1.3.0' # rubocop:todo Gemfile/MissingFeatureCategory
|
|||
gem 'gitaly', '~> 16.9.0-rc3', feature_category: :gitaly
|
||||
|
||||
# KAS GRPC protocol definitions
|
||||
gem 'kas-grpc', '~> 0.3.0', feature_category: :deployment_management
|
||||
gem 'kas-grpc', '~> 0.4.0', feature_category: :deployment_management
|
||||
|
||||
gem 'grpc', '~> 1.60.0' # rubocop:todo Gemfile/MissingFeatureCategory
|
||||
|
||||
|
|
|
|||
|
|
@ -341,7 +341,7 @@
|
|||
{"name":"kaminari-actionview","version":"1.2.2","platform":"ruby","checksum":"1330f6fc8b59a4a4ef6a549ff8a224797289ebf7a3a503e8c1652535287cc909"},
|
||||
{"name":"kaminari-activerecord","version":"1.2.2","platform":"ruby","checksum":"0dd3a67bab356a356f36b3b7236bcb81cef313095365befe8e98057dd2472430"},
|
||||
{"name":"kaminari-core","version":"1.2.2","platform":"ruby","checksum":"3bd26fec7370645af40ca73b9426a448d09b8a8ba7afa9ba3c3e0d39cdbb83ff"},
|
||||
{"name":"kas-grpc","version":"0.3.0","platform":"ruby","checksum":"78dfc454e6725e6354e66e9e65ea87b6ad0888f52d20bf41775e5400d74dad8a"},
|
||||
{"name":"kas-grpc","version":"0.4.0","platform":"ruby","checksum":"bb21845032b443289b20be8ff8ae22a35abedb3ed17e60ed10b6e5f05bc6738d"},
|
||||
{"name":"knapsack","version":"1.21.1","platform":"ruby","checksum":"82f70422adebcacec1b514f6ebff65265fc85d836e3c320718a160d8ac41cf14"},
|
||||
{"name":"kramdown","version":"2.3.2","platform":"ruby","checksum":"cb4530c2e9d16481591df2c9336723683c354e5416a5dd3e447fa48215a6a71c"},
|
||||
{"name":"kramdown-parser-gfm","version":"1.1.0","platform":"ruby","checksum":"fb39745516427d2988543bf01fc4cf0ab1149476382393e0e9c48592f6581729"},
|
||||
|
|
|
|||
|
|
@ -1009,7 +1009,7 @@ GEM
|
|||
activerecord
|
||||
kaminari-core (= 1.2.2)
|
||||
kaminari-core (1.2.2)
|
||||
kas-grpc (0.3.0)
|
||||
kas-grpc (0.4.0)
|
||||
grpc (~> 1.0)
|
||||
knapsack (1.21.1)
|
||||
rake
|
||||
|
|
@ -1987,7 +1987,7 @@ DEPENDENCIES
|
|||
jsonb_accessor (~> 1.3.10)
|
||||
jwt (~> 2.5)
|
||||
kaminari (~> 1.2.2)
|
||||
kas-grpc (~> 0.3.0)
|
||||
kas-grpc (~> 0.4.0)
|
||||
knapsack (~> 1.21.1)
|
||||
kramdown (~> 2.3.1)
|
||||
kubeclient (~> 4.11.0)
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ export default {
|
|||
};
|
||||
},
|
||||
result({ data: { activeBoardItem } }) {
|
||||
if (activeBoardItem) {
|
||||
if (activeBoardItem && activeBoardItem.listId !== null) {
|
||||
this.setActiveId('');
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ export default {
|
|||
mutation: setActiveBoardItemMutation,
|
||||
variables: {
|
||||
boardItem: this.isActive ? null : this.item,
|
||||
listId: this.list.id,
|
||||
isIssue: this.isActive ? undefined : this.isIssueBoard,
|
||||
},
|
||||
});
|
||||
|
|
@ -122,7 +123,7 @@ export default {
|
|||
});
|
||||
await this.$apollo.mutate({
|
||||
mutation: setActiveBoardItemMutation,
|
||||
variables: { boardItem: null },
|
||||
variables: { boardItem: null, listId: null },
|
||||
});
|
||||
}
|
||||
this.$apollo.mutate({
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import SidebarSubscriptionsWidget from '~/sidebar/components/subscriptions/sideb
|
|||
import SidebarTodoWidget from '~/sidebar/components/todo_toggle/sidebar_todo_widget.vue';
|
||||
import SidebarLabelsWidget from '~/sidebar/components/labels/labels_select_widget/labels_select_root.vue';
|
||||
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||
import { setError } from '../graphql/cache_updates';
|
||||
import { setError, updateListWeightCache } from '../graphql/cache_updates';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
|
@ -163,9 +163,14 @@ export default {
|
|||
mutation: setActiveBoardItemMutation,
|
||||
variables: {
|
||||
boardItem: null,
|
||||
listId: null,
|
||||
},
|
||||
});
|
||||
},
|
||||
updateListTotalWeight({ weight }) {
|
||||
const { cache } = this.$apollo.provider.clients.defaultClient;
|
||||
updateListWeightCache({ weight, listId: this.activeBoardCard.listId, cache });
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -280,6 +285,7 @@ export default {
|
|||
:iid="activeBoardIssuable.iid"
|
||||
:full-path="projectPathForActiveIssue"
|
||||
:issuable-type="issuableType"
|
||||
@weightUpdated="updateListTotalWeight"
|
||||
/>
|
||||
<sidebar-health-status-widget
|
||||
v-if="healthStatusFeatureAvailable"
|
||||
|
|
|
|||
|
|
@ -627,6 +627,7 @@ export default {
|
|||
mutation: setActiveBoardItemMutation,
|
||||
variables: {
|
||||
boardItem: issuable,
|
||||
listId: this.list.id,
|
||||
isIssue: this.isIssueBoard,
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -235,7 +235,7 @@ export default {
|
|||
openSidebarSettings() {
|
||||
this.$apollo.mutate({
|
||||
mutation: setActiveBoardItemMutation,
|
||||
variables: { boardItem: null },
|
||||
variables: { boardItem: null, listId: null },
|
||||
});
|
||||
this.$emit('setActiveList', this.list.id);
|
||||
|
||||
|
|
|
|||
|
|
@ -139,6 +139,21 @@ export function updateEpicsCount({
|
|||
);
|
||||
}
|
||||
|
||||
export function updateListWeightCache({ weight, listId, cache }) {
|
||||
cache.updateQuery(
|
||||
{
|
||||
query: listQuery,
|
||||
variables: { id: listId },
|
||||
},
|
||||
({ boardList }) => ({
|
||||
boardList: {
|
||||
...boardList,
|
||||
totalIssueWeight: toNumber(boardList.totalIssueWeight) + weight,
|
||||
},
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
export function setError({ message, error, captureError = true }) {
|
||||
defaultClient.mutate({
|
||||
mutation: setErrorMutation,
|
||||
|
|
|
|||
|
|
@ -3,5 +3,6 @@
|
|||
query activeBoardItem {
|
||||
activeBoardItem @client {
|
||||
...Issue
|
||||
listId
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
#import "ee_else_ce/boards/graphql/issue.fragment.graphql"
|
||||
|
||||
mutation setActiveBoardItem($boardItem: Issue) {
|
||||
setActiveBoardItem(boardItem: $boardItem) @client {
|
||||
mutation setActiveBoardItem($boardItem: Issue, $listId: ListID!) {
|
||||
setActiveBoardItem(boardItem: $boardItem, listId: $listId) @client {
|
||||
...Issue
|
||||
listId
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -220,12 +220,12 @@ export const resolvers = {
|
|||
});
|
||||
cache.writeQuery({ query: getIssueStateQuery, data });
|
||||
},
|
||||
setActiveBoardItem(_, { boardItem }, { cache }) {
|
||||
setActiveBoardItem(_, { boardItem, listId }, { cache }) {
|
||||
cache.writeQuery({
|
||||
query: activeBoardItemQuery,
|
||||
data: { activeBoardItem: boardItem },
|
||||
data: { activeBoardItem: { ...boardItem, listId } },
|
||||
});
|
||||
return boardItem;
|
||||
return { ...boardItem, listId };
|
||||
},
|
||||
setSelectedBoardItems(_, { itemId }, { cache }) {
|
||||
const sourceData = cache.readQuery({ query: selectedBoardItemsQuery });
|
||||
|
|
|
|||
|
|
@ -6,12 +6,6 @@
|
|||
max-width: 960px;
|
||||
}
|
||||
|
||||
.borderless {
|
||||
.login-box {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
.g-recaptcha {
|
||||
> div {
|
||||
margin-left: auto;
|
||||
|
|
@ -20,16 +14,11 @@
|
|||
}
|
||||
|
||||
.new-session-tabs {
|
||||
&.nav-links-unboxed {
|
||||
border-color: transparent;
|
||||
box-shadow: none;
|
||||
display: flex;
|
||||
border-color: transparent;
|
||||
|
||||
.nav-item {
|
||||
border-left: 0;
|
||||
border-right: 0;
|
||||
border-bottom: 1px solid $gray-100;
|
||||
background-color: transparent;
|
||||
}
|
||||
.nav-item {
|
||||
border-bottom: 1px solid $gray-100;
|
||||
|
||||
.nav-link.active {
|
||||
.gl-dark & {
|
||||
|
|
@ -38,28 +27,9 @@
|
|||
}
|
||||
}
|
||||
|
||||
display: flex;
|
||||
box-shadow: 0 0 0 1px $border-color;
|
||||
border-top-right-radius: $border-radius-default;
|
||||
border-top-left-radius: $border-radius-default;
|
||||
|
||||
li {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
border-left: 1px solid $border-color;
|
||||
|
||||
&:first-of-type {
|
||||
border-left: 0;
|
||||
border-top-left-radius: $border-radius-default;
|
||||
}
|
||||
|
||||
&:last-of-type {
|
||||
border-top-right-radius: $border-radius-default;
|
||||
}
|
||||
|
||||
&:not(.active) {
|
||||
background-color: $gray-light;
|
||||
}
|
||||
|
||||
a {
|
||||
width: 100%;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ParseCommitDate
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def convert_date_to_epoch(date)
|
||||
Date.strptime(date, "%Y-%m-%d")&.to_time&.to_i if date
|
||||
rescue Date::Error, TypeError
|
||||
end
|
||||
end
|
||||
|
|
@ -5,6 +5,7 @@ require "base64"
|
|||
class Projects::CommitsController < Projects::ApplicationController
|
||||
include ExtractsPath
|
||||
include RendersCommits
|
||||
include ParseCommitDate
|
||||
|
||||
COMMITS_DEFAULT_LIMIT = 40
|
||||
prepend_before_action(only: [:show]) { authenticate_sessionless_user!(:rss) }
|
||||
|
|
@ -75,6 +76,8 @@ class Projects::CommitsController < Projects::ApplicationController
|
|||
@offset = (permitted_params[:offset] || 0).to_i
|
||||
search = permitted_params[:search]
|
||||
author = permitted_params[:author]
|
||||
committed_before = convert_date_to_epoch(permitted_params[:committed_before])
|
||||
committed_after = convert_date_to_epoch(permitted_params[:committed_after])
|
||||
|
||||
# fully_qualified_ref is available in some situations from ExtractsRef
|
||||
ref = @fully_qualified_ref || @ref
|
||||
|
|
@ -89,6 +92,8 @@ class Projects::CommitsController < Projects::ApplicationController
|
|||
offset: @offset
|
||||
}
|
||||
options[:author] = author if author.present?
|
||||
options[:before] = committed_before if committed_before.present?
|
||||
options[:after] = committed_after if committed_after.present?
|
||||
|
||||
@repository.commits(ref, **options)
|
||||
end
|
||||
|
|
@ -101,6 +106,6 @@ class Projects::CommitsController < Projects::ApplicationController
|
|||
end
|
||||
|
||||
def permitted_params
|
||||
params.permit(:limit, :offset, :search, :author)
|
||||
params.permit(:limit, :offset, :search, :author, :committed_before, :committed_after)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
|
|||
include DiffHelper
|
||||
include Gitlab::Cache::Helpers
|
||||
include MergeRequestsHelper
|
||||
include ParseCommitDate
|
||||
|
||||
prepend_before_action(only: [:index]) { authenticate_sessionless_user!(:rss) }
|
||||
skip_before_action :merge_request, only: [:index, :bulk_update, :export_csv]
|
||||
|
|
@ -639,11 +640,6 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
|
|||
diff_head: true
|
||||
)
|
||||
end
|
||||
|
||||
def convert_date_to_epoch(date)
|
||||
Date.strptime(date, "%Y-%m-%d")&.to_time&.to_i if date
|
||||
rescue Date::Error, TypeError
|
||||
end
|
||||
end
|
||||
|
||||
Projects::MergeRequestsController.prepend_mod_with('Projects::MergeRequestsController')
|
||||
|
|
|
|||
|
|
@ -33,40 +33,16 @@ module Repositories
|
|||
|
||||
def execute(new_version)
|
||||
tags = {}
|
||||
versions = [new_version]
|
||||
|
||||
begin
|
||||
regex = Gitlab::UntrustedRegexp.new(@regex)
|
||||
rescue RegexpError => e
|
||||
# The error messages produced by default are not very helpful, so we
|
||||
# raise a better one here. We raise the specific error here so its
|
||||
# message is displayed in the API (where we catch this specific
|
||||
# error).
|
||||
raise(
|
||||
Gitlab::Changelog::Error,
|
||||
"The regular expression to use for finding the previous tag for a version is invalid: #{e.message}"
|
||||
)
|
||||
end
|
||||
requested_version = extract_version(new_version)
|
||||
return unless requested_version
|
||||
|
||||
versions = [requested_version]
|
||||
|
||||
@project.repository.tags.each do |tag|
|
||||
matches = regex.match(tag.name)
|
||||
version = extract_version(tag.name)
|
||||
|
||||
next unless matches
|
||||
|
||||
# When using this class for generating changelog data for a range of
|
||||
# commits, we want to compare against the tag of the last _stable_
|
||||
# release; not some random RC that came after that.
|
||||
next if matches[:pre]
|
||||
|
||||
major = matches[:major]
|
||||
minor = matches[:minor]
|
||||
patch = matches[:patch]
|
||||
build = matches[:meta]
|
||||
|
||||
next unless major && minor && patch
|
||||
|
||||
version = "#{major}.#{minor}.#{patch}"
|
||||
version += "+#{build}" if build
|
||||
next unless version
|
||||
|
||||
tags[version] = tag
|
||||
versions << version
|
||||
|
|
@ -74,9 +50,47 @@ module Repositories
|
|||
|
||||
VersionSorter.sort!(versions)
|
||||
|
||||
index = versions.index(new_version)
|
||||
index = versions.index(requested_version)
|
||||
|
||||
tags[versions[index - 1]] if index&.positive?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def version_matcher
|
||||
@version_matcher ||= Gitlab::UntrustedRegexp.new(@regex)
|
||||
rescue RegexpError => e
|
||||
# The error messages produced by default are not very helpful, so we
|
||||
# raise a better one here. We raise the specific error here so its
|
||||
# message is displayed in the API (where we catch this specific
|
||||
# error).
|
||||
raise(
|
||||
Gitlab::Changelog::Error,
|
||||
"The regular expression to use for finding the previous tag for a version is invalid: #{e.message}"
|
||||
)
|
||||
end
|
||||
|
||||
def extract_version(string)
|
||||
matches = version_matcher.match(string)
|
||||
|
||||
return unless matches
|
||||
|
||||
# When using this class for generating changelog data for a range of
|
||||
# commits, we want to compare against the tag of the last _stable_
|
||||
# release; not some random RC that came after that.
|
||||
return if matches[:pre]
|
||||
|
||||
major = matches[:major]
|
||||
minor = matches[:minor]
|
||||
patch = matches[:patch]
|
||||
build = matches[:meta]
|
||||
|
||||
return unless major && minor && patch
|
||||
|
||||
version = "#{major}.#{minor}.#{patch}"
|
||||
version += "+#{build}" if build
|
||||
|
||||
version
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -581,9 +581,7 @@ module Ci
|
|||
end
|
||||
|
||||
def self.use_partition_id_filter?
|
||||
::Gitlab::SafeRequestStore.fetch(:ci_builds_partition_id_query_filter) do
|
||||
::Feature.enabled?(:ci_builds_partition_id_query_filter)
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
def uses_needs?
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@ class CodequalityDegradationEntity < Grape::Entity
|
|||
expose :description
|
||||
expose :fingerprint
|
||||
expose :severity do |degradation|
|
||||
degradation.dig(:severity)&.downcase
|
||||
severity = degradation.dig(:severity)&.downcase
|
||||
|
||||
::Gitlab::Ci::Reports::CodequalityReports::SEVERITY_PRIORITIES.key?(severity) ? severity : 'unknown'
|
||||
end
|
||||
|
||||
expose :file_path do |degradation|
|
||||
|
|
|
|||
|
|
@ -50,6 +50,10 @@ module Ci
|
|||
yield(pipelines_project_merge_request_path(merge_request))
|
||||
yield(merge_request_widget_path(merge_request))
|
||||
end
|
||||
|
||||
pipeline.project.merge_requests.by_merged_or_merge_or_squash_commit_sha(pipeline.sha).each do |merge_request|
|
||||
yield(merge_request_widget_path(merge_request))
|
||||
end
|
||||
end
|
||||
|
||||
def graphql_pipeline_path(pipeline)
|
||||
|
|
|
|||
|
|
@ -38,6 +38,10 @@ module Projects
|
|||
return ServiceResponse.error(message: _('Project already forked'), reason: :already_forked)
|
||||
end
|
||||
|
||||
if fork_to_project == @project
|
||||
return ServiceResponse.error(message: _('Target project cannot be equal to source project'), reason: :self_fork)
|
||||
end
|
||||
|
||||
build_fork_network_member(fork_to_project)
|
||||
|
||||
if link_fork_network(fork_to_project)
|
||||
|
|
|
|||
|
|
@ -4,16 +4,15 @@
|
|||
.row.gl-mt-5.justify-content-center
|
||||
.col-md-5
|
||||
.login-page
|
||||
.borderless
|
||||
- if any_form_based_providers_enabled?
|
||||
= render 'devise/shared/tabs_ldap', admin_mode: true
|
||||
- elsif allow_admin_mode_password_authentication_for_web?
|
||||
= render 'devise/sessions/new_base', admin_mode: true
|
||||
- if any_form_based_providers_enabled?
|
||||
= render 'devise/shared/tabs_ldap', admin_mode: true
|
||||
- elsif allow_admin_mode_password_authentication_for_web?
|
||||
= render 'devise/sessions/new_base', admin_mode: true
|
||||
|
||||
-# Show a message if none of the mechanisms above are enabled
|
||||
- if !allow_admin_mode_password_authentication_for_web? && !ldap_sign_in_enabled? && !omniauth_enabled?
|
||||
.gl-mt-3.center
|
||||
= _('No authentication methods configured.')
|
||||
-# Show a message if none of the mechanisms above are enabled
|
||||
- if !allow_admin_mode_password_authentication_for_web? && !ldap_sign_in_enabled? && !omniauth_enabled?
|
||||
.gl-mt-3.center
|
||||
= _('No authentication methods configured.')
|
||||
|
||||
- if omniauth_enabled? && button_based_providers_enabled?
|
||||
= render 'devise/shared/omniauth_box', render_remember_me: false
|
||||
- if omniauth_enabled? && button_based_providers_enabled?
|
||||
= render 'devise/shared/omniauth_box', render_remember_me: false
|
||||
|
|
|
|||
|
|
@ -4,9 +4,8 @@
|
|||
.row.justify-content-center
|
||||
.col-md-5
|
||||
.login-page
|
||||
.borderless
|
||||
.login-box.gl-p-5
|
||||
- if current_user.two_factor_enabled?
|
||||
= render 'admin/sessions/two_factor_otp'
|
||||
- if current_user.two_factor_webauthn_enabled?
|
||||
= render 'authentication/authenticate', render_remember_me: false, target_path: admin_session_path
|
||||
.login-box.gl-p-5
|
||||
- if current_user.two_factor_enabled?
|
||||
= render 'admin/sessions/two_factor_otp'
|
||||
- if current_user.two_factor_webauthn_enabled?
|
||||
= render 'authentication/authenticate', render_remember_me: false, target_path: admin_session_path
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
= header_message
|
||||
= render "layouts/init_client_detection_flags"
|
||||
= yield :sessions_broadcast
|
||||
.gl-h-full.borderless.gl-display-flex.gl-flex-wrap
|
||||
.gl-h-full.gl-display-flex.gl-flex-wrap
|
||||
.container.gl-align-self-center
|
||||
.content
|
||||
= render "layouts/flash"
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: ci_builds_partition_id_query_filter
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/130073
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/431361
|
||||
milestone: '16.6'
|
||||
type: development
|
||||
group: group::pipeline execution
|
||||
default_enabled: false
|
||||
|
|
@ -700,6 +700,59 @@ Get the external wiki settings for a project.
|
|||
GET /projects/:id/integrations/external-wiki
|
||||
```
|
||||
|
||||
## GitGuardian
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Premium, Ultimate
|
||||
**Offering:** SaaS, self-managed
|
||||
**Status:** Beta
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/435706) in GitLab 16.9 [with a flag](../administration/feature_flags.md) named `git_guardian_integration`. Disabled by default.
|
||||
|
||||
FLAG:
|
||||
On self-managed GitLab, by default this feature is not available. To make it available, an administrator can [enable the feature flag](../administration/feature_flags.md) named `git_guardian_integration`.
|
||||
On GitLab.com, this feature is not available.
|
||||
This feature is not ready for production use.
|
||||
|
||||
[GitGuardian](https://www.gitguardian.com/) is a cybersecurity service that detects sensitive data such as API keys
|
||||
and passwords in source code repositories.
|
||||
It scans Git repositories, alerts on policy violations, and helps organizations
|
||||
fix security issues before hackers can exploit them.
|
||||
|
||||
You can configure GitLab to reject commits based on GitGuardian policies.
|
||||
|
||||
This feature is in [Beta](../policy/experiment-beta-support.md#beta) and subject to change without notice.
|
||||
|
||||
### Set up GitGuardian
|
||||
|
||||
Set up the GitGuardian integration for a project.
|
||||
|
||||
```plaintext
|
||||
PUT /projects/:id/integrations/git-guardian
|
||||
```
|
||||
|
||||
Parameters:
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- |-----------------------------------------------|
|
||||
| `token` | string | true | GitGuardian API token with `scan` scope. |
|
||||
|
||||
### Disable GitGuardian
|
||||
|
||||
Disable the GitGuardian integration for a project. Integration settings are reset.
|
||||
|
||||
```plaintext
|
||||
DELETE /projects/:id/integrations/git-guardian
|
||||
```
|
||||
|
||||
### Get GitGuardian settings
|
||||
|
||||
Get the GitGuardian integration settings for a project.
|
||||
|
||||
```plaintext
|
||||
GET /projects/:id/integrations/git-guardian
|
||||
```
|
||||
|
||||
## GitHub
|
||||
|
||||
DETAILS:
|
||||
|
|
|
|||
|
|
@ -366,6 +366,9 @@ If the `version` attribute is `2.1.0`, GitLab uses tag `v2.0.0`. And when the
|
|||
version is `1.1.1`, or `1.2.0`, GitLab uses tag v1.1.0. The tag `v1.0.0-pre1` is
|
||||
never used, because pre-release tags are ignored.
|
||||
|
||||
The `version` attribute can start with `v`. For example: `v1.0.0`.
|
||||
The response is the same as for `version` value `1.0.0`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/437616) in GitLab 16.9.
|
||||
|
||||
If `from` is unspecified and no tag to use is found, the API produces an error.
|
||||
To solve such an error, you must explicitly specify a value for the `from`
|
||||
attribute.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,77 @@
|
|||
---
|
||||
stage: Create
|
||||
group: Source Code
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# GitGuardian
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Premium, Ultimate
|
||||
**Offering:** SaaS, self-managed
|
||||
**Status:** Beta
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/435706) in GitLab 16.9 [with a flag](../../../administration/feature_flags.md) named `git_guardian_integration`. Disabled by default.
|
||||
|
||||
FLAG:
|
||||
On self-managed GitLab, by default this feature is not available. To make it available, an administrator can [enable the feature flag](../../../administration/feature_flags.md) named `git_guardian_integration`.
|
||||
On GitLab.com, this feature is not available.
|
||||
This feature is not ready for production use.
|
||||
|
||||
[GitGuardian](https://www.gitguardian.com/) is a cybersecurity service that detects sensitive data such as API keys
|
||||
and passwords in source code repositories.
|
||||
It scans Git repositories, alerts on policy violations, and helps organizations
|
||||
fix security issues before hackers can exploit them.
|
||||
|
||||
You can configure GitLab to reject commits based on GitGuardian policies.
|
||||
|
||||
This feature is in [Beta](../../../policy/experiment-beta-support.md#beta) and subject to change without notice.
|
||||
|
||||
To set up the GitGuardian integration:
|
||||
|
||||
1. [Create a GitGuardian API token](#create-a-gitguardian-api-token).
|
||||
1. [Set up the GitGuardian integration for your project](#set-up-the-gitguardian-integration-for-your-project).
|
||||
|
||||
## Create a GitGuardian API token
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- You must have a GitGuardian account.
|
||||
|
||||
To create an API token:
|
||||
|
||||
1. Sign in to your GitGuardian account.
|
||||
1. Go to the **API** section in the sidebar.
|
||||
1. In the API section sidebar go to **Personal access tokens** page.
|
||||
1. Select **Create token**. The token creation dialog opens.
|
||||
1. Provide your token information:
|
||||
- Give your API token a meaningful name to identify its purpose.
|
||||
For example, `GitLab integration token`.
|
||||
- Select an appropriate expiration.
|
||||
- Select the **scan scope** checkbox.
|
||||
It is the only one needed for the integration.
|
||||
1. Select **Create token**.
|
||||
1. After you've generated a token, copy it to your clipboard.
|
||||
This token is sensitive information, so keep it secure.
|
||||
|
||||
Now you have successfully created a GitGuardian API token that you can use to for our integration.
|
||||
|
||||
## Set up the GitGuardian integration for your project
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- You must have at least the Maintainer role for the project.
|
||||
|
||||
After you have created and copied your API token, configure GitLab to reject commits:
|
||||
|
||||
To enable the integration for your project:
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your project or group.
|
||||
1. Select **Settings > Integrations**.
|
||||
1. Select **GitGuardian**.
|
||||
1. In **Enable integration**, select the **Active** checkbox.
|
||||
1. In **API token**, [paste the token value from GitGuardian](#create-a-gitguardian-api-token).
|
||||
1. Optional. Select **Test settings**.
|
||||
1. Select **Save changes**.
|
||||
|
||||
GitLab is now ready to reject commits based on GitGuardian policies.
|
||||
|
|
@ -132,6 +132,7 @@ To use custom settings for a project or group integration:
|
|||
| [Emails on push](emails_on_push.md) | Send commits and diffs on push by email. | **{dotted-circle}** No |
|
||||
| [Engineering Workflow Management (EWM)](ewm.md) | Use EWM as an issue tracker. | **{dotted-circle}** No |
|
||||
| [External wiki](../wiki/index.md#link-an-external-wiki) | Link an external wiki. | **{dotted-circle}** No |
|
||||
| [GitGuardian](git_guardian.md) | Reject commits based on GitGuardian policies. | **{dotted-circle}** No |
|
||||
| [GitHub](github.md) | Receive statuses for commits and pull requests. | **{dotted-circle}** No |
|
||||
| [GitLab for Slack app](gitlab_slack_application.md) | Use the native Slack app to receive notifications and run commands. | **{dotted-circle}** No |
|
||||
| [Google Chat](hangouts_chat.md) | Send notifications from your GitLab project to a room in Google Chat. | **{dotted-circle}** No |
|
||||
|
|
|
|||
|
|
@ -126,6 +126,12 @@ rewrite the URL.
|
|||
## Domain-level redirects
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-pages/-/merge_requests/936) in GitLab 16.8 [with a flag](../../../administration/feature_flags.md) named `FF_ENABLE_DOMAIN_REDIRECT`. Disabled by default.
|
||||
> - [Enabled on GitLab.com](https://gitlab.com/gitlab-com/gl-infra/k8s-workloads/gitlab-com/-/merge_requests/3395) in GitLab 16.9.
|
||||
|
||||
NOTE:
|
||||
On self-managed GitLab, by default this feature is not available.
|
||||
To make it available, an administrator can [enable the feature flag](../../../administration/feature_flags.md) named `FF_ENABLE_DOMAIN_REDIRECT`.
|
||||
On GitLab.com, this feature is available.
|
||||
|
||||
To create a domain-level redirect, add a domain-level path (beginning with `http://`
|
||||
or `https://`) to either:
|
||||
|
|
|
|||
|
|
@ -28,6 +28,22 @@ The name and email information provided are retrieved from the
|
|||
[Git configuration](https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration)
|
||||
of the contributor when a commit is made.
|
||||
|
||||
## Limit history range
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/423108) in GitLab 16.9.
|
||||
|
||||
In these cases you can constrain the search period by adding `committed_before` and `committed_after` dates as parameters.
|
||||
To do this, add `&` and `committed_before=YYYY-MM-DD` or `committed_after=YYYY-MM-DD` parameters to the URL.
|
||||
|
||||
For example:
|
||||
|
||||
```plaintext
|
||||
https://gitlab.com/gitlab-org/gitlab/-/commits/master/README.md?ref_type=heads&committed_before=2010-11-22&committed_after=2008-05-15
|
||||
```
|
||||
|
||||
Doing this might be necessary to fix [commit history requests timeouts](https://gitlab.com/gitlab-org/gitaly/-/issues/5426)
|
||||
in very large repositories.
|
||||
|
||||
## Associated `git` command
|
||||
|
||||
If you're running `git` from the command line, the equivalent command
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def get_connected_agents_by_agent_ids(agent_ids:)
|
||||
request = Gitlab::Agent::AgentTracker::Rpc::GetConnectedAgentsByAgentIdsRequest.new(agent_ids: agent_ids)
|
||||
request = Gitlab::Agent::AgentTracker::Rpc::GetConnectedAgentsByAgentIDsRequest.new(agent_ids: agent_ids)
|
||||
|
||||
stub_for(:agent_tracker)
|
||||
.get_connected_agents_by_agent_ids(request, metadata: metadata)
|
||||
|
|
|
|||
|
|
@ -49029,6 +49029,9 @@ msgstr ""
|
|||
msgid "Target branch: %{target_branch}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Target project cannot be equal to source project"
|
||||
msgstr ""
|
||||
|
||||
msgid "Target roles"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@ module Gitlab
|
|||
# https://ruby.social/@getajobmike/109326475545816363
|
||||
@max_concurrency = 20
|
||||
@min_concurrency = 0
|
||||
# TODO: to be set to 20 once max_concurrency and min_concurrency is removed https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/2760
|
||||
@concurrency = 0
|
||||
@environment = ENV['RAILS_ENV'] || 'development'
|
||||
@metrics_dir = ENV["prometheus_multiproc_dir"] || File.absolute_path("tmp/prometheus_multiproc_dir/sidekiq")
|
||||
@pid = nil
|
||||
|
|
@ -143,6 +145,7 @@ module Gitlab
|
|||
directory: @rails_path,
|
||||
max_concurrency: @max_concurrency,
|
||||
min_concurrency: @min_concurrency,
|
||||
concurrency: @concurrency,
|
||||
dryrun: @dryrun,
|
||||
timeout: @soft_timeout_seconds
|
||||
)
|
||||
|
|
@ -220,6 +223,10 @@ module Gitlab
|
|||
abort opt.to_s
|
||||
end
|
||||
|
||||
opt.on('-c', '--concurrency INT', 'Number of threads to use with Sidekiq (default: 0)') do |int|
|
||||
@concurrency = int.to_i
|
||||
end
|
||||
|
||||
opt.on('-m', '--max-concurrency INT', 'Maximum threads to use with Sidekiq (default: 20, 0 to disable)') do |int|
|
||||
@max_concurrency = int.to_i
|
||||
end
|
||||
|
|
|
|||
|
|
@ -36,12 +36,13 @@ module Gitlab
|
|||
#
|
||||
# Returns an Array containing the waiter threads (from Process.detach) of
|
||||
# the started processes.
|
||||
def self.start(queues, env: :development, directory: Dir.pwd, max_concurrency: 20, min_concurrency: 0, timeout: DEFAULT_SOFT_TIMEOUT_SECONDS, dryrun: false)
|
||||
def self.start(queues, env: :development, directory: Dir.pwd, max_concurrency: 20, min_concurrency: 0, concurrency: 0, timeout: DEFAULT_SOFT_TIMEOUT_SECONDS, dryrun: false)
|
||||
queues.map.with_index do |pair, index|
|
||||
start_sidekiq(pair, env: env,
|
||||
directory: directory,
|
||||
max_concurrency: max_concurrency,
|
||||
min_concurrency: min_concurrency,
|
||||
concurrency: concurrency,
|
||||
worker_id: index,
|
||||
timeout: timeout,
|
||||
dryrun: dryrun)
|
||||
|
|
@ -51,11 +52,13 @@ module Gitlab
|
|||
# Starts a Sidekiq process that processes _only_ the given queues.
|
||||
#
|
||||
# Returns the PID of the started process.
|
||||
def self.start_sidekiq(queues, env:, directory:, max_concurrency:, min_concurrency:, worker_id:, timeout:, dryrun:)
|
||||
# rubocop: disable Metrics/ParameterLists -- max_concurrency and min_concurrency will be removed in 17.0
|
||||
def self.start_sidekiq(queues, env:, directory:, max_concurrency:, min_concurrency:, concurrency:, worker_id:, timeout:, dryrun:)
|
||||
# rubocop: enable Metrics/ParameterLists
|
||||
counts = count_by_queue(queues)
|
||||
|
||||
cmd = %w[bundle exec sidekiq]
|
||||
cmd << "-c#{self.concurrency(queues, min_concurrency, max_concurrency)}"
|
||||
cmd << "-c#{self.concurrency(queues, min_concurrency, max_concurrency, concurrency)}"
|
||||
cmd << "-e#{env}"
|
||||
cmd << "-t#{timeout}"
|
||||
cmd << "-gqueues:#{proc_details(counts)}"
|
||||
|
|
@ -101,7 +104,9 @@ module Gitlab
|
|||
end.join(',')
|
||||
end
|
||||
|
||||
def self.concurrency(queues, min_concurrency, max_concurrency)
|
||||
def self.concurrency(queues, min_concurrency, max_concurrency, concurrency)
|
||||
return concurrency if concurrency > 0
|
||||
|
||||
concurrency_from_queues = queues.length + 1
|
||||
max = max_concurrency > 0 ? max_concurrency : concurrency_from_queues
|
||||
min = [min_concurrency, max].min
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ RSpec.describe Gitlab::SidekiqCluster::CLI, feature_category: :gitlab_cli, stub_
|
|||
let(:cli) { described_class.new('/dev/null') }
|
||||
let(:timeout) { Gitlab::SidekiqCluster::DEFAULT_SOFT_TIMEOUT_SECONDS }
|
||||
let(:default_options) do
|
||||
{ env: 'test', directory: Dir.pwd, max_concurrency: 20, min_concurrency: 0, dryrun: false, timeout: timeout }
|
||||
{ env: 'test', directory: Dir.pwd, max_concurrency: 20, min_concurrency: 0, dryrun: false, timeout: timeout, concurrency: 0 }
|
||||
end
|
||||
|
||||
let(:sidekiq_exporter_enabled) { false }
|
||||
|
|
@ -125,6 +125,18 @@ RSpec.describe Gitlab::SidekiqCluster::CLI, feature_category: :gitlab_cli, stub_
|
|||
end
|
||||
end
|
||||
|
||||
context 'with --concurrency flag' do
|
||||
it 'starts Sidekiq workers for specified queues with the fixed concurrency' do
|
||||
expected_queues = [%w[foo bar baz], %w[solo]].each { |queues| queues.concat(described_class::DEFAULT_QUEUES) }
|
||||
expect(Gitlab::SidekiqConfig::CliMethods).to receive(:worker_queues).and_return(%w[foo bar baz])
|
||||
expect(Gitlab::SidekiqCluster).to receive(:start)
|
||||
.with(expected_queues, default_options.merge(concurrency: 2))
|
||||
.and_return([])
|
||||
|
||||
cli.run(%w[foo,bar,baz solo -c 2])
|
||||
end
|
||||
end
|
||||
|
||||
context 'with --timeout flag' do
|
||||
it 'when given', 'starts Sidekiq workers with given timeout' do
|
||||
expect(Gitlab::SidekiqCluster).to receive(:start)
|
||||
|
|
|
|||
|
|
@ -102,6 +102,77 @@ RSpec.describe Projects::CommitsController, feature_category: :source_code_manag
|
|||
end
|
||||
end
|
||||
|
||||
context 'date range' do
|
||||
let(:id) { "master/README.md" }
|
||||
let(:base_repository_params) do
|
||||
{
|
||||
path: "README.md",
|
||||
limit: described_class::COMMITS_DEFAULT_LIMIT,
|
||||
offset: 0
|
||||
}
|
||||
end
|
||||
|
||||
let(:base_request_params) do
|
||||
{
|
||||
namespace_id: project.namespace,
|
||||
project_id: project,
|
||||
id: id
|
||||
}
|
||||
end
|
||||
|
||||
shared_examples 'repository commits call' do
|
||||
it 'passes the correct params' do
|
||||
expect_any_instance_of(Repository).to receive(:commits).with(
|
||||
"master",
|
||||
repository_params
|
||||
).and_call_original
|
||||
|
||||
get :show, params: request_params
|
||||
|
||||
expect(response).to be_successful
|
||||
end
|
||||
end
|
||||
|
||||
context 'when committed_before param' do
|
||||
context 'is valid' do
|
||||
let(:request_params) { base_request_params.merge(committed_before: '2020-01-01') }
|
||||
let(:repository_params) { base_repository_params.merge(before: 1577836800) }
|
||||
|
||||
it_behaves_like 'repository commits call'
|
||||
end
|
||||
|
||||
context 'is invalid' do
|
||||
let(:request_params) { base_request_params.merge(committed_before: 'xxx') }
|
||||
let(:repository_params) { base_repository_params }
|
||||
|
||||
it_behaves_like 'repository commits call'
|
||||
end
|
||||
|
||||
context 'is not provided' do
|
||||
let(:request_params) { base_request_params }
|
||||
let(:repository_params) { base_repository_params }
|
||||
|
||||
it_behaves_like 'repository commits call'
|
||||
end
|
||||
end
|
||||
|
||||
context 'with committed_after param' do
|
||||
context 'is valid' do
|
||||
let(:request_params) { base_request_params.merge(committed_after: '2020-01-01') }
|
||||
let(:repository_params) { base_repository_params.merge(after: 1577836800) }
|
||||
|
||||
it_behaves_like 'repository commits call'
|
||||
end
|
||||
|
||||
context 'is invalid' do
|
||||
let(:request_params) { base_request_params.merge(committed_after: 'xxx') }
|
||||
let(:repository_params) { base_repository_params }
|
||||
|
||||
it_behaves_like 'repository commits call'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'loads tags for commits' do
|
||||
expect_next_instance_of(CommitCollection) do |collection|
|
||||
expect(collection).to receive(:load_tags)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Repositories::ChangelogTagFinder do
|
||||
RSpec.describe Repositories::ChangelogTagFinder, feature_category: :source_code_management do
|
||||
let(:project) { build_stubbed(:project) }
|
||||
let(:finder) { described_class.new(project) }
|
||||
|
||||
|
|
@ -35,6 +35,10 @@ RSpec.describe Repositories::ChangelogTagFinder do
|
|||
expect(finder.execute('1.0.0')).to eq(tag4)
|
||||
expect(finder.execute('0.9.0')).to eq(tag6)
|
||||
expect(finder.execute('0.6.0')).to eq(tag7)
|
||||
|
||||
# with v at the beginning
|
||||
expect(finder.execute('v2.1.0')).to eq(tag3)
|
||||
expect(finder.execute('wrong_version')).to eq(nil)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ describe('BoardApp', () => {
|
|||
mockApollo.clients.defaultClient.cache.writeQuery({
|
||||
query: activeBoardItemQuery,
|
||||
data: {
|
||||
activeBoardItem: issue,
|
||||
activeBoardItem: { ...issue, listId: 'gid://gitlab/List/1' },
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ describe('Board card', () => {
|
|||
mockApollo.clients.defaultClient.cache.writeQuery({
|
||||
query: activeBoardItemQuery,
|
||||
data: {
|
||||
activeBoardItem,
|
||||
activeBoardItem: { ...activeBoardItem, listId: 'gid://gitlab/List/1' },
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -113,7 +113,7 @@ describe('Board card', () => {
|
|||
});
|
||||
|
||||
it('should highlight the card with a correct style when selected', async () => {
|
||||
mountComponent({ activeBoardItem: mockIssue });
|
||||
mountComponent({ activeBoardItem: { ...mockIssue, listId: 'gid://gitlab/List/1' } });
|
||||
await waitForPromises();
|
||||
|
||||
expect(wrapper.classes()).toContain('is-active');
|
||||
|
|
@ -141,6 +141,7 @@ describe('Board card', () => {
|
|||
{},
|
||||
{
|
||||
boardItem: mockIssue,
|
||||
listId: 'gid://gitlab/List/2',
|
||||
},
|
||||
expect.anything(),
|
||||
expect.anything(),
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ describe('BoardContentSidebar', () => {
|
|||
mockApollo.clients.defaultClient.cache.writeQuery({
|
||||
query: activeBoardItemQuery,
|
||||
data: {
|
||||
activeBoardItem: issuable,
|
||||
activeBoardItem: { ...issuable, listId: 'gid://gitlab/List/1' },
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -142,6 +142,7 @@ describe('BoardContentSidebar', () => {
|
|||
{},
|
||||
{
|
||||
boardItem: null,
|
||||
listId: null,
|
||||
},
|
||||
expect.anything(),
|
||||
expect.anything(),
|
||||
|
|
|
|||
|
|
@ -47,8 +47,8 @@ RSpec.describe Gitlab::Kas::Client do
|
|||
|
||||
describe '#get_connected_agents_by_agent_ids' do
|
||||
let(:stub) { instance_double(Gitlab::Agent::AgentTracker::Rpc::AgentTracker::Stub) }
|
||||
let(:request) { instance_double(Gitlab::Agent::AgentTracker::Rpc::GetConnectedAgentsByAgentIdsRequest) }
|
||||
let(:response) { double(Gitlab::Agent::AgentTracker::Rpc::GetConnectedAgentsByAgentIdsResponse, agents: connected_agents) }
|
||||
let(:request) { instance_double(Gitlab::Agent::AgentTracker::Rpc::GetConnectedAgentsByAgentIDsRequest) }
|
||||
let(:response) { double(Gitlab::Agent::AgentTracker::Rpc::GetConnectedAgentsByAgentIDsResponse, agents: connected_agents) }
|
||||
|
||||
let(:connected_agents) { [double] }
|
||||
|
||||
|
|
@ -59,7 +59,7 @@ RSpec.describe Gitlab::Kas::Client do
|
|||
.with('example.kas.internal', :this_channel_is_insecure, timeout: described_class::TIMEOUT)
|
||||
.and_return(stub)
|
||||
|
||||
expect(Gitlab::Agent::AgentTracker::Rpc::GetConnectedAgentsByAgentIdsRequest).to receive(:new)
|
||||
expect(Gitlab::Agent::AgentTracker::Rpc::GetConnectedAgentsByAgentIDsRequest).to receive(:new)
|
||||
.with(agent_ids: [agent.id])
|
||||
.and_return(request)
|
||||
|
||||
|
|
|
|||
|
|
@ -3533,6 +3533,15 @@ RSpec.describe API::Projects, :aggregate_failures, feature_category: :groups_and
|
|||
expect(project_fork_target).not_to be_forked
|
||||
end
|
||||
end
|
||||
|
||||
context 'when fork target and source are the same' do
|
||||
it 'returns an error' do
|
||||
post api("/projects/#{project_fork_target.id}/fork/#{project_fork_target.id}", admin, admin_mode: true)
|
||||
|
||||
expect(response).to have_gitlab_http_status(:bad_request)
|
||||
expect(json_response['message']).to eq 'Target project cannot be equal to source project'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -54,6 +54,17 @@ RSpec.describe CodequalityDegradationEntity, feature_category: :code_quality do
|
|||
expect(subject[:engine_name]).to eq('rubocop')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when severity is a non-codeclimate-standard severity' do
|
||||
# See standard severities: https://docs.codeclimate.com/docs/issues#issue-severity
|
||||
let(:codequality_degradation) { build(:codequality_degradation_3) }
|
||||
|
||||
it 'returns severity as unknown', :aggregate_failures do
|
||||
codequality_degradation[:severity] = 'warning'
|
||||
|
||||
expect(subject[:severity]).to eq('unknown')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ RSpec.describe Ci::ExpirePipelineCacheService, feature_category: :continuous_int
|
|||
let_it_be(:user) { create(:user) }
|
||||
let_it_be(:project) { create(:project) }
|
||||
let_it_be(:pipeline) { create(:ci_pipeline, project: project) }
|
||||
let_it_be(:merge_pipeline) { create(:ci_pipeline, :detached_merge_request_pipeline, project: project) }
|
||||
|
||||
subject { described_class.new }
|
||||
|
||||
|
|
@ -45,6 +46,17 @@ RSpec.describe Ci::ExpirePipelineCacheService, feature_category: :continuous_int
|
|||
subject.execute(merge_request.all_pipelines.last)
|
||||
end
|
||||
|
||||
it 'invalidates Etag caching for merge request that pipeline runs on its merged commit' do
|
||||
merge_request = create(:merge_request, merge_commit_sha: pipeline.sha, source_project: pipeline.project)
|
||||
project = merge_request.target_project
|
||||
|
||||
merge_request_widget_path = "/#{project.full_path}/-/merge_requests/#{merge_request.iid}/cached_widget.json"
|
||||
|
||||
expect_touched_etag_caching_paths(merge_request_widget_path)
|
||||
|
||||
subject.execute(pipeline)
|
||||
end
|
||||
|
||||
it 'updates the cached status for a project' do
|
||||
expect(Gitlab::Cache::Ci::ProjectPipelineStatus).to receive(:update_for_pipeline).with(pipeline)
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,8 @@ RSpec.describe Gitlab::SidekiqCluster do # rubocop:disable RSpec/FilePath
|
|||
min_concurrency: 0,
|
||||
worker_id: an_instance_of(Integer),
|
||||
timeout: 25,
|
||||
dryrun: false
|
||||
dryrun: false,
|
||||
concurrency: 0
|
||||
}
|
||||
|
||||
expect(described_class).to receive(:start_sidekiq).ordered.with(%w[foo bar baz], expected_options)
|
||||
|
|
@ -55,7 +56,7 @@ RSpec.describe Gitlab::SidekiqCluster do # rubocop:disable RSpec/FilePath
|
|||
describe '.start_sidekiq' do
|
||||
let(:first_worker_id) { 0 }
|
||||
let(:options) do
|
||||
{ env: :production, directory: 'foo/bar', max_concurrency: 20, min_concurrency: 0, worker_id: first_worker_id, timeout: 10, dryrun: false }
|
||||
{ env: :production, directory: 'foo/bar', max_concurrency: 20, min_concurrency: 0, worker_id: first_worker_id, timeout: 10, dryrun: false, concurrency: 0 }
|
||||
end
|
||||
|
||||
let(:env) { { "ENABLE_SIDEKIQ_CLUSTER" => "1", "SIDEKIQ_WORKER_ID" => first_worker_id.to_s } }
|
||||
|
|
@ -102,21 +103,28 @@ RSpec.describe Gitlab::SidekiqCluster do # rubocop:disable RSpec/FilePath
|
|||
describe '.concurrency' do
|
||||
using RSpec::Parameterized::TableSyntax
|
||||
|
||||
where(:queue_count, :min, :max, :expected) do
|
||||
2 | 0 | 0 | 3 # No min or max specified
|
||||
2 | 0 | 9 | 3 # No min specified, value < max
|
||||
2 | 1 | 4 | 3 # Value between min and max
|
||||
2 | 4 | 5 | 4 # Value below range
|
||||
5 | 2 | 3 | 3 # Value above range
|
||||
2 | 1 | 1 | 1 # Value above explicit setting (min == max)
|
||||
0 | 3 | 3 | 3 # Value below explicit setting (min == max)
|
||||
1 | 4 | 3 | 3 # Min greater than max
|
||||
where(:queue_count, :min, :max, :fixed_concurrency, :expected) do
|
||||
# without fixed concurrency
|
||||
2 | 0 | 0 | 0 | 3 # No min or max specified
|
||||
2 | 0 | 9 | 0 | 3 # No min specified, value < max
|
||||
2 | 1 | 4 | 0 | 3 # Value between min and max
|
||||
2 | 4 | 5 | 0 | 4 # Value below range
|
||||
5 | 2 | 3 | 0 | 3 # Value above range
|
||||
2 | 1 | 1 | 0 | 1 # Value above explicit setting (min == max)
|
||||
0 | 3 | 3 | 0 | 3 # Value below explicit setting (min == max)
|
||||
1 | 4 | 3 | 0 | 3 # Min greater than max
|
||||
|
||||
# with fixed concurrency, expected always equal to fixed_concurrency
|
||||
1 | 0 | 20 | 20 | 20
|
||||
1 | 0 | 20 | 10 | 10
|
||||
1 | 20 | 20 | 10 | 10
|
||||
5 | 0 | 0 | 10 | 10
|
||||
end
|
||||
|
||||
with_them do
|
||||
let(:queues) { Array.new(queue_count) }
|
||||
|
||||
it { expect(described_class.concurrency(queues, min, max)).to eq(expected) }
|
||||
it { expect(described_class.concurrency(queues, min, max, fixed_concurrency)).to eq(expected) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ require (
|
|||
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.1
|
||||
github.com/BurntSushi/toml v1.3.2
|
||||
github.com/alecthomas/chroma/v2 v2.12.0
|
||||
github.com/aws/aws-sdk-go v1.49.3
|
||||
github.com/aws/aws-sdk-go v1.50.7
|
||||
github.com/disintegration/imaging v1.6.2
|
||||
github.com/getsentry/raven-go v0.2.0
|
||||
github.com/golang-jwt/jwt/v5 v5.2.0
|
||||
|
|
|
|||
|
|
@ -94,8 +94,8 @@ github.com/alecthomas/chroma/v2 v2.12.0/go.mod h1:4TQu7gdfuPjSh76j78ietmqh9LiurG
|
|||
github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/aws/aws-sdk-go v1.44.256/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
|
||||
github.com/aws/aws-sdk-go v1.49.3 h1:+UGwhC3kChk0pRCxSsbaQSNIc8MfFURQL44Ig6RRR3I=
|
||||
github.com/aws/aws-sdk-go v1.49.3/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk=
|
||||
github.com/aws/aws-sdk-go v1.50.7 h1:odKb+uneeGgF2jgAerKjFzpljiyZxleV4SHB7oBK+YA=
|
||||
github.com/aws/aws-sdk-go v1.50.7/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk=
|
||||
github.com/aws/aws-sdk-go-v2 v1.24.0 h1:890+mqQ+hTpNuw0gGP6/4akolQkSToDJgHfQE7AwGuk=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4 h1:OCs21ST2LrepDfD3lwlQiOqIGp6JiEUqG84GzTDoyJs=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.26.1 h1:z6DqMxclFGL3Zfo+4Q0rLnAZ6yVkzCRxhRMsiRQnD1o=
|
||||
|
|
|
|||
Loading…
Reference in New Issue