Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-11-11 06:09:30 +00:00
parent 48b4860d60
commit 75ef798ebc
19 changed files with 194 additions and 47 deletions

View File

@ -86,7 +86,7 @@ gem 'timfel-krb5-auth', '~> 0.8', group: :kerberos
# Spam and anti-bot protection
gem 'recaptcha', '~> 4.11', require: 'recaptcha/rails'
gem 'akismet', '~> 3.0'
gem 'invisible_captcha', '~> 1.1.0'
gem 'invisible_captcha', '~> 2.0.0'
# Two-factor authentication
gem 'devise-two-factor', '~> 4.0.2'

View File

@ -288,7 +288,7 @@
{"name":"icalendar","version":"2.8.0","platform":"ruby","checksum":"e404f970c7572bdebf6f09f9890970b68aab400ba9e609dc7d46098f28d0ee87"},
{"name":"ice_cube","version":"0.16.4","platform":"ruby","checksum":"da117e5de24bdc33931be629f9b55048641924442c7e9b72fedc05e5592531b7"},
{"name":"imagen","version":"0.1.8","platform":"ruby","checksum":"fde7b727d4fe79c6bb5ac46c1f7184bf87a6d54df54d712ad2be039d2f93a162"},
{"name":"invisible_captcha","version":"1.1.0","platform":"ruby","checksum":"3670294a998ab1430ff07cd1697d25c70e6367bdb0dff534df24a14fdee8b4d2"},
{"name":"invisible_captcha","version":"2.0.0","platform":"ruby","checksum":"a381edcb1d1b8744e9dc398ecad142c3e2ab077604645f85eeb02f9ea535c042"},
{"name":"ipaddr","version":"1.2.2","platform":"ruby","checksum":"27916ee6367d549850d3675bc020f1f1ddafbbe1cfc58635f17dfa56c42f9f79"},
{"name":"ipaddress","version":"0.8.3","platform":"ruby","checksum":"85640c4f9194c26937afc8c78e3074a8e7c97d5d1210358d1440f01034d006f5"},
{"name":"jaeger-client","version":"1.1.0","platform":"ruby","checksum":"cb5e9b9bbee6ee8d6a82d03d947a5b04543d8c0a949c22e484254f18d8a458a8"},

View File

@ -776,8 +776,8 @@ GEM
ice_cube (0.16.4)
imagen (0.1.8)
parser (>= 2.5, != 2.5.1.1)
invisible_captcha (1.1.0)
rails (>= 4.2)
invisible_captcha (2.0.0)
rails (>= 5.0)
ipaddr (1.2.2)
ipaddress (0.8.3)
jaeger-client (1.1.0)
@ -1701,7 +1701,7 @@ DEPENDENCIES
html2text
httparty (~> 0.20.0)
icalendar
invisible_captcha (~> 1.1.0)
invisible_captcha (~> 2.0.0)
ipaddr (= 1.2.2)
ipaddress (~> 0.8.3)
ipynbdiff!

View File

@ -6,7 +6,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Broadcast Messages API **(FREE SELF)**
> `target_access_levels` [introduced](https://gitlab.com/gitlab-org/growth/team-tasks/-/issues/461) in GitLab 14.8 [with a flag](../administration/feature_flags.md) named `role_targeted_broadcast_messages`. Disabled by default.
- > `target_access_levels` [introduced](https://gitlab.com/gitlab-org/growth/team-tasks/-/issues/461) in GitLab 14.8 [with a flag](../administration/feature_flags.md) named `role_targeted_broadcast_messages`. Disabled by default.
- > `color` parameter [removed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/95829) in GitLab 15.6.
Broadcast messages API operates on [broadcast messages](../user/admin_area/broadcast_messages.md).
@ -37,7 +38,6 @@ Example response:
"message":"Example broadcast message",
"starts_at":"2016-08-24T23:21:16.078Z",
"ends_at":"2016-08-26T23:21:16.080Z",
"color":"#E75E40",
"font":"#FFFFFF",
"id":1,
"active": false,
@ -76,7 +76,6 @@ Example response:
"message":"Deploy in progress",
"starts_at":"2016-08-24T23:21:16.078Z",
"ends_at":"2016-08-26T23:21:16.080Z",
"color":"#cecece",
"font":"#FFFFFF",
"id":1,
"active":false,
@ -102,7 +101,6 @@ Parameters:
| `message` | string | yes | Message to display. |
| `starts_at` | datetime | no | Starting time (defaults to current time in UTC). Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `ends_at` | datetime | no | Ending time (defaults to one hour from current time in UTC). Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `color` | string | no | Background color hex code. |
| `font` | string | no | Foreground color hex code. |
| `target_access_levels` | array of integers | no | Target access levels (roles) of the broadcast message.|
| `target_path` | string | no | Target path of the broadcast message. |
@ -121,7 +119,7 @@ following levels are valid:
Example request:
```shell
curl --data "message=Deploy in progress&color=#cecece&target_access_levels[]=10&target_access_levels[]=30" \
curl --data "message=Deploy in progress&target_access_levels[]=10&target_access_levels[]=30" \
--header "PRIVATE-TOKEN: <your_access_token>" \
"https://gitlab.example.com/api/v4/broadcast_messages"
```
@ -133,7 +131,6 @@ Example response:
"message":"Deploy in progress",
"starts_at":"2016-08-26T00:41:35.060Z",
"ends_at":"2016-08-26T01:41:35.060Z",
"color":"#cecece",
"font":"#FFFFFF",
"id":1,
"active": true,
@ -160,7 +157,6 @@ Parameters:
| `message` | string | no | Message to display. |
| `starts_at` | datetime | no | Starting time (UTC). Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `ends_at` | datetime | no | Ending time (UTC). Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `color` | string | no | Background color hex code. |
| `font` | string | no | Foreground color hex code. |
| `target_access_levels` | array of integers | no | Target access levels (roles) of the broadcast message.|
| `target_path` | string | no | Target path of the broadcast message. |
@ -179,7 +175,7 @@ following levels are valid:
Example request:
```shell
curl --request PUT --data "message=Update message&color=#000" \
curl --request PUT --data "message=Update message" \
--header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/broadcast_messages/1"
```
@ -190,7 +186,6 @@ Example response:
"message":"Update message",
"starts_at":"2016-08-26T00:41:35.060Z",
"ends_at":"2016-08-26T01:41:35.060Z",
"color":"#000",
"font":"#FFFFFF",
"id":1,
"active": true,

View File

@ -111,20 +111,21 @@ percentage of time.
POST /features/:name
```
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `name` | string | yes | Name of the feature to create or update |
| `value` | integer/string | yes | `true` or `false` to enable/disable, or an integer for percentage of time |
| `key` | string | no | `percentage_of_actors` or `percentage_of_time` (default) |
| `feature_group` | string | no | A Feature group name |
| `user` | string | no | A GitLab username or comma-separated multiple usernames |
| `group` | string | no | A GitLab group's path, for example `gitlab-org`, or comma-separated multiple group paths |
| `namespace` | string | no | A GitLab group or user namespace's path, for example `john-doe`, or comma-separated multiple namespace paths. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/353117) in GitLab 15.0. |
| `project` | string | no | A projects path, for example `gitlab-org/gitlab-foss`, or comma-separated multiple project paths |
| `force` | boolean | no | Skip feature flag validation checks, such as a YAML definition |
| Attribute | Type | Required | Description |
|-----------------|----------------|----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `name` | string | yes | Name of the feature to create or update |
| `value` | integer/string | yes | `true` or `false` to enable/disable, or an integer for percentage of time |
| `key` | string | no | `percentage_of_actors` or `percentage_of_time` (default) |
| `feature_group` | string | no | A Feature group name |
| `user` | string | no | A GitLab username or comma-separated multiple usernames |
| `group` | string | no | A GitLab group's path, for example `gitlab-org`, or comma-separated multiple group paths |
| `namespace` | string | no | A GitLab group or user namespace's path, for example `john-doe`, or comma-separated multiple namespace paths. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/353117) in GitLab 15.0. |
| `project` | string | no | A projects path, for example `gitlab-org/gitlab-foss`, or comma-separated multiple project paths |
| `repository` | string | no | A repository path, for example `gitlab-org/gitlab-test.git`, `gitlab-org/gitlab-test.wiki.git`, , `snippets/21.git`, to name a few. Use comma to separate multiple repository paths |
| `force` | boolean | no | Skip feature flag validation checks, such as a YAML definition |
You can enable or disable a feature for a `feature_group`, a `user`,
a `group`, a `namespace` and a `project` in a single API call.
a `group`, a `namespace`, a `project`, and a `repository` in a single API call.
```shell
curl --data "value=30" --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/features/new_library"

View File

@ -16348,6 +16348,18 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="pipelinejobssecurityreporttypes"></a>`securityReportTypes` | [`[SecurityReportTypeEnum!]`](#securityreporttypeenum) | Filter jobs by the type of security report they produce. |
| <a id="pipelinejobsstatuses"></a>`statuses` | [`[CiJobStatus!]`](#cijobstatus) | Filter jobs by status. |
##### `Pipeline.securityReportFinding`
Vulnerability finding reported on the pipeline.
Returns [`PipelineSecurityReportFinding`](#pipelinesecurityreportfinding).
###### Arguments
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="pipelinesecurityreportfindinguuid"></a>`uuid` | [`String!`](#string) | UUID of the security report finding. |
##### `Pipeline.securityReportFindings`
Vulnerability findings reported on the pipeline.

View File

@ -232,6 +232,7 @@ module API
mount ::API::Tags
mount ::API::Unleash
mount ::API::UserCounts
mount ::API::Wikis
add_open_api_documentation!
end
@ -329,7 +330,6 @@ module API
mount ::API::UsageDataNonSqlMetrics
mount ::API::UsageDataQueries
mount ::API::Users
mount ::API::Wikis
mount ::API::Ml::Mlflow
end

View File

@ -5,12 +5,16 @@ module API
class WikiAttachment < Grape::Entity
include Gitlab::FileMarkdownLinkBuilder
expose :file_name
expose :file_path
expose :branch
expose :file_name, documentation: { type: 'string', example: 'dk.png' }
expose :file_path, documentation: { type: 'string', example: 'uploads/6a061c4cf9f1c28cb22c384b4b8d4e3c/dk.png' }
expose :branch, documentation: { type: 'string', example: 'main' }
expose :link do
expose :file_path, as: :url
expose :markdown do |_entity|
expose :file_path, as: :url, documentation: {
type: 'string', example: 'uploads/6a061c4cf9f1c28cb22c384b4b8d4e3c/dk.png'
}
expose :markdown, documentation: {
type: 'string', example: '![dk](uploads/6a061c4cf9f1c28cb22c384b4b8d4e3c/dk.png)'
} do |_entity|
self.markdown_link
end
end

View File

@ -5,7 +5,9 @@ module API
class WikiPage < WikiPageBasic
include ::MarkupHelper
expose :content do |wiki_page, options|
expose :content, documentation: {
type: 'string', example: 'Here is an instruction how to deploy this project.'
} do |wiki_page, options|
if options[:render_html]
render_wiki_content(
wiki_page,
@ -17,7 +19,7 @@ module API
end
end
expose :encoding do |wiki_page|
expose :encoding, documentation: { type: 'string', example: 'UTF-8' } do |wiki_page|
wiki_page.content.encoding.name
end
end

View File

@ -3,9 +3,9 @@
module API
module Entities
class WikiPageBasic < Grape::Entity
expose :format
expose :slug
expose :title
expose :format, documentation: { type: 'string', example: 'markdown' }
expose :slug, documentation: { type: 'string', example: 'deploy' }
expose :title, documentation: { type: 'string', example: 'deploy' }
end
end
end

View File

@ -96,6 +96,10 @@ module API
optional :project,
type: String,
desc: "A projects path, for example `gitlab-org/gitlab-foss`, or comma-separated multiple project paths"
optional :repository,
type: String,
desc: "A repository path, for example `gitlab-org/gitlab-test.git`, `gitlab-org/gitlab-test.wiki.git`, " \
"`snippets/21.git`, to name a few. Use comma to separate multiple repository paths"
optional :force, type: Boolean, desc: 'Skip feature flag validation checks, such as a YAML definition'
mutually_exclusive :key, :feature_group
@ -103,6 +107,7 @@ module API
mutually_exclusive :key, :group
mutually_exclusive :key, :namespace
mutually_exclusive :key, :project
mutually_exclusive :key, :repository
end
post ':name' do
if Feature.enabled?(:set_feature_flag_service)

View File

@ -28,6 +28,11 @@ module API
desc 'Get a list of wiki pages' do
success Entities::WikiPageBasic
failure [
{ code: 404, message: 'Not found' }
]
tags %w[wikis]
is_array true
end
params do
optional :with_content, type: Boolean, default: false, desc: "Include pages' content"
@ -47,6 +52,10 @@ module API
desc 'Get a wiki page' do
success Entities::WikiPage
failure [
{ code: 404, message: 'Not found' }
]
tags %w[wikis]
end
params do
requires :slug, type: String, desc: 'The slug of a wiki page'
@ -67,6 +76,12 @@ module API
desc 'Create a wiki page' do
success Entities::WikiPage
failure [
{ code: 400, message: 'Validation error' },
{ code: 404, message: 'Not found' },
{ code: 422, message: 'Unprocessable entity' }
]
tags %w[wikis]
end
params do
requires :title, type: String, desc: 'Title of a wiki page'
@ -88,6 +103,12 @@ module API
desc 'Update a wiki page' do
success Entities::WikiPage
failure [
{ code: 400, message: 'Validation error' },
{ code: 404, message: 'Not found' },
{ code: 422, message: 'Unprocessable entity' }
]
tags %w[wikis]
end
params do
optional :title, type: String, desc: 'Title of a wiki page'
@ -110,7 +131,14 @@ module API
end
end
desc 'Delete a wiki page'
desc 'Delete a wiki page' do
success code: 204
failure [
{ code: 400, message: 'Validation error' },
{ code: 404, message: 'Not found' }
]
tags %w[wikis]
end
params do
requires :slug, type: String, desc: 'The slug of a wiki page'
end
@ -131,6 +159,10 @@ module API
desc 'Upload an attachment to the wiki repository' do
detail 'This feature was introduced in GitLab 11.3.'
success Entities::WikiAttachment
failure [
{ code: 404, message: 'Not found' }
]
tags %w[wikis]
end
params do
requires :file, types: [Rack::Multipart::UploadedFile, ::API::Validations::Types::WorkhorseFile], desc: 'The attachment file to be uploaded', documentation: { type: 'file' }

View File

@ -301,11 +301,11 @@ module Feature
end
def gate_specified?
%i(user project group feature_group namespace).any? { |key| params.key?(key) }
%i(user project group feature_group namespace repository).any? { |key| params.key?(key) }
end
def targets
[feature_group, users, projects, groups, namespaces].flatten.compact
[feature_group, users, projects, groups, namespaces, repositories].flatten.compact
end
private
@ -350,6 +350,17 @@ module Feature
Namespace.without_project_namespaces.find_by_full_path(arg) || (raise UnknowTargetError, "#{arg} is not found!")
end
end
def repositories
return unless params.key?(:repository)
params[:repository].split(',').map do |arg|
container, _project, _type, _path = Gitlab::RepoPath.parse(arg)
raise UnknowTargetError, "#{arg} is not found!" if container.nil?
container.repository
end
end
end
end

View File

@ -2,7 +2,7 @@
source 'https://rubygems.org'
gem 'gitlab-qa', '~> 8', '>= 8.10.1', require: 'gitlab/qa'
gem 'gitlab-qa', '~> 8', '>= 8.10.2', require: 'gitlab/qa'
gem 'activesupport', '~> 6.1.4.7' # This should stay in sync with the root's Gemfile
gem 'allure-rspec', '~> 2.19.0'
gem 'capybara', '~> 3.38.0'

View File

@ -100,7 +100,7 @@ GEM
gitlab (4.18.0)
httparty (~> 0.18)
terminal-table (>= 1.5.1)
gitlab-qa (8.10.1)
gitlab-qa (8.10.2)
activesupport (~> 6.1)
gitlab (~> 4.18.0)
http (~> 5.0)
@ -311,7 +311,7 @@ DEPENDENCIES
faraday-retry (~> 2.0)
fog-core (= 2.1.0)
fog-google (~> 1.19)
gitlab-qa (~> 8, >= 8.10.1)
gitlab-qa (~> 8, >= 8.10.2)
influxdb-client (~> 2.8)
knapsack (~> 4.0)
nokogiri (~> 1.13, >= 1.13.9)

View File

@ -18,7 +18,10 @@ RSpec.describe Types::Ci::PipelineType do
]
if Gitlab.ee?
expected_fields += %w[security_report_summary security_report_findings code_quality_reports dast_profile]
expected_fields += %w[
security_report_summary security_report_findings security_report_finding
code_quality_reports dast_profile
]
end
expect(described_class).to have_graphql_fields(*expected_fields)

View File

@ -790,11 +790,47 @@ RSpec.describe Feature, stub_feature_flags: false do
let(:group) { create(:group) }
let(:user_name) { project.first_owner.username }
subject { described_class.new(user: user_name, project: project.full_path, group: group.full_path) }
subject do
described_class.new(
user: user_name,
project: project.full_path,
group: group.full_path,
repository: project.repository.full_path
)
end
it 'returns all found targets' do
expect(subject.targets).to be_an(Array)
expect(subject.targets).to eq([project.first_owner, project, group])
expect(subject.targets).to eq([project.first_owner, project, group, project.repository])
end
context 'when repository target works with different types of repositories' do
let_it_be(:group) { create(:group) }
let_it_be(:project) { create(:project, :wiki_repo, group: group) }
let_it_be(:project_in_user_namespace) { create(:project, namespace: create(:user).namespace) }
let(:personal_snippet) { create(:personal_snippet) }
let(:project_snippet) { create(:project_snippet, project: project) }
let(:targets) do
[
project,
project.wiki,
project_in_user_namespace,
personal_snippet,
project_snippet
]
end
subject do
described_class.new(
repository: targets.map { |t| t.repository.full_path }.join(",")
)
end
it 'returns all found targets' do
expect(subject.targets).to be_an(Array)
expect(subject.targets).to eq(targets.map(&:repository))
end
end
end
end

View File

@ -193,7 +193,7 @@ RSpec.describe API::Features, stub_feature_flags: false do
'state' => 'conditional',
'gates' => [
{ 'key' => 'boolean', 'value' => false },
{ 'key' => 'actors', 'value' => ["#{actor.class}:#{actor.id}"] }
{ 'key' => 'actors', 'value' => [actor.flipper_id] }
],
'definition' => known_feature_flag_definition_hash
)
@ -269,6 +269,20 @@ RSpec.describe API::Features, stub_feature_flags: false do
end
end
context 'when enabling for a repository by path' do
context 'when the repository exists' do
it_behaves_like 'enables the flag for the actor', :repository do
let_it_be(:actor) { create(:project).repository }
end
end
context 'when the repository does not exist' do
it_behaves_like 'does not enable the flag', :repository do
let(:actor_path) { 'not/a/repository' }
end
end
end
context 'with multiple users' do
let_it_be(:users) { create_list(:user, 3) }
@ -361,6 +375,29 @@ RSpec.describe API::Features, stub_feature_flags: false do
end
end
context 'with multiple repository' do
let_it_be(:projects) { create_list(:project, 3) }
it_behaves_like 'creates an enabled feature for the specified entries' do
let(:gate_params) { { repository: projects.map { |p| p.repository.full_path }.join(',') } }
let(:expected_gate_params) { projects.map { |p| p.repository.flipper_id } }
end
context 'when empty value exists between comma' do
it_behaves_like 'creates an enabled feature for the specified entries' do
let(:gate_params) { { repository: "#{projects.first.repository.full_path},,,," } }
let(:expected_gate_params) { projects.first.repository.flipper_id }
end
end
context 'when one of the projects does not exist' do
it_behaves_like 'does not enable the flag', :project do
let(:actor_path) { "#{projects.first.repository.full_path},inexistent-entry" }
let(:expected_inexistent_path) { "inexistent-entry" }
end
end
end
it 'creates a feature with the given percentage of time if passed an integer' do
post api("/features/#{feature_name}", admin), params: { value: '50' }

View File

@ -130,6 +130,15 @@ RSpec.describe Admin::SetFeatureFlagService do
end
end
context 'when enabling for a repository' do
let(:params) { { value: 'true', repository: project.repository.full_path } }
it 'enables the feature flag' do
expect(Feature).to receive(:enable).with(feature_name, project.repository)
expect(subject).to be_success
end
end
context 'when enabling for a user actor and a feature group' do
let(:params) { { value: 'true', user: user.username, feature_group: 'perf_team' } }
let(:feature_group) { Feature.group('perf_team') }