Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
a1e4372fbf
commit
223ffc2e59
|
|
@ -1 +1 @@
|
|||
e0204f0c2b736bb4b72f622c64bbf8220ede14bc
|
||||
3bec5af36c5d3304174566c706807806eee8996d
|
||||
|
|
|
|||
2
Gemfile
2
Gemfile
|
|
@ -303,7 +303,7 @@ gem 'gitlab-sidekiq-fetcher',
|
|||
gem 'fugit', '~> 1.11.1', feature_category: :continuous_integration
|
||||
|
||||
# HTTP requests
|
||||
gem 'httparty', '~> 0.21.0', feature_category: :shared
|
||||
gem 'httparty', '~> 0.22.0', feature_category: :shared
|
||||
|
||||
# Colored output to console
|
||||
gem 'rainbow', '~> 3.0', feature_category: :shared
|
||||
|
|
|
|||
|
|
@ -330,7 +330,7 @@
|
|||
{"name":"http-accept","version":"1.7.0","platform":"ruby","checksum":"c626860682bfbb3b46462f8c39cd470fd7b0584f61b3cc9df5b2e9eb9972a126"},
|
||||
{"name":"http-cookie","version":"1.0.5","platform":"ruby","checksum":"73756d46c7dbdc7023deecdb8a171348ea95a1b99810b31cfe8b4fb4e9a6318f"},
|
||||
{"name":"http-form_data","version":"2.3.0","platform":"ruby","checksum":"cc4eeb1361d9876821e31d7b1cf0b68f1cf874b201d27903480479d86448a5f3"},
|
||||
{"name":"httparty","version":"0.21.0","platform":"ruby","checksum":"00ef7bf9a71f30a3bff88edeb5b16a34bea883ab67c246b3f0db2d6794fe1214"},
|
||||
{"name":"httparty","version":"0.22.0","platform":"ruby","checksum":"78652a5c9471cf0093d3b2083c2295c9c8f12b44c65112f1846af2b71430fa6c"},
|
||||
{"name":"httpclient","version":"2.8.3","platform":"ruby","checksum":"2951e4991214464c3e92107e46438527d23048e634f3aee91c719e0bdfaebda6"},
|
||||
{"name":"i18n","version":"1.14.4","platform":"ruby","checksum":"c7deedead0866ea9102975a4eab7968f53de50793a0c211a37808f75dd187551"},
|
||||
{"name":"i18n_data","version":"0.13.1","platform":"ruby","checksum":"e5aa99b09a69b463bb0443fc1f9540351a49f3d1541c5e91316bafa035c63f66"},
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ PATH
|
|||
gitlab-http (0.1.0)
|
||||
activesupport (~> 7)
|
||||
concurrent-ruby (~> 1.2)
|
||||
httparty (~> 0.21.0)
|
||||
httparty (~> 0.21)
|
||||
ipaddress (~> 0.8.3)
|
||||
net-http (= 0.6.0)
|
||||
railties (~> 7)
|
||||
|
|
@ -1015,7 +1015,8 @@ GEM
|
|||
http-cookie (1.0.5)
|
||||
domain_name (~> 0.5)
|
||||
http-form_data (2.3.0)
|
||||
httparty (0.21.0)
|
||||
httparty (0.22.0)
|
||||
csv
|
||||
mini_mime (>= 1.0.0)
|
||||
multi_xml (>= 0.5.2)
|
||||
httpclient (2.8.3)
|
||||
|
|
@ -2161,7 +2162,7 @@ DEPENDENCIES
|
|||
health_check (~> 3.0)
|
||||
html-pipeline (~> 2.14.3)
|
||||
html2text
|
||||
httparty (~> 0.21.0)
|
||||
httparty (~> 0.22.0)
|
||||
i18n_data (~> 0.13.1)
|
||||
icalendar (~> 2.10.1)
|
||||
influxdb-client (~> 3.1)
|
||||
|
|
@ -2363,4 +2364,4 @@ DEPENDENCIES
|
|||
yajl-ruby (~> 1.4.3)
|
||||
|
||||
BUNDLED WITH
|
||||
2.5.11
|
||||
2.6.5
|
||||
|
|
|
|||
|
|
@ -330,7 +330,7 @@
|
|||
{"name":"http-accept","version":"1.7.0","platform":"ruby","checksum":"c626860682bfbb3b46462f8c39cd470fd7b0584f61b3cc9df5b2e9eb9972a126"},
|
||||
{"name":"http-cookie","version":"1.0.5","platform":"ruby","checksum":"73756d46c7dbdc7023deecdb8a171348ea95a1b99810b31cfe8b4fb4e9a6318f"},
|
||||
{"name":"http-form_data","version":"2.3.0","platform":"ruby","checksum":"cc4eeb1361d9876821e31d7b1cf0b68f1cf874b201d27903480479d86448a5f3"},
|
||||
{"name":"httparty","version":"0.21.0","platform":"ruby","checksum":"00ef7bf9a71f30a3bff88edeb5b16a34bea883ab67c246b3f0db2d6794fe1214"},
|
||||
{"name":"httparty","version":"0.22.0","platform":"ruby","checksum":"78652a5c9471cf0093d3b2083c2295c9c8f12b44c65112f1846af2b71430fa6c"},
|
||||
{"name":"httpclient","version":"2.8.3","platform":"ruby","checksum":"2951e4991214464c3e92107e46438527d23048e634f3aee91c719e0bdfaebda6"},
|
||||
{"name":"i18n","version":"1.14.4","platform":"ruby","checksum":"c7deedead0866ea9102975a4eab7968f53de50793a0c211a37808f75dd187551"},
|
||||
{"name":"i18n_data","version":"0.13.1","platform":"ruby","checksum":"e5aa99b09a69b463bb0443fc1f9540351a49f3d1541c5e91316bafa035c63f66"},
|
||||
|
|
@ -802,8 +802,8 @@
|
|||
{"name":"webmock","version":"3.25.0","platform":"ruby","checksum":"573c23fc4887008c830f22da588db339ca38b6d59856fd57f5a068959474198e"},
|
||||
{"name":"webrick","version":"1.8.2","platform":"ruby","checksum":"431746a349199546ff9dd272cae10849c865f938216e41c402a6489248f12f21"},
|
||||
{"name":"websocket","version":"1.2.10","platform":"ruby","checksum":"2cc1a4a79b6e63637b326b4273e46adcddf7871caa5dc5711f2ca4061a629fa8"},
|
||||
{"name":"websocket-driver","version":"0.7.7","platform":"java","checksum":"e2520a6049feb88691e042d631063fa96d50620fb7f53b30180ae6fb2cf75eb1"},
|
||||
{"name":"websocket-driver","version":"0.7.7","platform":"ruby","checksum":"056d99f2cd545712cfb1291650fde7478e4f2661dc1db6a0fa3b966231a146b4"},
|
||||
{"name":"websocket-driver","version":"0.7.6","platform":"java","checksum":"bc894b9e9d5aee55ac04b61003e1957c4ef411a5a048199587d0499785b505c3"},
|
||||
{"name":"websocket-driver","version":"0.7.6","platform":"ruby","checksum":"f69400be7bc197879726ad8e6f5869a61823147372fd8928836a53c2c741d0db"},
|
||||
{"name":"websocket-extensions","version":"0.1.5","platform":"ruby","checksum":"1c6ba63092cda343eb53fc657110c71c754c56484aad42578495227d717a8241"},
|
||||
{"name":"wikicloth","version":"0.8.1","platform":"ruby","checksum":"7ac8a9ca0a948cf472851e521afc6c2a6b04a8f91ef1d824ba6a61ffbd60e6ca"},
|
||||
{"name":"wisper","version":"2.0.1","platform":"ruby","checksum":"ce17bc5c3a166f241a2e6613848b025c8146fce2defba505920c1d1f3f88fae6"},
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ PATH
|
|||
gitlab-http (0.1.0)
|
||||
activesupport (~> 7)
|
||||
concurrent-ruby (~> 1.2)
|
||||
httparty (~> 0.21.0)
|
||||
httparty (~> 0.21)
|
||||
ipaddress (~> 0.8.3)
|
||||
net-http (= 0.6.0)
|
||||
railties (~> 7)
|
||||
|
|
@ -1027,7 +1027,8 @@ GEM
|
|||
http-cookie (1.0.5)
|
||||
domain_name (~> 0.5)
|
||||
http-form_data (2.3.0)
|
||||
httparty (0.21.0)
|
||||
httparty (0.22.0)
|
||||
csv
|
||||
mini_mime (>= 1.0.0)
|
||||
multi_xml (>= 0.5.2)
|
||||
httpclient (2.8.3)
|
||||
|
|
@ -2007,8 +2008,7 @@ GEM
|
|||
hashdiff (>= 0.4.0, < 2.0.0)
|
||||
webrick (1.8.2)
|
||||
websocket (1.2.10)
|
||||
websocket-driver (0.7.7)
|
||||
base64
|
||||
websocket-driver (0.7.6)
|
||||
websocket-extensions (>= 0.1.0)
|
||||
websocket-extensions (0.1.5)
|
||||
wikicloth (0.8.1)
|
||||
|
|
@ -2196,7 +2196,7 @@ DEPENDENCIES
|
|||
health_check (~> 3.0)
|
||||
html-pipeline (~> 2.14.3)
|
||||
html2text
|
||||
httparty (~> 0.21.0)
|
||||
httparty (~> 0.22.0)
|
||||
i18n_data (~> 0.13.1)
|
||||
icalendar (~> 2.10.1)
|
||||
influxdb-client (~> 3.1)
|
||||
|
|
@ -2398,4 +2398,4 @@ DEPENDENCIES
|
|||
yajl-ruby (~> 1.4.3)
|
||||
|
||||
BUNDLED WITH
|
||||
2.5.11
|
||||
2.6.5
|
||||
|
|
|
|||
|
|
@ -51,6 +51,11 @@ export default {
|
|||
type: String,
|
||||
required: true,
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
@ -89,6 +94,7 @@ export default {
|
|||
:data-track-action-for-errors="trackActionForErrors"
|
||||
:title="title"
|
||||
:type="type"
|
||||
:disabled="disabled"
|
||||
/>
|
||||
<gl-button
|
||||
v-gl-tooltip="toggleVisibilityLabel"
|
||||
|
|
@ -96,6 +102,7 @@ export default {
|
|||
category="tertiary"
|
||||
:aria-label="toggleVisibilityLabel"
|
||||
:icon="toggleVisibilityIcon"
|
||||
:disabled="disabled"
|
||||
@click="handleToggleVisibilityButtonClick"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -20,9 +20,11 @@ export const initPasswordInput = () => {
|
|||
required,
|
||||
autocomplete,
|
||||
name,
|
||||
disabled,
|
||||
} = el.dataset;
|
||||
|
||||
const requiredAttr = required ? parseBoolean(required) : true;
|
||||
const disabledAttr = disabled ? parseBoolean(disabled) : false;
|
||||
|
||||
// eslint-disable-next-line no-new
|
||||
new Vue({
|
||||
|
|
@ -39,6 +41,7 @@ export const initPasswordInput = () => {
|
|||
autocomplete,
|
||||
name,
|
||||
required: requiredAttr,
|
||||
disabled: disabledAttr,
|
||||
},
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -5,9 +5,11 @@ import {
|
|||
initDeleteUserModals,
|
||||
} from '~/admin/users';
|
||||
import initConfirmModal from '~/confirm_modal';
|
||||
import { initPasswordInput } from '~/authentication/password';
|
||||
|
||||
initAdminUsersFilterApp();
|
||||
initAdminUserActions();
|
||||
initAdminUsersApp();
|
||||
initDeleteUserModals();
|
||||
initConfirmModal();
|
||||
initPasswordInput();
|
||||
|
|
|
|||
|
|
@ -788,14 +788,9 @@ module Ci
|
|||
return unless project
|
||||
return if user&.blocked?
|
||||
|
||||
if Feature.enabled?(:ci_async_build_hooks_execution, project)
|
||||
return unless project.has_active_hooks?(:job_hooks) || project.has_active_integrations?(:job_hooks)
|
||||
return unless project.has_active_hooks?(:job_hooks) || project.has_active_integrations?(:job_hooks)
|
||||
|
||||
Ci::ExecuteBuildHooksWorker.perform_async(project.id, build_data)
|
||||
else
|
||||
project.execute_hooks(build_data.dup, :job_hooks) if project.has_active_hooks?(:job_hooks)
|
||||
project.execute_integrations(build_data.dup, :job_hooks) if project.has_active_integrations?(:job_hooks)
|
||||
end
|
||||
Ci::ExecuteBuildHooksWorker.perform_async(project.id, build_data)
|
||||
end
|
||||
|
||||
def browsable_artifacts?
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ module Integrations
|
|||
build_help_page_url(
|
||||
'user/project/integrations/discord_notifications.md',
|
||||
s_("DiscordService|Send notifications about project events to a Discord channel."),
|
||||
_('How do I set up this integration?')
|
||||
link_text: _('How do I set up this integration?')
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ module Integrations
|
|||
'user/project/integrations/hangouts_chat.md',
|
||||
'Before enabling this integration, create a webhook for the space in Google Chat where you want to ' \
|
||||
'receive notifications from this project.',
|
||||
_('How do I set up a Google Chat webhook?')
|
||||
link_text: _('How do I set up a Google Chat webhook?')
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -424,7 +424,7 @@ module Integrations
|
|||
@field_storage || :properties
|
||||
end
|
||||
|
||||
def build_help_page_url(url_path, help_text, link_text = _("Learn More"), options = {})
|
||||
def build_help_page_url(url_path, help_text, options = {}, link_text: _("Learn More"))
|
||||
docs_link = ActionController::Base.helpers.link_to(
|
||||
'',
|
||||
Rails.application.routes.url_helpers.help_page_url(url_path, **options), # rubocop:disable Gitlab/DocumentationLinks/Link: -- existing code moved as is
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ module Integrations
|
|||
build_help_page_url(
|
||||
'integration/datadog.md',
|
||||
s_('DatadogIntegration|Connect your GitLab projects to your Datadog account to synchronize repository metadata and enrich telemetry on your Datadog account.'),
|
||||
_('How do I set up this integration?')
|
||||
link_text: _('How do I set up this integration?')
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -31,13 +31,13 @@
|
|||
- c.with_body do
|
||||
= s_('AdminUsers|Reset link will be generated and sent to the user. User will be forced to set the password on first sign in.')
|
||||
- else
|
||||
.form-group.gl-form-group{ role: 'group' }
|
||||
.form-group.gl-form-group.gl-form-input-lg{ role: 'group' }
|
||||
= f.label :password, _('Password'), class: 'gl-block col-form-label'
|
||||
= f.password_field :password, disabled: f.object.force_random_password, autocomplete: 'new-password', class: 'form-control gl-form-input js-password-complexity-validation gl-form-input-lg'
|
||||
= f.password_field :password, class: 'form-control gl-form-input js-password-complexity-validation js-password', data: { autocomplete: 'new-password', disabled: f.object.force_random_password, required: false, id: 'user_password', name: 'user[password]' }
|
||||
= render_if_exists 'shared/password_requirements_list'
|
||||
.form-group.gl-form-group{ role: 'group' }
|
||||
.form-group.gl-form-group.gl-form-input-lg{ role: 'group' }
|
||||
= f.label :password_confirmation, _('Password confirmation'), class: 'gl-block col-form-label'
|
||||
= f.password_field :password_confirmation, disabled: f.object.force_random_password, autocomplete: 'new-password', class: 'form-control gl-form-input gl-form-input-lg'
|
||||
= f.password_field :password_confirmation, class: 'form-control gl-form-input js-password', data: { autocomplete: 'new-password', disabled: f.object.force_random_password, required: false, id: 'user_password_confirmation', name: 'user[password_confirmation]' }
|
||||
|
||||
= render partial: 'access', locals: { f: f }
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ module Ci
|
|||
project = Project.find_by_id(project_id)
|
||||
return unless project
|
||||
|
||||
build_data = build_data.with_indifferent_access
|
||||
|
||||
project.execute_hooks(build_data, :job_hooks) if project.has_active_hooks?(:job_hooks)
|
||||
project.execute_integrations(build_data, :job_hooks) if project.has_active_integrations?(:job_hooks)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
---
|
||||
name: ci_async_build_hooks_execution
|
||||
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/499290
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/177706
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/512832
|
||||
milestone: '17.9'
|
||||
group: group::pipeline authoring
|
||||
type: gitlab_com_derisk
|
||||
default_enabled: false
|
||||
|
|
@ -47,7 +47,7 @@ Other examples of internal users:
|
|||
[GitLab Admin Bot](https://gitlab.com/gitlab-org/gitlab/-/blob/1d38cfdbed081f8b3fa14b69dd743440fe85081b/lib/users/internal.rb#L104)
|
||||
is an internal user that cannot be accessed or modified by regular users and is responsible for many tasks including:
|
||||
|
||||
- Applying [default compliance frameworks](../user/group/compliance_frameworks.md#default-compliance-frameworks) to
|
||||
- Applying [default compliance frameworks](../user/compliance/compliance_frameworks.md#default-compliance-frameworks) to
|
||||
projects.
|
||||
- [Automatically deactivating dormant users](moderate_users.md#automatically-deactivate-dormant-users).
|
||||
- [Automatically deleting unconfirmed users](moderate_users.md#automatically-delete-unconfirmed-users).
|
||||
|
|
|
|||
|
|
@ -43,16 +43,16 @@ If you don't have access to the `gitaly` command, alternatives to server hooks i
|
|||
|
||||
## Set server hooks for a repository
|
||||
|
||||
{{< tabs >}}
|
||||
|
||||
{{< tab title="GitLab 15.11 and later" >}}
|
||||
|
||||
{{< history >}}
|
||||
|
||||
- [Introduced](https://gitlab.com/gitlab-org/gitaly/-/issues/4629) in GitLab 15.11, `hooks set` command replaces direct file system access. Existing Git hooks don't need migrating for the `hooks set` command.
|
||||
|
||||
{{< /history >}}
|
||||
|
||||
{{< tabs >}}
|
||||
|
||||
{{< tab title="GitLab 15.11 and later" >}}
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- The [storage name](gitaly/configure_gitaly.md#gitlab-requires-a-default-repository-storage), path to the Gitaly configuration file
|
||||
|
|
@ -181,16 +181,16 @@ subdirectories.
|
|||
|
||||
## Remove server hooks for a repository
|
||||
|
||||
{{< tabs >}}
|
||||
|
||||
{{< tab title="GitLab 15.11 and later" >}}
|
||||
|
||||
{{< history >}}
|
||||
|
||||
- [Introduced](https://gitlab.com/gitlab-org/gitaly/-/issues/4629) in GitLab 15.11, `hooks set` command replaces direct file system access.
|
||||
|
||||
{{< /history >}}
|
||||
|
||||
{{< tabs >}}
|
||||
|
||||
{{< tab title="GitLab 15.11 and later" >}}
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- The [storage name and relative path](repository_storage_paths.md#from-project-name-to-hashed-path) for the repository.
|
||||
|
|
|
|||
|
|
@ -521,7 +521,7 @@ To set the maximum file size:
|
|||
|
||||
This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/389467) in GitLab 15.9
|
||||
and was removed in 17.0. From 17.4, it is available only behind the feature flag `required_pipelines`, disabled by default.
|
||||
Use [compliance pipelines](../../user/group/compliance_pipelines.md) instead. This change is a breaking change.
|
||||
Use [compliance pipelines](../../user/compliance/compliance_pipelines.md) instead. This change is a breaking change.
|
||||
|
||||
{{< /alert >}}
|
||||
|
||||
|
|
|
|||
|
|
@ -141,9 +141,9 @@ In this example:
|
|||
|
||||
{{< alert type="note" >}}
|
||||
|
||||
Because of a [known issue](https://gitlab.com/gitlab-org/gitlab/-/issues/382857), projects that use [compliance pipelines](../../user/group/compliance_pipelines.md) can have prefilled variables not appear
|
||||
Because of a [known issue](https://gitlab.com/gitlab-org/gitlab/-/issues/382857), projects that use [compliance pipelines](../../user/compliance/compliance_pipelines.md) can have prefilled variables not appear
|
||||
when running a pipeline manually. To workaround this issue,
|
||||
[change the compliance pipeline configuration](../../user/group/compliance_pipelines.md#prefilled-variables-are-not-shown).
|
||||
[change the compliance pipeline configuration](../../user/compliance/compliance_pipelines.md#prefilled-variables-are-not-shown).
|
||||
|
||||
{{< /alert >}}
|
||||
|
||||
|
|
|
|||
|
|
@ -554,7 +554,7 @@ start. Jobs in the current stage are not stopped and continue to run.
|
|||
|
||||
- If a job does not specify a [`stage`](#stage), the job is assigned the `test` stage.
|
||||
- If a stage is defined but no jobs use it, the stage is not visible in the pipeline,
|
||||
which can help [compliance pipeline configurations](../../user/group/compliance_pipelines.md):
|
||||
which can help [compliance pipeline configurations](../../user/compliance/compliance_pipelines.md):
|
||||
- Stages can be defined in the compliance configuration but remain hidden if not used.
|
||||
- The defined stages become visible when developers use them in job definitions.
|
||||
|
||||
|
|
@ -4651,7 +4651,7 @@ In this example:
|
|||
section. The project containing the `include` section can be different than the project
|
||||
running the pipeline when using:
|
||||
- [Nested includes](includes.md#use-nested-includes).
|
||||
- [Compliance pipelines](../../user/group/compliance_pipelines.md).
|
||||
- [Compliance pipelines](../../user/compliance/compliance_pipelines.md).
|
||||
- `rules:exists` cannot search for the presence of [artifacts](../jobs/job_artifacts.md),
|
||||
because `rules` evaluation happens before jobs run and artifacts are fetched.
|
||||
|
||||
|
|
|
|||
|
|
@ -106,6 +106,12 @@ you must enable and configure product analytics.
|
|||
|
||||
### Product analytics provider
|
||||
|
||||
{{< history >}}
|
||||
|
||||
- Self-managed provider [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/117804) in GitLab 16.0.
|
||||
|
||||
{{< /history >}}
|
||||
|
||||
Your GitLab instance connects to a product analytics provider.
|
||||
A product analytics provider is the collection of services required to receive,
|
||||
process, store and query your analytics data.
|
||||
|
|
@ -114,12 +120,6 @@ process, store and query your analytics data.
|
|||
|
||||
{{< tab title="GitLab-managed provider" >}}
|
||||
|
||||
{{< details >}}
|
||||
|
||||
- Offering: GitLab.com
|
||||
|
||||
{{< /details >}}
|
||||
|
||||
On GitLab.com you can use a GitLab-managed provider offered only in the Google Cloud Platform zone `us-central-1`.
|
||||
|
||||
If GitLab manages your product analytics provider, then your analytics data is retained for one year.
|
||||
|
|
@ -129,8 +129,6 @@ You can request to delete your data at any time by [contacting support](https://
|
|||
|
||||
{{< tab title="Self-managed provider" >}}
|
||||
|
||||
>[Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/117804) in GitLab 16.0.
|
||||
|
||||
A self-managed product analytics provider is a deployed instance of the
|
||||
[product analytics Helm charts](https://gitlab.com/gitlab-org/analytics-section/product-analytics/helm-charts).
|
||||
|
||||
|
|
|
|||
|
|
@ -18,13 +18,13 @@ title: 'Tutorial: Create a compliance pipeline (deprecated)'
|
|||
|
||||
This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/159841) in GitLab 17.3
|
||||
and is planned for removal in 18.0. Use [pipeline execution policy type](../../user/application_security/policies/pipeline_execution_policies.md) instead.
|
||||
This change is a breaking change. For more information, see the [migration guide](../../user/group/compliance_pipelines.md#pipeline-execution-policies-migration).
|
||||
This change is a breaking change. For more information, see the [migration guide](../../user/compliance/compliance_pipelines.md#pipeline-execution-policies-migration).
|
||||
|
||||
{{< /alert >}}
|
||||
|
||||
You can use [compliance pipelines](../../user/group/compliance_pipelines.md) to ensure specific
|
||||
You can use [compliance pipelines](../../user/compliance/compliance_pipelines.md) to ensure specific
|
||||
compliance-related jobs are run on pipelines for all projects in a group. Compliance pipelines are applied
|
||||
to projects through [compliance frameworks](../../user/group/compliance_frameworks.md).
|
||||
to projects through [compliance frameworks](../../user/compliance/compliance_frameworks.md).
|
||||
|
||||
In this tutorial, you:
|
||||
|
||||
|
|
@ -57,7 +57,7 @@ To create the new group:
|
|||
## Create a new compliance pipeline project
|
||||
|
||||
Now you're ready to create a compliance pipeline project. This project contains the
|
||||
[compliance pipeline configuration](../../user/group/compliance_pipelines.md#example-configuration) to apply to all
|
||||
[compliance pipeline configuration](../../user/compliance/compliance_pipelines.md#example-configuration) to apply to all
|
||||
projects with the compliance framework applied.
|
||||
|
||||
To create the compliance pipeline project:
|
||||
|
|
@ -191,6 +191,6 @@ Notice the pipeline runs two jobs in a **test** stage:
|
|||
|
||||
Congratulations, you've created and configured a compliance pipeline!
|
||||
|
||||
See more [example compliance pipeline configurations](../../user/group/compliance_pipelines.md#example-configuration).
|
||||
See more [example compliance pipeline configurations](../../user/compliance/compliance_pipelines.md#example-configuration).
|
||||
|
||||
<!--- end_remove -->
|
||||
|
|
|
|||
|
|
@ -193,7 +193,7 @@ Security and compliance teams must ensure that security scans:
|
|||
|
||||
GitLab provides two methods of accomplishing this, each with advantages and disadvantages.
|
||||
|
||||
- [Compliance framework pipelines](../group/compliance_pipelines.md)
|
||||
- [Compliance framework pipelines](../compliance/compliance_pipelines.md)
|
||||
are recommended when:
|
||||
|
||||
- Scan execution enforcement is required for any scanner that uses a GitLab template, such as SAST IaC, DAST, Dependency Scanning,
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ compliance:
|
|||
|
||||
| Feature | Instances | Groups | Projects | Description |
|
||||
|:-----------------------------------------------------------------------------------------------------------------------------------------|:-------------------------------------|:-------------------------------------|:-------------------------------------|:------------|
|
||||
| [Compliance frameworks](../group/compliance_frameworks.md) | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Describe the type of compliance requirements projects must follow. |
|
||||
| [Compliance pipelines](../group/compliance_pipelines.md) | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Define a pipeline configuration to run for any projects with a given compliance framework. |
|
||||
| [Compliance frameworks](../compliance/compliance_frameworks.md) | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Describe the type of compliance requirements projects must follow. |
|
||||
| [Compliance pipelines](../compliance/compliance_pipelines.md) | {{< icon name="dotted-circle" >}} No | {{< icon name="check-circle" >}} Yes | {{< icon name="dotted-circle" >}} No | Define a pipeline configuration to run for any projects with a given compliance framework. |
|
||||
| [Merge request approval policy approval settings](../application_security/policies/merge_request_approval_policies.md#approval_settings) | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | {{< icon name="check-circle" >}} Yes | Enforce a merge request approval policy enforcing multiple approvers and override various project settings in all enforced groups or projects across your GitLab instance or group. |
|
||||
|
||||
## Audit management
|
||||
|
|
|
|||
|
|
@ -78,6 +78,34 @@ To delete a compliance framework from the compliance frameworks report:
|
|||
1. Hover over framework and select **Edit the framework**.
|
||||
1. Select the **Delete framework** to delete compliance framework.
|
||||
|
||||
## Set and remove a compliance framework as default
|
||||
|
||||
{{< history >}}
|
||||
|
||||
- [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/181500) in GitLab 17.10.
|
||||
|
||||
{{< /history >}}
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- You must be an administrator or have the Owner role for the group.
|
||||
|
||||
To set a compliance framework as [default](../compliance_frameworks.md#default-compliance-frameworks)] from the compliance frameworks report:
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your group.
|
||||
1. Select **Secure > Compliance center**.
|
||||
1. On the page, select the **Frameworks** tab.
|
||||
1. Next to the compliance framework you want to set as default, select {{< icon name="pencil" >}} action.
|
||||
1. Select the **Set as default** to set as default.
|
||||
|
||||
To remove a compliance framework as default from the compliance frameworks report:
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your group.
|
||||
1. Select **Secure > Compliance center**.
|
||||
1. On the page, select the **Frameworks** tab.
|
||||
1. Next to the compliance framework that is default, select {{< icon name="pencil" >}} action.
|
||||
1. Select the **Remove as default** to remove as default.
|
||||
|
||||
## Export a report of compliance frameworks in a group
|
||||
|
||||
{{< history >}}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,112 @@
|
|||
---
|
||||
stage: Software Supply Chain Security
|
||||
group: Compliance
|
||||
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
|
||||
title: Compliance frameworks
|
||||
---
|
||||
|
||||
{{< details >}}
|
||||
|
||||
- Tier: Premium, Ultimate
|
||||
- Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
|
||||
|
||||
{{< /details >}}
|
||||
|
||||
You can create a compliance framework that is a label to identify that your project has certain compliance
|
||||
requirements or needs additional oversight.
|
||||
|
||||
In the Ultimate tier, the compliance framework can optionally enforce
|
||||
[compliance pipeline configuration](compliance_pipelines.md) and
|
||||
[security policies](../application_security/policies/_index.md#scope) to the projects on which it is applied.
|
||||
|
||||
Compliance frameworks are created on top-level groups. If a project is moved outside of its existing top-level group,
|
||||
its frameworks are removed.
|
||||
|
||||
You can apply up to 20 compliance frameworks to each project.
|
||||
|
||||
For a click-through demo, see [Compliance frameworks](https://gitlab.navattic.com/compliance).
|
||||
<!-- Demo published on 2025-01-27 -->
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- To create, edit, and delete compliance frameworks, users must have either:
|
||||
- The Owner role for the top-level group.
|
||||
- Be assigned a [custom role](../custom_roles.md) with the `admin_compliance_framework`
|
||||
[custom permission](../custom_roles/abilities.md#compliance-management).
|
||||
- To add or remove a compliance framework to or from a project, the group to which the project belongs must have a
|
||||
compliance framework.
|
||||
|
||||
## Create, edit, or delete a compliance framework
|
||||
|
||||
You can create, edit, or delete a compliance framework from a compliance framework report. For more information, see:
|
||||
|
||||
- [Create a new compliance framework](../compliance/compliance_center/compliance_frameworks_report.md#create-a-new-compliance-framework).
|
||||
- [Edit a compliance framework](../compliance/compliance_center/compliance_frameworks_report.md#edit-a-compliance-framework).
|
||||
- [Delete a compliance framework](../compliance/compliance_center/compliance_frameworks_report.md#delete-a-compliance-framework).
|
||||
|
||||
You can create, edit, or delete a compliance framework from a compliance projects report. For more information, see:
|
||||
|
||||
- [Create a new compliance framework](../compliance/compliance_center/compliance_projects_report.md#create-a-new-compliance-framework).
|
||||
- [Edit a compliance framework](../compliance/compliance_center/compliance_projects_report.md#edit-a-compliance-framework).
|
||||
- [Delete a compliance framework](../compliance/compliance_center/compliance_projects_report.md#delete-a-compliance-framework).
|
||||
|
||||
Subgroups and projects have access to all compliance frameworks created on their top-level group. However, compliance frameworks cannot be created, edited,
|
||||
or deleted at the subgroup or project level. Project owners can choose a framework to apply to their projects.
|
||||
|
||||
## Apply a compliance framework to a project
|
||||
|
||||
{{< history >}}
|
||||
|
||||
- Assigning multiple compliance frameworks [introduced](https://gitlab.com/groups/gitlab-org/-/epics/13294) in GitLab 17.3.
|
||||
|
||||
{{< /history >}}
|
||||
|
||||
You can apply multiple compliance frameworks to a project but cannot apply compliance frameworks to projects in personal namespaces.
|
||||
|
||||
To apply a compliance framework to a project, apply the compliance framework through the
|
||||
[Compliance projects report](../compliance/compliance_center/compliance_projects_report.md#apply-a-compliance-framework-to-projects-in-a-group).
|
||||
|
||||
You can use the [GraphQL API](../../api/graphql/reference/_index.md#mutationprojectupdatecomplianceframeworks) to apply one or many
|
||||
compliance frameworks to a project.
|
||||
|
||||
If you create compliance frameworks on subgroups with GraphQL, the framework is created on the root ancestor if the user
|
||||
has the correct permissions. The GitLab UI presents a read-only view to discourage this behavior.
|
||||
|
||||
## Default compliance frameworks
|
||||
|
||||
{{< history >}}
|
||||
|
||||
- [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/375036) in GitLab 15.6.
|
||||
|
||||
{{< /history >}}
|
||||
|
||||
Group owners can set a default compliance framework. The default framework is applied to all the new and imported
|
||||
projects that are created in that group. It does not affect the framework applied to the existing projects. The
|
||||
default framework cannot be deleted.
|
||||
|
||||
A compliance framework that is set to default has a **default** label.
|
||||
|
||||
### Set and remove a default by using the compliance center
|
||||
|
||||
To set as default (or remove the default) from [compliance projects report](../compliance/compliance_center/compliance_projects_report.md):
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your group.
|
||||
1. Select **Secure > Compliance center**.
|
||||
1. On the page, select the **Projects** tab.
|
||||
1. Hover over a compliance framework, select the **Edit Framework** tab.
|
||||
1. Select **Set as default**.
|
||||
1. Select **Save changes**.
|
||||
|
||||
To set as default (or remove the default) from [compliance framework report](../compliance/compliance_center/compliance_frameworks_report.md):
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your group.
|
||||
1. Select **Secure > Compliance center**.
|
||||
1. On the page, select the **Frameworks** tab.
|
||||
1. Hover over a compliance framework, select the **Edit Framework** tab.
|
||||
1. Select **Set as default**.
|
||||
1. Select **Save changes**.
|
||||
|
||||
## Remove a compliance framework from a project
|
||||
|
||||
To remove a compliance framework from one or multiple project in a group, remove the compliance framework through the
|
||||
[Compliance projects report](../compliance/compliance_center/compliance_projects_report.md#remove-a-compliance-framework-from-projects-in-a-group).
|
||||
|
|
@ -0,0 +1,416 @@
|
|||
---
|
||||
stage: Software Supply Chain Security
|
||||
group: Compliance
|
||||
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
|
||||
title: Compliance pipelines (deprecated)
|
||||
---
|
||||
|
||||
<!--- start_remove The following content will be removed on remove_date: '2025-08-15' -->
|
||||
|
||||
{{< details >}}
|
||||
|
||||
- Tier: Ultimate
|
||||
- Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
|
||||
|
||||
{{< /details >}}
|
||||
|
||||
{{< alert type="warning" >}}
|
||||
|
||||
This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/159841) in GitLab 17.3
|
||||
and is planned for removal in 19.0. Use [pipeline execution policy type](../application_security/policies/pipeline_execution_policies.md) instead.
|
||||
This change is a breaking change. For more information, see the [migration guide](#pipeline-execution-policies-migration).
|
||||
|
||||
{{< /alert >}}
|
||||
|
||||
Group owners can configure a compliance pipeline in a project separate to other projects. By default, the compliance
|
||||
pipeline configuration (for example, `.compliance-gitlab-ci.yml`) is run instead of the pipeline configuration (for example, `.gitlab-ci.yml`) of labeled
|
||||
projects.
|
||||
|
||||
However, the compliance pipeline configuration can reference the `.gitlab-ci.yml` file of the labeled projects so that:
|
||||
|
||||
- The compliance pipeline can also run jobs of labeled project pipelines. This allows for centralized control of
|
||||
pipeline configuration.
|
||||
- Jobs and variables defined in the compliance pipeline can't be changed by variables in the labeled project's
|
||||
`.gitlab-ci.yml` file.
|
||||
|
||||
{{< alert type="note" >}}
|
||||
|
||||
Because of a [known issue](https://gitlab.com/gitlab-org/gitlab/-/issues/414004), project pipelines must be included first at the top of compliance pipeline configuration
|
||||
to prevent projects overriding settings downstream.
|
||||
|
||||
{{< /alert >}}
|
||||
|
||||
For more information, see:
|
||||
|
||||
- [Example configuration](#example-configuration) for help configuring a compliance pipeline that runs jobs from
|
||||
labeled project pipeline configuration.
|
||||
- The [Create a compliance pipeline](../../tutorials/compliance_pipeline/_index.md) tutorial.
|
||||
|
||||
## Pipeline execution policies migration
|
||||
|
||||
To consolidate and simplify scan and pipeline enforcement, we have introduced pipeline execution policies. We deprecated
|
||||
compliance pipelines in GitLab 17.3 and will remove compliance pipelines in GitLab 19.0.
|
||||
|
||||
Pipeline execution policies extend a project's `.gitlab-ci.yml` file with the configuration provided in separate YAML file
|
||||
(for example, `pipeline-execution.yml`) linked in the pipeline execution policy.
|
||||
|
||||
By default, when creating a new compliance framework, you are directed to use the pipeline execution policy type instead
|
||||
of compliance pipelines.
|
||||
|
||||
Existing compliance pipelines must be migrated. Customers should migrate from compliance pipelines to the new
|
||||
[pipeline execution policy type](../application_security/policies/pipeline_execution_policies.md) as soon as possible.
|
||||
|
||||
### Migrate an existing compliance framework
|
||||
|
||||
To migrate an existing compliance framework to use the pipeline execution policy type:
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your group.
|
||||
1. Select **Secure > Compliance center**.
|
||||
1. [Edit](compliance_frameworks.md#create-edit-or-delete-a-compliance-framework) the existing compliance framework.
|
||||
1. In the banner than appears, select **Migrate pipeline to a policy** to create a new policy in the security policies.
|
||||
1. Edit the compliance framework again to remove the compliance pipeline.
|
||||
|
||||
For more information, see [Security policy project](../application_security/policies/_index.md#security-policy-project).
|
||||
|
||||
If you receive a `Pipeline execution policy error: Job names must be unique` error during the migration, see the
|
||||
[relevant troubleshooting information](#error-job-names-must-be-unique).
|
||||
|
||||
## Effect on labeled projects
|
||||
|
||||
Users have no way of knowing that a compliance pipeline has been configured and might be confused why their own
|
||||
pipelines are not running at all, or include jobs that they did not define themselves.
|
||||
|
||||
When authoring pipelines on a labeled project, there is no indication that a compliance pipeline has been configured.
|
||||
The only marker at the project level is the compliance framework label itself, but the label does not say whether the
|
||||
framework has a compliance pipeline configured or not.
|
||||
|
||||
Therefore, communicate with project users about compliance pipeline configuration to reduce uncertainty and confusion.
|
||||
|
||||
### Multiple compliance frameworks
|
||||
|
||||
You can [apply to a single project](compliance_frameworks.md#apply-a-compliance-framework-to-a-project) multiple compliance frameworks with compliance pipelines configured.
|
||||
In this case, only the first compliance framework applied to a project has its compliance pipeline included in the project pipeline.
|
||||
|
||||
To ensure that the correct compliance pipeline is included in a project:
|
||||
|
||||
1. Remove all compliance frameworks from the project.
|
||||
1. Apply the compliance framework with the correct compliance pipeline to the project.
|
||||
1. Apply additional compliance frameworks to the project.
|
||||
|
||||
## Configure a compliance pipeline
|
||||
|
||||
{{< history >}}
|
||||
|
||||
- [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/383209) in GitLab 15.11, compliance frameworks moved to compliance center.
|
||||
|
||||
{{< /history >}}
|
||||
|
||||
To configure a compliance pipeline:
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your group.
|
||||
1. Select **Secure** > **Compliance Center**.
|
||||
1. Select **Frameworks** section.
|
||||
1. Select **New framework** section, add information of compliance framework including path to the compliance framework configuration. Use the
|
||||
`path/file.y[a]ml@group-name/project-name` format. For example:
|
||||
|
||||
- `.compliance-ci.yml@gitlab-org/gitlab`.
|
||||
- `.compliance-ci.yaml@gitlab-org/gitlab`.
|
||||
|
||||
This configuration is inherited by projects where the compliance framework label is
|
||||
[applied](../project/working_with_projects.md#add-a-compliance-framework-to-a-project). In projects with the applied compliance
|
||||
framework label, the compliance pipeline configuration is run instead of the labeled project's own pipeline configuration.
|
||||
|
||||
The user running the pipeline in the labeled project must at least have the Reporter role on the compliance project.
|
||||
|
||||
When used to enforce scan execution, this feature has some overlap with
|
||||
[scan execution policies](../application_security/policies/scan_execution_policies.md). We have not
|
||||
[unified the user experience for these two features](https://gitlab.com/groups/gitlab-org/-/epics/7312). For details on
|
||||
the similarities and differences between these features, see [Enforce scan execution](../application_security/_index.md#enforce-scan-execution).
|
||||
|
||||
### Example configuration
|
||||
|
||||
The following example `.compliance-gitlab-ci.yml` includes the `include` keyword to ensure labeled project pipeline
|
||||
configuration is also executed.
|
||||
|
||||
```yaml
|
||||
include: # Execute individual project's configuration (if project contains .gitlab-ci.yml)
|
||||
- project: '$CI_PROJECT_PATH'
|
||||
file: '$CI_CONFIG_PATH'
|
||||
ref: '$CI_COMMIT_SHA' # Must be defined or MR pipelines always use the use default branch
|
||||
rules:
|
||||
- if: $CI_PROJECT_PATH != "my-group/project-1" # Must run on projects other than the one hosting this configuration.
|
||||
|
||||
# Allows compliance team to control the ordering and interweaving of stages/jobs.
|
||||
# Stages without jobs defined will remain hidden.
|
||||
stages:
|
||||
- pre-compliance
|
||||
- build
|
||||
- test
|
||||
- pre-deploy-compliance
|
||||
- deploy
|
||||
- post-compliance
|
||||
|
||||
variables: # Can be overridden by setting a job-specific variable in project's local .gitlab-ci.yml
|
||||
FOO: sast
|
||||
|
||||
sast: # None of these attributes can be overridden by a project's local .gitlab-ci.yml
|
||||
variables:
|
||||
FOO: sast
|
||||
image: ruby:2.6
|
||||
stage: pre-compliance
|
||||
rules:
|
||||
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"
|
||||
when: never
|
||||
- when: always # or when: on_success
|
||||
allow_failure: false
|
||||
before_script:
|
||||
- "# No before scripts."
|
||||
script:
|
||||
- echo "running $FOO"
|
||||
after_script:
|
||||
- "# No after scripts."
|
||||
|
||||
sanity check:
|
||||
image: ruby:2.6
|
||||
stage: pre-deploy-compliance
|
||||
rules:
|
||||
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"
|
||||
when: never
|
||||
- when: always # or when: on_success
|
||||
allow_failure: false
|
||||
before_script:
|
||||
- "# No before scripts."
|
||||
script:
|
||||
- echo "running $FOO"
|
||||
after_script:
|
||||
- "# No after scripts."
|
||||
|
||||
audit trail:
|
||||
image: ruby:2.7
|
||||
stage: post-compliance
|
||||
rules:
|
||||
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"
|
||||
when: never
|
||||
- when: always # or when: on_success
|
||||
allow_failure: false
|
||||
before_script:
|
||||
- "# No before scripts."
|
||||
script:
|
||||
- echo "running $FOO"
|
||||
after_script:
|
||||
- "# No after scripts."
|
||||
```
|
||||
|
||||
The `rules` configuration in the `include` definition avoids circular inclusion in case the compliance pipeline must be able to run in the host project itself.
|
||||
You can leave it out if your compliance pipeline only ever runs in labeled projects.
|
||||
|
||||
#### Compliance pipelines and custom pipeline configuration hosted externally
|
||||
|
||||
The example above assumes that all projects host their pipeline configuration in the same project.
|
||||
If any projects use [configuration hosted externally](../../ci/pipelines/settings.md#specify-a-custom-cicd-configuration-file),
|
||||
the example configuration does not work. See [issue 393960](https://gitlab.com/gitlab-org/gitlab/-/issues/393960)
|
||||
for more details.
|
||||
|
||||
With projects that use externally hosted configuration, you can try the this workaround:
|
||||
|
||||
- The `include` section in the example compliance pipeline configuration must be adjusted.
|
||||
For example, using [`include:rules`](../../ci/yaml/includes.md#use-rules-with-include):
|
||||
|
||||
```yaml
|
||||
include:
|
||||
# If the custom path variables are defined, include the project's external config file.
|
||||
- project: '$PROTECTED_PIPELINE_CI_PROJECT_PATH'
|
||||
file: '$PROTECTED_PIPELINE_CI_CONFIG_PATH'
|
||||
ref: '$PROTECTED_PIPELINE_CI_REF'
|
||||
rules:
|
||||
- if: $PROTECTED_PIPELINE_CI_PROJECT_PATH && $PROTECTED_PIPELINE_CI_CONFIG_PATH && $PROTECTED_PIPELINE_CI_REF
|
||||
# If any custom path variable is not defined, include the project's internal config file as normal.
|
||||
- project: '$CI_PROJECT_PATH'
|
||||
file: '$CI_CONFIG_PATH'
|
||||
ref: '$CI_COMMIT_SHA'
|
||||
rules:
|
||||
- if: $PROTECTED_PIPELINE_CI_PROJECT_PATH == null || $PROTECTED_PIPELINE_CI_CONFIG_PATH == null || $PROTECTED_PIPELINE_CI_REF == null
|
||||
```
|
||||
|
||||
- [CI/CD variables](../../ci/variables/_index.md) must be added to projects with external
|
||||
pipeline configuration. In this example:
|
||||
|
||||
- `PROTECTED_PIPELINE_CI_PROJECT_PATH`: The path to the project hosting the configuration file, for example `group/subgroup/project`.
|
||||
- `PROTECTED_PIPELINE_CI_CONFIG_PATH`: The path to the configuration file in the project, for example `path/to/.gitlab-ci.yml`.
|
||||
- `PROTECTED_PIPELINE_CI_REF`: The ref to use when retrieving the configuration file, for example `main`.
|
||||
|
||||
#### Compliance pipelines in merge requests originating in project forks
|
||||
|
||||
When a merge request originates in a fork, the branch to be merged usually only exists in the fork.
|
||||
When creating such a merge request against a project with compliance pipelines, the above snippet fails with a
|
||||
`Project <project-name> reference <branch-name> does not exist!` error message.
|
||||
This error occurs because in the context of the target project, `$CI_COMMIT_REF_NAME` evaluates to a non-existing
|
||||
branch name.
|
||||
|
||||
To get the correct context, use `$CI_MERGE_REQUEST_SOURCE_PROJECT_PATH` instead of `$CI_PROJECT_PATH`.
|
||||
This variable is only available in
|
||||
[merge request pipelines](../../ci/pipelines/merge_request_pipelines.md).
|
||||
|
||||
For example, for a configuration that supports both merge request pipelines originating in project forks and branch pipelines,
|
||||
you need to [combine both `include` directives with `rules:if`](../../ci/yaml/includes.md#use-rules-with-include):
|
||||
|
||||
```yaml
|
||||
include: # Execute individual project's configuration (if project contains .gitlab-ci.yml)
|
||||
- project: '$CI_MERGE_REQUEST_SOURCE_PROJECT_PATH'
|
||||
file: '$CI_CONFIG_PATH'
|
||||
ref: '$CI_COMMIT_REF_NAME'
|
||||
rules:
|
||||
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
|
||||
- project: '$CI_PROJECT_PATH'
|
||||
file: '$CI_CONFIG_PATH'
|
||||
ref: '$CI_COMMIT_REF_NAME'
|
||||
rules:
|
||||
- if: $CI_PIPELINE_SOURCE != 'merge_request_event'
|
||||
```
|
||||
|
||||
#### Compliance pipelines in projects with no configuration file
|
||||
|
||||
The [example configuration](#example-configuration) above assumes that all projects contain
|
||||
a pipeline configuration file (`.gitlab-ci.yml` by default). However, in projects
|
||||
with no configuration file (and therefore no pipelines by default), the compliance pipeline
|
||||
fails because the file specified in `include:project` is required.
|
||||
|
||||
To only include a configuration file if it exists in a target project, use
|
||||
[`rules:exists:project`](../../ci/yaml/_index.md#rulesexistsproject):
|
||||
|
||||
```yaml
|
||||
include: # Execute individual project's configuration
|
||||
- project: '$CI_PROJECT_PATH'
|
||||
file: '$CI_CONFIG_PATH'
|
||||
ref: '$CI_COMMIT_SHA'
|
||||
rules:
|
||||
- exists:
|
||||
paths:
|
||||
- '$CI_CONFIG_PATH'
|
||||
project: '$CI_PROJECT_PATH'
|
||||
ref: '$CI_COMMIT_SHA'
|
||||
```
|
||||
|
||||
In this example, a configuration file is only included if it exists for the given `ref`
|
||||
in the project in `exists:project: $CI_PROJECT_PATH'`.
|
||||
|
||||
If `exists:project` is not specified in the compliance pipeline configuration, it searches for files in the project
|
||||
in which the `include` is defined. In compliance pipelines, the `include` from the example above
|
||||
is defined in the project hosting the compliance pipeline configuration file, not the project
|
||||
running the pipeline.
|
||||
|
||||
## Ensure compliance jobs are always run
|
||||
|
||||
Compliance pipelines [use GitLab CI/CD](../../ci/_index.md) to give you an incredible amount of flexibility
|
||||
for defining any sort of compliance jobs you like. Depending on your goals, these jobs
|
||||
can be configured to be:
|
||||
|
||||
- Modified by users.
|
||||
- Non-modifiable.
|
||||
|
||||
Generally, if a value in a compliance job:
|
||||
|
||||
- Is set, it cannot be changed or overridden by project-level configurations.
|
||||
- Is not set, a project-level configuration may be set.
|
||||
|
||||
Either might be wanted or not depending on your use case.
|
||||
|
||||
The following are a few best practices for ensuring that these jobs are always run exactly
|
||||
as you define them and that downstream, project-level pipeline configurations
|
||||
cannot change them:
|
||||
|
||||
- Add [a `rules:when:always` block](../../ci/yaml/_index.md#when) to each of your compliance jobs. This ensures they are
|
||||
non-modifiable and are always run.
|
||||
- Explicitly set any [variables](../../ci/yaml/_index.md#variables) the job references. This:
|
||||
- Ensures that project-level pipeline configurations do not set them and alter their
|
||||
behavior. For example, see `before_script` and `after_script` configuration in the [example configuration](#example-configuration).
|
||||
- Includes any jobs that drive the logic of your job.
|
||||
- Explicitly set the [container image](../../ci/yaml/_index.md#image) to run the job in. This ensures that your script
|
||||
steps execute in the correct environment.
|
||||
- Explicitly set any relevant GitLab pre-defined [job keywords](../../ci/yaml/_index.md#job-keywords).
|
||||
This ensures that your job uses the settings you intend and that they are not overridden by
|
||||
project-level pipelines.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Compliance jobs are overwritten by target repository
|
||||
|
||||
If you use the `extends` statement in a compliance pipeline configuration, compliance jobs are overwritten by the target repository job. For example,
|
||||
you could have the following `.compliance-gitlab-ci.yml` configuration:
|
||||
|
||||
```yaml
|
||||
"compliance job":
|
||||
extends:
|
||||
- .compliance_template
|
||||
stage: build
|
||||
|
||||
.compliance_template:
|
||||
script:
|
||||
- echo "take compliance action"
|
||||
```
|
||||
|
||||
You could also have the following `.gitlab-ci.yml` configuration:
|
||||
|
||||
```yaml
|
||||
"compliance job":
|
||||
stage: test
|
||||
script:
|
||||
- echo "overwriting compliance action"
|
||||
```
|
||||
|
||||
This configuration results in the target repository pipeline overwriting the compliance pipeline, and you get the following message:
|
||||
`overwriting compliance action`.
|
||||
|
||||
To avoid overwriting a compliance job, don't use the `extends` keyword in compliance pipeline configuration. For example,
|
||||
you could have the following `.compliance-gitlab-ci.yml` configuration:
|
||||
|
||||
```yaml
|
||||
"compliance job":
|
||||
stage: build
|
||||
script:
|
||||
- echo "take compliance action"
|
||||
```
|
||||
|
||||
You could also have the following `.gitlab-ci.yml` configuration:
|
||||
|
||||
```yaml
|
||||
"compliance job":
|
||||
stage: test
|
||||
script:
|
||||
- echo "overwriting compliance action"
|
||||
```
|
||||
|
||||
This configuration doesn't overwrite the compliance pipeline and you get the following message:
|
||||
`take compliance action`.
|
||||
|
||||
### Prefilled variables are not shown
|
||||
|
||||
Because of a [known issue](https://gitlab.com/gitlab-org/gitlab/-/issues/382857),
|
||||
compliance pipelines in GitLab 15.3 and later can prevent
|
||||
[prefilled variables](../../ci/pipelines/_index.md#prefill-variables-in-manual-pipelines)
|
||||
from appearing when manually starting a pipeline.
|
||||
|
||||
To workaround this issue, use `ref: '$CI_COMMIT_SHA'` instead of `ref: '$CI_COMMIT_REF_NAME'`
|
||||
in the `include:` statement that executes the individual project's configuration.
|
||||
|
||||
The [example configuration](#example-configuration) has been updated with this change:
|
||||
|
||||
```yaml
|
||||
include:
|
||||
- project: '$CI_PROJECT_PATH'
|
||||
file: '$CI_CONFIG_PATH'
|
||||
ref: '$CI_COMMIT_SHA'
|
||||
```
|
||||
|
||||
### Error: `Job names must be unique`
|
||||
|
||||
To configure a compliance pipeline, the [example configuration](#example-configuration) recommends including the
|
||||
individual project configuration with `include.project`.
|
||||
|
||||
The configuration can lead to an error when running the projects pipeline: `Pipeline execution policy error: Job names must be unique`.
|
||||
This error occurs because the pipeline execution policy includes the project's `.gitlab-ci.yml` and tries to insert the
|
||||
jobs when the jobs have already been declared in the pipeline.
|
||||
|
||||
To resolve this error, remove `include.project` from the separate YAML file linked in the pipeline execution policy.
|
||||
|
||||
<!--- end_remove -->
|
||||
|
|
@ -43,7 +43,7 @@ License approval policies rely on the output of a dependency scanning job to ver
|
|||
To ensure enforcement of your policies, you should enable dependency scanning on your target development projects. You can achieve this a few different ways:
|
||||
|
||||
- Create a global [scan execution policy](../application_security/policies/scan_execution_policies.md) that enforces Dependency Scanning to run in all target development projects.
|
||||
- Use a [Compliance Pipeline](../group/compliance_frameworks.md) to define a Dependency Scanning job that is enforced on projects enforced by a given Compliance Framework.
|
||||
- Use a [Compliance Pipeline](../compliance/compliance_frameworks.md) to define a Dependency Scanning job that is enforced on projects enforced by a given Compliance Framework.
|
||||
- Work with development teams to configure [Dependency Scanning](../application_security/dependency_scanning/_index.md) in each of their project's `.gitlab-ci.yml` files or enable by using the [Security Configuration panel](../application_security/configuration/_index.md).
|
||||
|
||||
License approval policies require license information from [GitLab-supported packages](license_scanning_of_cyclonedx_files/_index.md#supported-languages-and-package-managers).
|
||||
|
|
|
|||
|
|
@ -1,112 +1,13 @@
|
|||
---
|
||||
stage: Software Supply Chain Security
|
||||
group: Compliance
|
||||
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
|
||||
title: Compliance frameworks
|
||||
redirect_to: '../compliance/compliance_frameworks.md'
|
||||
remove_date: '2025-05-25'
|
||||
---
|
||||
|
||||
{{< details >}}
|
||||
<!-- markdownlint-disable -->
|
||||
|
||||
- Tier: Premium, Ultimate
|
||||
- Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
|
||||
This document was moved to [another location](../compliance/compliance_frameworks.md).
|
||||
|
||||
{{< /details >}}
|
||||
|
||||
You can create a compliance framework that is a label to identify that your project has certain compliance
|
||||
requirements or needs additional oversight.
|
||||
|
||||
In the Ultimate tier, the compliance framework can optionally enforce
|
||||
[compliance pipeline configuration](compliance_pipelines.md) and
|
||||
[security policies](../application_security/policies/_index.md#scope) to the projects on which it is applied.
|
||||
|
||||
Compliance frameworks are created on top-level groups. If a project is moved outside of its existing top-level group,
|
||||
its frameworks are removed.
|
||||
|
||||
You can apply up to 20 compliance frameworks to each project.
|
||||
|
||||
For a click-through demo, see [Compliance frameworks](https://gitlab.navattic.com/compliance).
|
||||
<!-- Demo published on 2025-01-27 -->
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- To create, edit, and delete compliance frameworks, users must have either:
|
||||
- The Owner role for the top-level group.
|
||||
- Be assigned a [custom role](../custom_roles.md) with the `admin_compliance_framework`
|
||||
[custom permission](../custom_roles/abilities.md#compliance-management).
|
||||
- To add or remove a compliance framework to or from a project, the group to which the project belongs must have a
|
||||
compliance framework.
|
||||
|
||||
## Create, edit, or delete a compliance framework
|
||||
|
||||
You can create, edit, or delete a compliance framework from a compliance framework report. For more information, see:
|
||||
|
||||
- [Create a new compliance framework](../compliance/compliance_center/compliance_frameworks_report.md#create-a-new-compliance-framework).
|
||||
- [Edit a compliance framework](../compliance/compliance_center/compliance_frameworks_report.md#edit-a-compliance-framework).
|
||||
- [Delete a compliance framework](../compliance/compliance_center/compliance_frameworks_report.md#delete-a-compliance-framework).
|
||||
|
||||
You can create, edit, or delete a compliance framework from a compliance projects report. For more information, see:
|
||||
|
||||
- [Create a new compliance framework](../compliance/compliance_center/compliance_projects_report.md#create-a-new-compliance-framework).
|
||||
- [Edit a compliance framework](../compliance/compliance_center/compliance_projects_report.md#edit-a-compliance-framework).
|
||||
- [Delete a compliance framework](../compliance/compliance_center/compliance_projects_report.md#delete-a-compliance-framework).
|
||||
|
||||
Subgroups and projects have access to all compliance frameworks created on their top-level group. However, compliance frameworks cannot be created, edited,
|
||||
or deleted at the subgroup or project level. Project owners can choose a framework to apply to their projects.
|
||||
|
||||
## Apply a compliance framework to a project
|
||||
|
||||
{{< history >}}
|
||||
|
||||
- Assigning multiple compliance frameworks [introduced](https://gitlab.com/groups/gitlab-org/-/epics/13294) in GitLab 17.3.
|
||||
|
||||
{{< /history >}}
|
||||
|
||||
You can apply multiple compliance frameworks to a project but cannot apply compliance frameworks to projects in personal namespaces.
|
||||
|
||||
To apply a compliance framework to a project, apply the compliance framework through the
|
||||
[Compliance projects report](../compliance/compliance_center/compliance_projects_report.md#apply-a-compliance-framework-to-projects-in-a-group).
|
||||
|
||||
You can use the [GraphQL API](../../api/graphql/reference/_index.md#mutationprojectupdatecomplianceframeworks) to apply one or many
|
||||
compliance frameworks to a project.
|
||||
|
||||
If you create compliance frameworks on subgroups with GraphQL, the framework is created on the root ancestor if the user
|
||||
has the correct permissions. The GitLab UI presents a read-only view to discourage this behavior.
|
||||
|
||||
## Default compliance frameworks
|
||||
|
||||
{{< history >}}
|
||||
|
||||
- [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/375036) in GitLab 15.6.
|
||||
|
||||
{{< /history >}}
|
||||
|
||||
Group owners can set a default compliance framework. The default framework is applied to all the new and imported
|
||||
projects that are created in that group. It does not affect the framework applied to the existing projects. The
|
||||
default framework cannot be deleted.
|
||||
|
||||
A compliance framework that is set to default has a **default** label.
|
||||
|
||||
### Set and remove a default by using the compliance center
|
||||
|
||||
To set as default (or remove the default) from [compliance projects report](../compliance/compliance_center/compliance_projects_report.md):
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your group.
|
||||
1. Select **Secure > Compliance center**.
|
||||
1. On the page, select the **Projects** tab.
|
||||
1. Hover over a compliance framework, select the **Edit Framework** tab.
|
||||
1. Select **Set as default**.
|
||||
1. Select **Save changes**.
|
||||
|
||||
To set as default (or remove the default) from [compliance framework report](../compliance/compliance_center/compliance_frameworks_report.md):
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your group.
|
||||
1. Select **Secure > Compliance center**.
|
||||
1. On the page, select the **Frameworks** tab.
|
||||
1. Hover over a compliance framework, select the **Edit Framework** tab.
|
||||
1. Select **Set as default**.
|
||||
1. Select **Save changes**.
|
||||
|
||||
## Remove a compliance framework from a project
|
||||
|
||||
To remove a compliance framework from one or multiple project in a group, remove the compliance framework through the
|
||||
[Compliance projects report](../compliance/compliance_center/compliance_projects_report.md#remove-a-compliance-framework-from-projects-in-a-group).
|
||||
<!-- This redirect file can be deleted after <YYYY-MM-DD>. -->
|
||||
<!-- Redirects that point to other docs in the same project expire in three months. -->
|
||||
<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
|
||||
<!-- Before deletion, see: https://docs.gitlab.com/development/documentation/redirects -->
|
||||
|
|
@ -1,416 +1,13 @@
|
|||
---
|
||||
stage: Software Supply Chain Security
|
||||
group: Compliance
|
||||
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
|
||||
title: Compliance pipelines (deprecated)
|
||||
redirect_to: '../compliance/compliance_pipelines.md'
|
||||
remove_date: '2025-05-25'
|
||||
---
|
||||
|
||||
<!--- start_remove The following content will be removed on remove_date: '2025-08-15' -->
|
||||
<!-- markdownlint-disable -->
|
||||
|
||||
{{< details >}}
|
||||
This document was moved to [another location](../compliance/compliance_pipelines.md).
|
||||
|
||||
- Tier: Ultimate
|
||||
- Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
|
||||
|
||||
{{< /details >}}
|
||||
|
||||
{{< alert type="warning" >}}
|
||||
|
||||
This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/159841) in GitLab 17.3
|
||||
and is planned for removal in 19.0. Use [pipeline execution policy type](../application_security/policies/pipeline_execution_policies.md) instead.
|
||||
This change is a breaking change. For more information, see the [migration guide](#pipeline-execution-policies-migration).
|
||||
|
||||
{{< /alert >}}
|
||||
|
||||
Group owners can configure a compliance pipeline in a project separate to other projects. By default, the compliance
|
||||
pipeline configuration (for example, `.compliance-gitlab-ci.yml`) is run instead of the pipeline configuration (for example, `.gitlab-ci.yml`) of labeled
|
||||
projects.
|
||||
|
||||
However, the compliance pipeline configuration can reference the `.gitlab-ci.yml` file of the labeled projects so that:
|
||||
|
||||
- The compliance pipeline can also run jobs of labeled project pipelines. This allows for centralized control of
|
||||
pipeline configuration.
|
||||
- Jobs and variables defined in the compliance pipeline can't be changed by variables in the labeled project's
|
||||
`.gitlab-ci.yml` file.
|
||||
|
||||
{{< alert type="note" >}}
|
||||
|
||||
Because of a [known issue](https://gitlab.com/gitlab-org/gitlab/-/issues/414004), project pipelines must be included first at the top of compliance pipeline configuration
|
||||
to prevent projects overriding settings downstream.
|
||||
|
||||
{{< /alert >}}
|
||||
|
||||
For more information, see:
|
||||
|
||||
- [Example configuration](#example-configuration) for help configuring a compliance pipeline that runs jobs from
|
||||
labeled project pipeline configuration.
|
||||
- The [Create a compliance pipeline](../../tutorials/compliance_pipeline/_index.md) tutorial.
|
||||
|
||||
## Pipeline execution policies migration
|
||||
|
||||
To consolidate and simplify scan and pipeline enforcement, we have introduced pipeline execution policies. We deprecated
|
||||
compliance pipelines in GitLab 17.3 and will remove compliance pipelines in GitLab 19.0.
|
||||
|
||||
Pipeline execution policies extend a project's `.gitlab-ci.yml` file with the configuration provided in separate YAML file
|
||||
(for example, `pipeline-execution.yml`) linked in the pipeline execution policy.
|
||||
|
||||
By default, when creating a new compliance framework, you are directed to use the pipeline execution policy type instead
|
||||
of compliance pipelines.
|
||||
|
||||
Existing compliance pipelines must be migrated. Customers should migrate from compliance pipelines to the new
|
||||
[pipeline execution policy type](../application_security/policies/pipeline_execution_policies.md) as soon as possible.
|
||||
|
||||
### Migrate an existing compliance framework
|
||||
|
||||
To migrate an existing compliance framework to use the pipeline execution policy type:
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your group.
|
||||
1. Select **Secure > Compliance center**.
|
||||
1. [Edit](compliance_frameworks.md#create-edit-or-delete-a-compliance-framework) the existing compliance framework.
|
||||
1. In the banner than appears, select **Migrate pipeline to a policy** to create a new policy in the security policies.
|
||||
1. Edit the compliance framework again to remove the compliance pipeline.
|
||||
|
||||
For more information, see [Security policy project](../application_security/policies/_index.md#security-policy-project).
|
||||
|
||||
If you receive a `Pipeline execution policy error: Job names must be unique` error during the migration, see the
|
||||
[relevant troubleshooting information](#error-job-names-must-be-unique).
|
||||
|
||||
## Effect on labeled projects
|
||||
|
||||
Users have no way of knowing that a compliance pipeline has been configured and might be confused why their own
|
||||
pipelines are not running at all, or include jobs that they did not define themselves.
|
||||
|
||||
When authoring pipelines on a labeled project, there is no indication that a compliance pipeline has been configured.
|
||||
The only marker at the project level is the compliance framework label itself, but the label does not say whether the
|
||||
framework has a compliance pipeline configured or not.
|
||||
|
||||
Therefore, communicate with project users about compliance pipeline configuration to reduce uncertainty and confusion.
|
||||
|
||||
### Multiple compliance frameworks
|
||||
|
||||
You can [apply to a single project](compliance_frameworks.md#apply-a-compliance-framework-to-a-project) multiple compliance frameworks with compliance pipelines configured.
|
||||
In this case, only the first compliance framework applied to a project has its compliance pipeline included in the project pipeline.
|
||||
|
||||
To ensure that the correct compliance pipeline is included in a project:
|
||||
|
||||
1. Remove all compliance frameworks from the project.
|
||||
1. Apply the compliance framework with the correct compliance pipeline to the project.
|
||||
1. Apply additional compliance frameworks to the project.
|
||||
|
||||
## Configure a compliance pipeline
|
||||
|
||||
{{< history >}}
|
||||
|
||||
- [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/383209) in GitLab 15.11, compliance frameworks moved to compliance center.
|
||||
|
||||
{{< /history >}}
|
||||
|
||||
To configure a compliance pipeline:
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your group.
|
||||
1. Select **Secure** > **Compliance Center**.
|
||||
1. Select **Frameworks** section.
|
||||
1. Select **New framework** section, add information of compliance framework including path to the compliance framework configuration. Use the
|
||||
`path/file.y[a]ml@group-name/project-name` format. For example:
|
||||
|
||||
- `.compliance-ci.yml@gitlab-org/gitlab`.
|
||||
- `.compliance-ci.yaml@gitlab-org/gitlab`.
|
||||
|
||||
This configuration is inherited by projects where the compliance framework label is
|
||||
[applied](../project/working_with_projects.md#add-a-compliance-framework-to-a-project). In projects with the applied compliance
|
||||
framework label, the compliance pipeline configuration is run instead of the labeled project's own pipeline configuration.
|
||||
|
||||
The user running the pipeline in the labeled project must at least have the Reporter role on the compliance project.
|
||||
|
||||
When used to enforce scan execution, this feature has some overlap with
|
||||
[scan execution policies](../application_security/policies/scan_execution_policies.md). We have not
|
||||
[unified the user experience for these two features](https://gitlab.com/groups/gitlab-org/-/epics/7312). For details on
|
||||
the similarities and differences between these features, see [Enforce scan execution](../application_security/_index.md#enforce-scan-execution).
|
||||
|
||||
### Example configuration
|
||||
|
||||
The following example `.compliance-gitlab-ci.yml` includes the `include` keyword to ensure labeled project pipeline
|
||||
configuration is also executed.
|
||||
|
||||
```yaml
|
||||
include: # Execute individual project's configuration (if project contains .gitlab-ci.yml)
|
||||
- project: '$CI_PROJECT_PATH'
|
||||
file: '$CI_CONFIG_PATH'
|
||||
ref: '$CI_COMMIT_SHA' # Must be defined or MR pipelines always use the use default branch
|
||||
rules:
|
||||
- if: $CI_PROJECT_PATH != "my-group/project-1" # Must run on projects other than the one hosting this configuration.
|
||||
|
||||
# Allows compliance team to control the ordering and interweaving of stages/jobs.
|
||||
# Stages without jobs defined will remain hidden.
|
||||
stages:
|
||||
- pre-compliance
|
||||
- build
|
||||
- test
|
||||
- pre-deploy-compliance
|
||||
- deploy
|
||||
- post-compliance
|
||||
|
||||
variables: # Can be overridden by setting a job-specific variable in project's local .gitlab-ci.yml
|
||||
FOO: sast
|
||||
|
||||
sast: # None of these attributes can be overridden by a project's local .gitlab-ci.yml
|
||||
variables:
|
||||
FOO: sast
|
||||
image: ruby:2.6
|
||||
stage: pre-compliance
|
||||
rules:
|
||||
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"
|
||||
when: never
|
||||
- when: always # or when: on_success
|
||||
allow_failure: false
|
||||
before_script:
|
||||
- "# No before scripts."
|
||||
script:
|
||||
- echo "running $FOO"
|
||||
after_script:
|
||||
- "# No after scripts."
|
||||
|
||||
sanity check:
|
||||
image: ruby:2.6
|
||||
stage: pre-deploy-compliance
|
||||
rules:
|
||||
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"
|
||||
when: never
|
||||
- when: always # or when: on_success
|
||||
allow_failure: false
|
||||
before_script:
|
||||
- "# No before scripts."
|
||||
script:
|
||||
- echo "running $FOO"
|
||||
after_script:
|
||||
- "# No after scripts."
|
||||
|
||||
audit trail:
|
||||
image: ruby:2.7
|
||||
stage: post-compliance
|
||||
rules:
|
||||
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"
|
||||
when: never
|
||||
- when: always # or when: on_success
|
||||
allow_failure: false
|
||||
before_script:
|
||||
- "# No before scripts."
|
||||
script:
|
||||
- echo "running $FOO"
|
||||
after_script:
|
||||
- "# No after scripts."
|
||||
```
|
||||
|
||||
The `rules` configuration in the `include` definition avoids circular inclusion in case the compliance pipeline must be able to run in the host project itself.
|
||||
You can leave it out if your compliance pipeline only ever runs in labeled projects.
|
||||
|
||||
#### Compliance pipelines and custom pipeline configuration hosted externally
|
||||
|
||||
The example above assumes that all projects host their pipeline configuration in the same project.
|
||||
If any projects use [configuration hosted externally](../../ci/pipelines/settings.md#specify-a-custom-cicd-configuration-file),
|
||||
the example configuration does not work. See [issue 393960](https://gitlab.com/gitlab-org/gitlab/-/issues/393960)
|
||||
for more details.
|
||||
|
||||
With projects that use externally hosted configuration, you can try the this workaround:
|
||||
|
||||
- The `include` section in the example compliance pipeline configuration must be adjusted.
|
||||
For example, using [`include:rules`](../../ci/yaml/includes.md#use-rules-with-include):
|
||||
|
||||
```yaml
|
||||
include:
|
||||
# If the custom path variables are defined, include the project's external config file.
|
||||
- project: '$PROTECTED_PIPELINE_CI_PROJECT_PATH'
|
||||
file: '$PROTECTED_PIPELINE_CI_CONFIG_PATH'
|
||||
ref: '$PROTECTED_PIPELINE_CI_REF'
|
||||
rules:
|
||||
- if: $PROTECTED_PIPELINE_CI_PROJECT_PATH && $PROTECTED_PIPELINE_CI_CONFIG_PATH && $PROTECTED_PIPELINE_CI_REF
|
||||
# If any custom path variable is not defined, include the project's internal config file as normal.
|
||||
- project: '$CI_PROJECT_PATH'
|
||||
file: '$CI_CONFIG_PATH'
|
||||
ref: '$CI_COMMIT_SHA'
|
||||
rules:
|
||||
- if: $PROTECTED_PIPELINE_CI_PROJECT_PATH == null || $PROTECTED_PIPELINE_CI_CONFIG_PATH == null || $PROTECTED_PIPELINE_CI_REF == null
|
||||
```
|
||||
|
||||
- [CI/CD variables](../../ci/variables/_index.md) must be added to projects with external
|
||||
pipeline configuration. In this example:
|
||||
|
||||
- `PROTECTED_PIPELINE_CI_PROJECT_PATH`: The path to the project hosting the configuration file, for example `group/subgroup/project`.
|
||||
- `PROTECTED_PIPELINE_CI_CONFIG_PATH`: The path to the configuration file in the project, for example `path/to/.gitlab-ci.yml`.
|
||||
- `PROTECTED_PIPELINE_CI_REF`: The ref to use when retrieving the configuration file, for example `main`.
|
||||
|
||||
#### Compliance pipelines in merge requests originating in project forks
|
||||
|
||||
When a merge request originates in a fork, the branch to be merged usually only exists in the fork.
|
||||
When creating such a merge request against a project with compliance pipelines, the above snippet fails with a
|
||||
`Project <project-name> reference <branch-name> does not exist!` error message.
|
||||
This error occurs because in the context of the target project, `$CI_COMMIT_REF_NAME` evaluates to a non-existing
|
||||
branch name.
|
||||
|
||||
To get the correct context, use `$CI_MERGE_REQUEST_SOURCE_PROJECT_PATH` instead of `$CI_PROJECT_PATH`.
|
||||
This variable is only available in
|
||||
[merge request pipelines](../../ci/pipelines/merge_request_pipelines.md).
|
||||
|
||||
For example, for a configuration that supports both merge request pipelines originating in project forks and branch pipelines,
|
||||
you need to [combine both `include` directives with `rules:if`](../../ci/yaml/includes.md#use-rules-with-include):
|
||||
|
||||
```yaml
|
||||
include: # Execute individual project's configuration (if project contains .gitlab-ci.yml)
|
||||
- project: '$CI_MERGE_REQUEST_SOURCE_PROJECT_PATH'
|
||||
file: '$CI_CONFIG_PATH'
|
||||
ref: '$CI_COMMIT_REF_NAME'
|
||||
rules:
|
||||
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
|
||||
- project: '$CI_PROJECT_PATH'
|
||||
file: '$CI_CONFIG_PATH'
|
||||
ref: '$CI_COMMIT_REF_NAME'
|
||||
rules:
|
||||
- if: $CI_PIPELINE_SOURCE != 'merge_request_event'
|
||||
```
|
||||
|
||||
#### Compliance pipelines in projects with no configuration file
|
||||
|
||||
The [example configuration](#example-configuration) above assumes that all projects contain
|
||||
a pipeline configuration file (`.gitlab-ci.yml` by default). However, in projects
|
||||
with no configuration file (and therefore no pipelines by default), the compliance pipeline
|
||||
fails because the file specified in `include:project` is required.
|
||||
|
||||
To only include a configuration file if it exists in a target project, use
|
||||
[`rules:exists:project`](../../ci/yaml/_index.md#rulesexistsproject):
|
||||
|
||||
```yaml
|
||||
include: # Execute individual project's configuration
|
||||
- project: '$CI_PROJECT_PATH'
|
||||
file: '$CI_CONFIG_PATH'
|
||||
ref: '$CI_COMMIT_SHA'
|
||||
rules:
|
||||
- exists:
|
||||
paths:
|
||||
- '$CI_CONFIG_PATH'
|
||||
project: '$CI_PROJECT_PATH'
|
||||
ref: '$CI_COMMIT_SHA'
|
||||
```
|
||||
|
||||
In this example, a configuration file is only included if it exists for the given `ref`
|
||||
in the project in `exists:project: $CI_PROJECT_PATH'`.
|
||||
|
||||
If `exists:project` is not specified in the compliance pipeline configuration, it searches for files in the project
|
||||
in which the `include` is defined. In compliance pipelines, the `include` from the example above
|
||||
is defined in the project hosting the compliance pipeline configuration file, not the project
|
||||
running the pipeline.
|
||||
|
||||
## Ensure compliance jobs are always run
|
||||
|
||||
Compliance pipelines [use GitLab CI/CD](../../ci/_index.md) to give you an incredible amount of flexibility
|
||||
for defining any sort of compliance jobs you like. Depending on your goals, these jobs
|
||||
can be configured to be:
|
||||
|
||||
- Modified by users.
|
||||
- Non-modifiable.
|
||||
|
||||
Generally, if a value in a compliance job:
|
||||
|
||||
- Is set, it cannot be changed or overridden by project-level configurations.
|
||||
- Is not set, a project-level configuration may be set.
|
||||
|
||||
Either might be wanted or not depending on your use case.
|
||||
|
||||
The following are a few best practices for ensuring that these jobs are always run exactly
|
||||
as you define them and that downstream, project-level pipeline configurations
|
||||
cannot change them:
|
||||
|
||||
- Add [a `rules:when:always` block](../../ci/yaml/_index.md#when) to each of your compliance jobs. This ensures they are
|
||||
non-modifiable and are always run.
|
||||
- Explicitly set any [variables](../../ci/yaml/_index.md#variables) the job references. This:
|
||||
- Ensures that project-level pipeline configurations do not set them and alter their
|
||||
behavior. For example, see `before_script` and `after_script` configuration in the [example configuration](#example-configuration).
|
||||
- Includes any jobs that drive the logic of your job.
|
||||
- Explicitly set the [container image](../../ci/yaml/_index.md#image) to run the job in. This ensures that your script
|
||||
steps execute in the correct environment.
|
||||
- Explicitly set any relevant GitLab pre-defined [job keywords](../../ci/yaml/_index.md#job-keywords).
|
||||
This ensures that your job uses the settings you intend and that they are not overridden by
|
||||
project-level pipelines.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Compliance jobs are overwritten by target repository
|
||||
|
||||
If you use the `extends` statement in a compliance pipeline configuration, compliance jobs are overwritten by the target repository job. For example,
|
||||
you could have the following `.compliance-gitlab-ci.yml` configuration:
|
||||
|
||||
```yaml
|
||||
"compliance job":
|
||||
extends:
|
||||
- .compliance_template
|
||||
stage: build
|
||||
|
||||
.compliance_template:
|
||||
script:
|
||||
- echo "take compliance action"
|
||||
```
|
||||
|
||||
You could also have the following `.gitlab-ci.yml` configuration:
|
||||
|
||||
```yaml
|
||||
"compliance job":
|
||||
stage: test
|
||||
script:
|
||||
- echo "overwriting compliance action"
|
||||
```
|
||||
|
||||
This configuration results in the target repository pipeline overwriting the compliance pipeline, and you get the following message:
|
||||
`overwriting compliance action`.
|
||||
|
||||
To avoid overwriting a compliance job, don't use the `extends` keyword in compliance pipeline configuration. For example,
|
||||
you could have the following `.compliance-gitlab-ci.yml` configuration:
|
||||
|
||||
```yaml
|
||||
"compliance job":
|
||||
stage: build
|
||||
script:
|
||||
- echo "take compliance action"
|
||||
```
|
||||
|
||||
You could also have the following `.gitlab-ci.yml` configuration:
|
||||
|
||||
```yaml
|
||||
"compliance job":
|
||||
stage: test
|
||||
script:
|
||||
- echo "overwriting compliance action"
|
||||
```
|
||||
|
||||
This configuration doesn't overwrite the compliance pipeline and you get the following message:
|
||||
`take compliance action`.
|
||||
|
||||
### Prefilled variables are not shown
|
||||
|
||||
Because of a [known issue](https://gitlab.com/gitlab-org/gitlab/-/issues/382857),
|
||||
compliance pipelines in GitLab 15.3 and later can prevent
|
||||
[prefilled variables](../../ci/pipelines/_index.md#prefill-variables-in-manual-pipelines)
|
||||
from appearing when manually starting a pipeline.
|
||||
|
||||
To workaround this issue, use `ref: '$CI_COMMIT_SHA'` instead of `ref: '$CI_COMMIT_REF_NAME'`
|
||||
in the `include:` statement that executes the individual project's configuration.
|
||||
|
||||
The [example configuration](#example-configuration) has been updated with this change:
|
||||
|
||||
```yaml
|
||||
include:
|
||||
- project: '$CI_PROJECT_PATH'
|
||||
file: '$CI_CONFIG_PATH'
|
||||
ref: '$CI_COMMIT_SHA'
|
||||
```
|
||||
|
||||
### Error: `Job names must be unique`
|
||||
|
||||
To configure a compliance pipeline, the [example configuration](#example-configuration) recommends including the
|
||||
individual project configuration with `include.project`.
|
||||
|
||||
The configuration can lead to an error when running the projects pipeline: `Pipeline execution policy error: Job names must be unique`.
|
||||
This error occurs because the pipeline execution policy includes the project's `.gitlab-ci.yml` and tries to insert the
|
||||
jobs when the jobs have already been declared in the pipeline.
|
||||
|
||||
To resolve this error, remove `include.project` from the separate YAML file linked in the pipeline execution policy.
|
||||
|
||||
<!--- end_remove -->
|
||||
<!-- This redirect file can be deleted after <YYYY-MM-DD>. -->
|
||||
<!-- Redirects that point to other docs in the same project expire in three months. -->
|
||||
<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
|
||||
<!-- Before deletion, see: https://docs.gitlab.com/development/documentation/redirects -->
|
||||
|
|
@ -469,8 +469,8 @@ Group permissions for [compliance](compliance/_index.md) features including comp
|
|||
| View [audit events](compliance/audit_events.md) | | | | ✓ | ✓ | ✓ | Users can view only events based on their individual actions. For more details, see the [prerequisites](compliance/audit_events.md#prerequisites). |
|
||||
| View licenses in the [dependency list](application_security/dependency_list/_index.md) | | | | ✓ | ✓ | ✓ | |
|
||||
| View the [compliance center](compliance/compliance_center/_index.md) | | | | | | ✓ | |
|
||||
| Manage [compliance frameworks](group/compliance_frameworks.md) | | | | | | ✓ | |
|
||||
| Assign [compliance frameworks](group/compliance_frameworks.md) to projects | | | | | | ✓ | |
|
||||
| Manage [compliance frameworks](compliance/compliance_frameworks.md) | | | | | | ✓ | |
|
||||
| Assign [compliance frameworks](compliance/compliance_frameworks.md) to projects | | | | | | ✓ | |
|
||||
| Manage [audit streams](compliance/audit_event_streaming.md) | | | | | | ✓ | |
|
||||
|
||||
### GitLab Duo group permissions
|
||||
|
|
|
|||
|
|
@ -597,7 +597,7 @@ To leave a project:
|
|||
|
||||
{{< /details >}}
|
||||
|
||||
You can add compliance frameworks to projects in a group that has a [compliance framework](../group/compliance_frameworks.md).
|
||||
You can add compliance frameworks to projects in a group that has a [compliance framework](../compliance/compliance_frameworks.md).
|
||||
|
||||
## Manage project access through LDAP groups
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ PATH
|
|||
gitlab-http (0.1.0)
|
||||
activesupport (~> 7)
|
||||
concurrent-ruby (~> 1.2)
|
||||
httparty (~> 0.21.0)
|
||||
httparty (~> 0.21)
|
||||
ipaddress (~> 0.8.3)
|
||||
net-http (= 0.6.0)
|
||||
railties (~> 7)
|
||||
|
|
@ -62,6 +62,7 @@ GEM
|
|||
crack (0.4.5)
|
||||
rexml
|
||||
crass (1.0.6)
|
||||
csv (3.3.2)
|
||||
debug_inspector (1.2.0)
|
||||
diff-lcs (1.5.0)
|
||||
erubi (1.12.0)
|
||||
|
|
@ -75,7 +76,8 @@ GEM
|
|||
rubocop-rspec (~> 3.0.4)
|
||||
rubocop-rspec_rails (~> 2.30.0)
|
||||
hashdiff (1.0.1)
|
||||
httparty (0.21.0)
|
||||
httparty (0.22.0)
|
||||
csv
|
||||
mini_mime (>= 1.0.0)
|
||||
multi_xml (>= 0.5.2)
|
||||
i18n (1.14.1)
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
|
|||
|
||||
spec.add_runtime_dependency 'activesupport', '~> 7'
|
||||
spec.add_runtime_dependency 'concurrent-ruby', '~> 1.2'
|
||||
spec.add_runtime_dependency 'httparty', '~> 0.21.0'
|
||||
spec.add_runtime_dependency 'httparty', '~> 0.21'
|
||||
spec.add_runtime_dependency 'ipaddress', '~> 0.8.3'
|
||||
spec.add_runtime_dependency "railties", "~> 7"
|
||||
# See lib/net_http/connect_patch.rb
|
||||
|
|
|
|||
|
|
@ -70,7 +70,8 @@ module API
|
|||
'available only on Premium and Ultimate tiers.'
|
||||
end
|
||||
route_setting :authentication, job_token_allowed: true
|
||||
route_setting :authorization, job_token_policies: :read_jobs
|
||||
route_setting :authorization, job_token_policies: :read_jobs,
|
||||
allow_public_access_for_enabled_project_features: [:repository, :builds]
|
||||
get ':id/jobs/artifacts/:ref_name/raw/*artifact_path',
|
||||
urgency: :low,
|
||||
format: false,
|
||||
|
|
|
|||
|
|
@ -392,7 +392,8 @@ module API
|
|||
optional :direct_download, default: false, type: Boolean, desc: 'Perform direct download from remote storage instead of proxying artifacts'
|
||||
end
|
||||
route_setting :authentication, job_token_allowed: true
|
||||
route_setting :authorization, job_token_policies: :read_jobs
|
||||
route_setting :authorization, job_token_policies: :read_jobs,
|
||||
allow_public_access_for_enabled_project_features: [:repository, :builds]
|
||||
get '/:id/artifacts', feature_category: :job_artifacts do
|
||||
authenticate_job_via_dependent_job!
|
||||
authorize_job_token_policies!(current_job.project)
|
||||
|
|
|
|||
|
|
@ -204,7 +204,8 @@ module API
|
|||
requires :package_name, type: String, file_path: true, desc: 'The Composer package name', documentation: { example: 'my-composer-package' }
|
||||
end
|
||||
route_setting :authentication, job_token_allowed: :basic_auth, basic_auth_personal_access_token: true, deploy_token_allowed: true
|
||||
route_setting :authorization, job_token_policies: :read_packages
|
||||
route_setting :authorization, job_token_policies: :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry
|
||||
get 'archives/*package_name', urgency: :default do
|
||||
project = authorized_user_project(action: :read_package)
|
||||
authorize_job_token_policies!(project)
|
||||
|
|
|
|||
|
|
@ -59,7 +59,8 @@ module API
|
|||
tags %w[conan_packages]
|
||||
end
|
||||
route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true
|
||||
route_setting :authorization, job_token_policies: :read_packages
|
||||
route_setting :authorization, job_token_policies: :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry
|
||||
get urgency: :low do
|
||||
download_package_file(:recipe_file)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -110,7 +110,8 @@ module API
|
|||
end
|
||||
|
||||
route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true
|
||||
route_setting :authorization, job_token_policies: :read_packages
|
||||
route_setting :authorization, job_token_policies: :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry
|
||||
|
||||
get 'packages/:conan_package_reference', urgency: :low do
|
||||
authorize_read_package!(project)
|
||||
|
|
@ -137,7 +138,8 @@ module API
|
|||
end
|
||||
|
||||
route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true
|
||||
route_setting :authorization, job_token_policies: :read_packages
|
||||
route_setting :authorization, job_token_policies: :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry
|
||||
|
||||
get urgency: :low do
|
||||
authorize_read_package!(project)
|
||||
|
|
@ -168,7 +170,8 @@ module API
|
|||
end
|
||||
|
||||
route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true
|
||||
route_setting :authorization, job_token_policies: :read_packages
|
||||
route_setting :authorization, job_token_policies: :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry
|
||||
|
||||
get 'packages/:conan_package_reference/digest', urgency: :low do
|
||||
present_package_download_urls
|
||||
|
|
@ -186,7 +189,8 @@ module API
|
|||
end
|
||||
|
||||
route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true
|
||||
route_setting :authorization, job_token_policies: :read_packages
|
||||
route_setting :authorization, job_token_policies: :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry
|
||||
|
||||
get 'digest', urgency: :low do
|
||||
present_recipe_download_urls
|
||||
|
|
@ -215,7 +219,8 @@ module API
|
|||
end
|
||||
|
||||
route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true
|
||||
route_setting :authorization, job_token_policies: :read_packages
|
||||
route_setting :authorization, job_token_policies: :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry
|
||||
|
||||
get 'packages/:conan_package_reference/download_urls', urgency: :low do
|
||||
present_package_download_urls
|
||||
|
|
@ -233,7 +238,8 @@ module API
|
|||
end
|
||||
|
||||
route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true
|
||||
route_setting :authorization, job_token_policies: :read_packages
|
||||
route_setting :authorization, job_token_policies: :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry
|
||||
|
||||
get 'download_urls', urgency: :low do
|
||||
present_recipe_download_urls
|
||||
|
|
@ -263,7 +269,8 @@ module API
|
|||
end
|
||||
|
||||
route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true
|
||||
route_setting :authorization, job_token_policies: :read_packages
|
||||
route_setting :authorization, job_token_policies: :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry
|
||||
|
||||
post 'packages/:conan_package_reference/upload_urls', urgency: :low do
|
||||
authorize_read_package!(project)
|
||||
|
|
@ -284,7 +291,8 @@ module API
|
|||
end
|
||||
|
||||
route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true
|
||||
route_setting :authorization, job_token_policies: :read_packages
|
||||
route_setting :authorization, job_token_policies: :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry
|
||||
|
||||
post 'upload_urls', urgency: :low do
|
||||
authorize_read_package!(project)
|
||||
|
|
@ -358,7 +366,8 @@ module API
|
|||
end
|
||||
|
||||
route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true
|
||||
route_setting :authorization, job_token_policies: :read_packages
|
||||
route_setting :authorization, job_token_policies: :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry
|
||||
|
||||
get urgency: :low do
|
||||
download_package_file(:recipe_file)
|
||||
|
|
@ -430,7 +439,8 @@ module API
|
|||
end
|
||||
|
||||
route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true
|
||||
route_setting :authorization, job_token_policies: :read_packages
|
||||
route_setting :authorization, job_token_policies: :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry
|
||||
|
||||
get urgency: :low do
|
||||
download_package_file(:package_file)
|
||||
|
|
|
|||
|
|
@ -79,7 +79,8 @@ module API
|
|||
end
|
||||
route_setting :authentication, job_token_allowed: true, deploy_token_allowed: true,
|
||||
authenticate_non_public: true
|
||||
route_setting :authorization, job_token_policies: :read_packages
|
||||
route_setting :authorization, job_token_policies: :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry
|
||||
get 'dist-tags', format: false, requirements: ::API::Helpers::Packages::Npm::NPM_ENDPOINT_REQUIREMENTS do
|
||||
package_name = params[:package_name]
|
||||
|
||||
|
|
@ -194,7 +195,8 @@ module API
|
|||
tags %w[npm_packages]
|
||||
end
|
||||
route_setting :authentication, job_token_allowed: true, deploy_token_allowed: true
|
||||
route_setting :authorization, job_token_policies: :read_packages
|
||||
route_setting :authorization, job_token_policies: :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry
|
||||
post '-/npm/v1/security/advisories/bulk' do
|
||||
redirect_or_present_audit_report
|
||||
end
|
||||
|
|
@ -214,7 +216,8 @@ module API
|
|||
tags %w[npm_packages]
|
||||
end
|
||||
route_setting :authentication, job_token_allowed: true, deploy_token_allowed: true
|
||||
route_setting :authorization, job_token_policies: :read_packages
|
||||
route_setting :authorization, job_token_policies: :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry
|
||||
post '-/npm/v1/security/audits/quick' do
|
||||
redirect_or_present_audit_report
|
||||
end
|
||||
|
|
|
|||
|
|
@ -59,7 +59,8 @@ module API
|
|||
end
|
||||
route_setting :authentication, job_token_allowed: true, deploy_token_allowed: true,
|
||||
authenticate_non_public: true
|
||||
route_setting :authorization, job_token_policies: :read_packages
|
||||
route_setting :authorization, job_token_policies: :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry
|
||||
get '*package_name', format: false, requirements: ::API::Helpers::Packages::Npm::NPM_ENDPOINT_REQUIREMENTS do
|
||||
package_name = declared_params[:package_name]
|
||||
packages =
|
||||
|
|
|
|||
|
|
@ -69,7 +69,8 @@ module API
|
|||
end
|
||||
|
||||
route_setting :authentication, job_token_allowed: true
|
||||
route_setting :authorization, job_token_policies: :read_deployments
|
||||
route_setting :authorization, job_token_policies: :read_deployments,
|
||||
allow_public_access_for_enabled_project_features: [:repository, :builds, :environments]
|
||||
get ':id/deployments' do
|
||||
authorize! :read_deployment, user_project
|
||||
|
||||
|
|
@ -95,7 +96,8 @@ module API
|
|||
requires :deployment_id, type: Integer, desc: 'The ID of the deployment'
|
||||
end
|
||||
route_setting :authentication, job_token_allowed: true
|
||||
route_setting :authorization, job_token_policies: :read_deployments
|
||||
route_setting :authorization, job_token_policies: :read_deployments,
|
||||
allow_public_access_for_enabled_project_features: [:repository, :builds, :environments]
|
||||
get ':id/deployments/:deployment_id' do
|
||||
authorize! :read_deployment, user_project
|
||||
|
||||
|
|
@ -251,7 +253,8 @@ module API
|
|||
use :merge_requests_base_params
|
||||
end
|
||||
route_setting :authentication, job_token_allowed: true
|
||||
route_setting :authorization, job_token_policies: :read_deployments
|
||||
route_setting :authorization, job_token_policies: :read_deployments,
|
||||
allow_public_access_for_enabled_project_features: [:repository, :builds, :environments]
|
||||
get ':id/deployments/:deployment_id/merge_requests' do
|
||||
authorize! :read_deployment, user_project
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,8 @@ module API
|
|||
mutually_exclusive :name, :search, message: 'cannot be used together'
|
||||
end
|
||||
route_setting :authentication, job_token_allowed: true
|
||||
route_setting :authorization, job_token_policies: :read_environments
|
||||
route_setting :authorization, job_token_policies: :read_environments,
|
||||
allow_public_access_for_enabled_project_features: [:repository, :builds, :environments]
|
||||
get ':id/environments' do
|
||||
authorize! :read_environment, user_project
|
||||
|
||||
|
|
@ -271,7 +272,8 @@ module API
|
|||
requires :environment_id, type: Integer, desc: 'The ID of the environment'
|
||||
end
|
||||
route_setting :authentication, job_token_allowed: true
|
||||
route_setting :authorization, job_token_policies: :read_environments
|
||||
route_setting :authorization, job_token_policies: :read_environments,
|
||||
allow_public_access_for_enabled_project_features: [:repository, :builds, :environments]
|
||||
get ':id/environments/:environment_id' do
|
||||
authorize! :read_environment, user_project
|
||||
|
||||
|
|
|
|||
|
|
@ -128,7 +128,8 @@ module API
|
|||
end
|
||||
|
||||
route_setting :authentication, job_token_allowed: %i[request basic_auth], basic_auth_personal_access_token: true, deploy_token_allowed: true
|
||||
route_setting :authorization, job_token_policies: :read_packages
|
||||
route_setting :authorization, job_token_policies: :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry
|
||||
|
||||
get do
|
||||
project = authorized_user_project(action: :read_package)
|
||||
|
|
|
|||
|
|
@ -69,7 +69,8 @@ module API
|
|||
end
|
||||
route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true,
|
||||
authenticate_non_public: true
|
||||
route_setting :authorization, job_token_policies: :read_packages
|
||||
route_setting :authorization, job_token_policies: :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry
|
||||
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
|
||||
before do
|
||||
authorize_read_package!(project)
|
||||
|
|
|
|||
|
|
@ -1038,6 +1038,7 @@ module API
|
|||
return true unless current_user&.from_ci_job_token?
|
||||
return true unless Feature.enabled?(:add_policies_to_ci_job_token, project)
|
||||
return true if skip_job_token_policies?
|
||||
return true if publicly_accessible_feature?(project)
|
||||
|
||||
current_user.ci_job_token_scope.policies_allowed?(project, job_token_policies)
|
||||
end
|
||||
|
|
@ -1069,6 +1070,19 @@ module API
|
|||
|
||||
route_setting(:authorization).try(:fetch, :skip_job_token_policies, false)
|
||||
end
|
||||
|
||||
def publicly_accessible_feature?(project)
|
||||
return false unless respond_to?(:route_setting)
|
||||
return false unless project.public? || project.internal?
|
||||
return false unless project&.project_feature
|
||||
|
||||
project_features = Array(route_setting(:authorization).try(:fetch, :allow_public_access_for_enabled_project_features, nil))
|
||||
return false if project_features.empty?
|
||||
|
||||
project_features.all? do |project_feature|
|
||||
project.project_feature.access_level(project_feature) >= ProjectFeature::ENABLED
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -102,7 +102,8 @@ module API
|
|||
use :path_and_file_name
|
||||
end
|
||||
route_setting :authentication, job_token_allowed: true, deploy_token_allowed: true, basic_auth_personal_access_token: true
|
||||
route_setting :authorization, job_token_policies: :read_packages
|
||||
route_setting :authorization, job_token_policies: :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry
|
||||
get 'packages/maven/*path/:file_name', requirements: MAVEN_ENDPOINT_REQUIREMENTS do
|
||||
# return a similar failure to authorize_read_package!(project)
|
||||
|
||||
|
|
@ -158,7 +159,8 @@ module API
|
|||
use :path_and_file_name
|
||||
end
|
||||
route_setting :authentication, job_token_allowed: true, deploy_token_allowed: true, basic_auth_personal_access_token: true
|
||||
route_setting :authorization, job_token_policies: :read_packages
|
||||
route_setting :authorization, job_token_policies: :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry
|
||||
get ':id/-/packages/maven/*path/:file_name', requirements: MAVEN_ENDPOINT_REQUIREMENTS do
|
||||
# return a similar failure to group = find_group(params[:id])
|
||||
group = find_authorized_group!(action: :read_package_within_public_registries)
|
||||
|
|
@ -200,7 +202,8 @@ module API
|
|||
use :path_and_file_name
|
||||
end
|
||||
route_setting :authentication, job_token_allowed: true, deploy_token_allowed: true, basic_auth_personal_access_token: true
|
||||
route_setting :authorization, job_token_policies: :read_packages
|
||||
route_setting :authorization, job_token_policies: :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry
|
||||
get ':id/packages/maven/*path/:file_name', requirements: MAVEN_ENDPOINT_REQUIREMENTS do
|
||||
project = authorized_user_project(action: :read_package)
|
||||
|
||||
|
|
|
|||
|
|
@ -61,7 +61,8 @@ module API
|
|||
requires :file_name, type: String, desc: 'Package file name'
|
||||
end
|
||||
route_setting :authentication, job_token_allowed: true, deploy_token_allowed: true
|
||||
route_setting :authorization, job_token_policies: :read_packages
|
||||
route_setting :authorization, job_token_policies: :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry
|
||||
get '*package_name/-/*file_name', format: false do
|
||||
authorize_read_package!(project)
|
||||
|
||||
|
|
@ -141,7 +142,8 @@ module API
|
|||
end
|
||||
route_setting :authentication, job_token_allowed: true, deploy_token_allowed: true,
|
||||
authenticate_non_public: true
|
||||
route_setting :authorization, job_token_policies: :read_packages
|
||||
route_setting :authorization, job_token_policies: :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry
|
||||
get '*package_name', format: false, requirements: ::API::Helpers::Packages::Npm::NPM_ENDPOINT_REQUIREMENTS do
|
||||
package_name = declared_params[:package_name]
|
||||
packages = ::Packages::Npm::PackageFinder.new(project: project_or_nil, params: { package_name: package_name }).execute
|
||||
|
|
|
|||
|
|
@ -31,7 +31,8 @@ module API
|
|||
use :pagination
|
||||
end
|
||||
route_setting :authentication, job_token_allowed: true
|
||||
route_setting :authorization, job_token_policies: :read_packages
|
||||
route_setting :authorization, job_token_policies: :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry
|
||||
get ':id/packages/:package_id/package_files' do
|
||||
package = ::Packages::PackageFinder
|
||||
.new(user_project, params[:package_id]).execute
|
||||
|
|
|
|||
|
|
@ -54,7 +54,8 @@ module API
|
|||
desc: 'Return packages with specified status'
|
||||
end
|
||||
route_setting :authentication, job_token_allowed: true
|
||||
route_setting :authorization, job_token_policies: :read_packages
|
||||
route_setting :authorization, job_token_policies: :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry
|
||||
get ':id/packages' do
|
||||
packages = ::Packages::PackagesFinder.new(
|
||||
user_project,
|
||||
|
|
@ -77,7 +78,8 @@ module API
|
|||
requires :package_id, type: Integer, desc: 'The ID of a package'
|
||||
end
|
||||
route_setting :authentication, job_token_allowed: true
|
||||
route_setting :authorization, job_token_policies: :read_packages
|
||||
route_setting :authorization, job_token_policies: :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry
|
||||
get ':id/packages/:package_id' do
|
||||
render_api_error!('Package not found', 404) unless package.detailed_info?
|
||||
|
||||
|
|
@ -104,7 +106,8 @@ module API
|
|||
values: 1..20
|
||||
end
|
||||
route_setting :authentication, job_token_allowed: true
|
||||
route_setting :authorization, job_token_policies: :read_packages
|
||||
route_setting :authorization, job_token_policies: :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry
|
||||
get ':id/packages/:package_id/pipelines' do
|
||||
not_found!('Package not found') unless package.detailed_info?
|
||||
|
||||
|
|
|
|||
|
|
@ -131,7 +131,8 @@ module API
|
|||
end
|
||||
|
||||
route_setting :authentication, deploy_token_allowed: true, basic_auth_personal_access_token: true, job_token_allowed: :basic_auth
|
||||
route_setting :authorization, job_token_policies: :read_packages
|
||||
route_setting :authorization, job_token_policies: :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry
|
||||
get 'files/:sha256/*file_identifier' do
|
||||
group = find_authorized_group!
|
||||
authorize_read_package!(group)
|
||||
|
|
@ -212,7 +213,8 @@ module API
|
|||
end
|
||||
|
||||
route_setting :authentication, deploy_token_allowed: true, basic_auth_personal_access_token: true, job_token_allowed: :basic_auth
|
||||
route_setting :authorization, job_token_policies: :read_packages
|
||||
route_setting :authorization, job_token_policies: :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry
|
||||
get 'files/:sha256/*file_identifier' do
|
||||
project = project!
|
||||
authorize_job_token_policies!(project)
|
||||
|
|
@ -240,7 +242,8 @@ module API
|
|||
# An API entry point but returns an HTML file instead of JSON.
|
||||
# PyPi simple API returns a list of packages as a simple HTML file.
|
||||
route_setting :authentication, deploy_token_allowed: true, basic_auth_personal_access_token: true, job_token_allowed: :basic_auth
|
||||
route_setting :authorization, job_token_policies: :read_packages
|
||||
route_setting :authorization, job_token_policies: :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry
|
||||
get 'simple', format: :txt do
|
||||
project = project!
|
||||
authorize_job_token_policies!(project)
|
||||
|
|
@ -265,7 +268,8 @@ module API
|
|||
# An API entry point but returns an HTML file instead of JSON.
|
||||
# PyPi simple API returns the package descriptor as a simple HTML file.
|
||||
route_setting :authentication, deploy_token_allowed: true, basic_auth_personal_access_token: true, job_token_allowed: :basic_auth
|
||||
route_setting :authorization, job_token_policies: :read_packages
|
||||
route_setting :authorization, job_token_policies: :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry
|
||||
get 'simple/*package_name', format: :txt do
|
||||
project = project!
|
||||
authorize_job_token_policies!(project)
|
||||
|
|
|
|||
|
|
@ -38,7 +38,8 @@ module API
|
|||
use :pagination
|
||||
end
|
||||
route_setting :authentication, job_token_allowed: true
|
||||
route_setting :authorization, job_token_policies: :read_releases
|
||||
route_setting :authorization, job_token_policies: :read_releases,
|
||||
allow_public_access_for_enabled_project_features: :releases
|
||||
get 'links' do
|
||||
authorize! :read_release, release
|
||||
|
||||
|
|
@ -95,7 +96,8 @@ module API
|
|||
tags release_links_tags
|
||||
end
|
||||
route_setting :authentication, job_token_allowed: true
|
||||
route_setting :authorization, job_token_policies: :read_releases
|
||||
route_setting :authorization, job_token_policies: :read_releases,
|
||||
allow_public_access_for_enabled_project_features: :releases
|
||||
get do
|
||||
authorize! :read_release, release
|
||||
|
||||
|
|
|
|||
|
|
@ -98,7 +98,8 @@ module API
|
|||
optional :updated_after, type: DateTime, desc: 'Return releases updated after the specified datetime. Format: ISO 8601 YYYY-MM-DDTHH:MM:SSZ'
|
||||
end
|
||||
route_setting :authentication, job_token_allowed: true
|
||||
route_setting :authorization, job_token_policies: :read_releases
|
||||
route_setting :authorization, job_token_policies: :read_releases,
|
||||
allow_public_access_for_enabled_project_features: [:repository, :releases]
|
||||
get ':id/releases' do
|
||||
releases = ::ReleasesFinder.new(user_project, current_user, declared_params.slice(:order_by, :sort, :updated_before, :updated_after)).execute
|
||||
|
||||
|
|
@ -134,7 +135,8 @@ module API
|
|||
desc: 'If `true`, a response includes HTML rendered markdown of the release description'
|
||||
end
|
||||
route_setting :authentication, job_token_allowed: true
|
||||
route_setting :authorization, job_token_policies: :read_releases
|
||||
route_setting :authorization, job_token_policies: :read_releases,
|
||||
allow_public_access_for_enabled_project_features: [:repository, :releases]
|
||||
get ':id/releases/:tag_name', requirements: RELEASE_ENDPOINT_REQUIREMENTS do
|
||||
authorize_read_code!
|
||||
|
||||
|
|
@ -162,7 +164,8 @@ module API
|
|||
as: :filepath
|
||||
end
|
||||
route_setting :authentication, job_token_allowed: true
|
||||
route_setting :authorization, job_token_policies: :read_releases
|
||||
route_setting :authorization, job_token_policies: :read_releases,
|
||||
allow_public_access_for_enabled_project_features: [:repository, :releases]
|
||||
get ':id/releases/:tag_name/downloads/*direct_asset_path', format: false, requirements: RELEASE_ENDPOINT_REQUIREMENTS do
|
||||
authorize_read_code!
|
||||
|
||||
|
|
@ -191,7 +194,8 @@ module API
|
|||
desc: 'The path to be suffixed to the latest release'
|
||||
end
|
||||
route_setting :authentication, job_token_allowed: true
|
||||
route_setting :authorization, job_token_policies: :read_releases
|
||||
route_setting :authorization, job_token_policies: :read_releases,
|
||||
allow_public_access_for_enabled_project_features: [:repository, :releases]
|
||||
get ':id/releases/permalink/latest(/)(*suffix_path)', format: false, requirements: RELEASE_ENDPOINT_REQUIREMENTS do
|
||||
authorize_read_code!
|
||||
|
||||
|
|
|
|||
|
|
@ -293,7 +293,8 @@ module API
|
|||
desc: "The file path to the configuration file as stored in the project's Git repository. Defaults to '.gitlab/changelog_config.yml'"
|
||||
end
|
||||
route_setting :authentication, job_token_allowed: true
|
||||
route_setting :authorization, job_token_policies: :read_releases
|
||||
route_setting :authorization, job_token_policies: :read_releases,
|
||||
allow_public_access_for_enabled_project_features: :repository
|
||||
get ':id/repository/changelog' do
|
||||
check_rate_limit!(:project_repositories_changelog, scope: [current_user, user_project]) do
|
||||
render_api_error!({ error: 'This changelog has been requested too many times. Try again later.' }, 429)
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@
|
|||
"@gitlab/fonts": "^1.3.0",
|
||||
"@gitlab/query-language-rust": "0.4.0",
|
||||
"@gitlab/svgs": "3.123.0",
|
||||
"@gitlab/ui": "108.3.1",
|
||||
"@gitlab/ui": "108.4.1",
|
||||
"@gitlab/vue-router-vue3": "npm:vue-router@4.5.0",
|
||||
"@gitlab/vuex-vue3": "npm:vuex@4.1.0",
|
||||
"@gitlab/web-ide": "^0.0.1-dev-20250211142744",
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ describe('PasswordInput', () => {
|
|||
expect(passwordInput.attributes('data-testid')).toBe(propsData.testid);
|
||||
expect(passwordInput.attributes('title')).toBe(propsData.title);
|
||||
expect(passwordInput.attributes('required')).toBe('true');
|
||||
expect(passwordInput.attributes('disabled')).toBeUndefined();
|
||||
});
|
||||
|
||||
describe('when password input is not required', () => {
|
||||
|
|
@ -73,4 +74,13 @@ describe('PasswordInput', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when password input is disabled', () => {
|
||||
it('disables the input field and the toggle button', () => {
|
||||
wrapper = createComponent({ disabled: true });
|
||||
|
||||
expect(findPasswordInput().attributes('disabled')).toBeDefined();
|
||||
expect(findToggleButton().attributes('disabled')).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -334,6 +334,16 @@ RSpec.describe API::Helpers, feature_category: :shared do
|
|||
|
||||
it { is_expected.to eq project }
|
||||
end
|
||||
|
||||
context 'when the project feature is publicly accessible' do
|
||||
let_it_be(:project) { create(:project, :public, :builds_enabled) }
|
||||
|
||||
before do
|
||||
allow(helper).to receive(:route_setting).with(:authorization).and_return(allow_public_access_for_enabled_project_features: :builds)
|
||||
end
|
||||
|
||||
it { is_expected.to eq project }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when no policy is given' do
|
||||
|
|
|
|||
|
|
@ -5112,79 +5112,7 @@ RSpec.describe Ci::Build, feature_category: :continuous_integration, factory_def
|
|||
build.clear_memoization(:build_data)
|
||||
end
|
||||
|
||||
context 'when ci_async_build_hooks_execution flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(ci_async_build_hooks_execution: false)
|
||||
end
|
||||
|
||||
context 'with project services' do
|
||||
before do
|
||||
create(:integration, active: true, job_events: true, project: project)
|
||||
end
|
||||
|
||||
it 'executes services' do
|
||||
allow_next_instance_of(Integration) do |integration|
|
||||
expect(integration).to receive(:async_execute)
|
||||
end
|
||||
|
||||
build.execute_hooks
|
||||
end
|
||||
end
|
||||
|
||||
context 'without relevant project services' do
|
||||
before do
|
||||
create(:integration, active: true, job_events: false, project: project)
|
||||
end
|
||||
|
||||
it 'does not execute services' do
|
||||
allow_next_instance_of(Integration) do |integration|
|
||||
expect(integration).not_to receive(:async_execute)
|
||||
end
|
||||
|
||||
build.execute_hooks
|
||||
end
|
||||
end
|
||||
|
||||
context 'with project hooks' do
|
||||
let(:build_data) { double(:BuildData, dup: double(:DupedData)) }
|
||||
|
||||
before do
|
||||
create(:project_hook, project: project, job_events: true)
|
||||
end
|
||||
|
||||
it 'executes hooks' do
|
||||
expect(::Gitlab::DataBuilder::Build)
|
||||
.to receive(:build).with(build).and_return(build_data)
|
||||
|
||||
expect(build.project)
|
||||
.to receive(:execute_hooks).with(build_data.dup, :job_hooks)
|
||||
|
||||
build.execute_hooks
|
||||
end
|
||||
|
||||
context 'with blocked users' do
|
||||
before do
|
||||
allow(build).to receive(:user) { FactoryBot.build(:user, :blocked) }
|
||||
end
|
||||
|
||||
it 'does not execute hooks' do
|
||||
expect(build.project).not_to receive(:execute_hooks)
|
||||
|
||||
build.execute_hooks
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'without project hooks' do
|
||||
it 'does not execute hooks' do
|
||||
expect(build.project).not_to receive(:execute_hooks)
|
||||
|
||||
build.execute_hooks
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when ci_async_build_hooks_execution flag is enabled' do
|
||||
context 'when project hooks exists' do
|
||||
let(:build_data) { double(:BuildData) }
|
||||
|
||||
before do
|
||||
|
|
|
|||
|
|
@ -35,6 +35,12 @@ RSpec.describe Integrations::Campfire, feature_category: :integrations do
|
|||
end
|
||||
end
|
||||
|
||||
describe '.help' do
|
||||
it 'links to the help page correctly' do
|
||||
expect(described_class.help).to include('help/api/integrations.md#campfire', 'Learn More')
|
||||
end
|
||||
end
|
||||
|
||||
describe "#execute" do
|
||||
let(:user) { build_stubbed(:user) }
|
||||
let(:project) { build_stubbed(:project, :repository) }
|
||||
|
|
|
|||
|
|
@ -152,11 +152,10 @@ RSpec.describe Integrations::Datadog, feature_category: :integrations do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#help' do
|
||||
subject { instance.help }
|
||||
|
||||
it { is_expected.to be_a(String) }
|
||||
it { is_expected.not_to be_empty }
|
||||
describe '.help' do
|
||||
it 'links to the help page correctly' do
|
||||
expect(described_class.help).to include('help/integration/datadog.md', 'How do I set up this integration?')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'upgrade from previous version' do
|
||||
|
|
|
|||
|
|
@ -506,10 +506,7 @@ RSpec.describe API::Ci::JobArtifacts, feature_category: :job_artifacts do
|
|||
it_behaves_like 'enforcing job token policies', :read_jobs do
|
||||
before do
|
||||
stub_licensed_features(cross_project_pipelines: true)
|
||||
end
|
||||
|
||||
around do |example|
|
||||
Sidekiq::Testing.inline! { example.run }
|
||||
pipeline.update!(status: :success)
|
||||
end
|
||||
|
||||
let(:request) do
|
||||
|
|
@ -701,6 +698,19 @@ RSpec.describe API::Ci::JobArtifacts, feature_category: :job_artifacts do
|
|||
expect(response.headers.to_h)
|
||||
.not_to include('Gitlab-Workhorse-Send-Data' => /artifacts-entry/)
|
||||
end
|
||||
|
||||
it_behaves_like 'enforcing job token policies', :read_jobs,
|
||||
allow_public_access_for_enabled_project_features: [:repository, :builds] do
|
||||
before do
|
||||
stub_licensed_features(cross_project_pipelines: true)
|
||||
pipeline.update!(status: :success)
|
||||
end
|
||||
|
||||
let(:request) do
|
||||
get api("/projects/#{source_project.id}/jobs/artifacts/#{pipeline.ref}/raw/#{artifact}"),
|
||||
params: { job: job.name, job_token: target_job.token }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1082,7 +1082,8 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state, feature_catego
|
|||
expect(response).to have_gitlab_http_status(:forbidden)
|
||||
end
|
||||
|
||||
it_behaves_like 'enforcing job token policies', :read_jobs do
|
||||
it_behaves_like 'enforcing job token policies', :read_jobs,
|
||||
allow_public_access_for_enabled_project_features: [:repository, :builds] do
|
||||
let(:token) { target_job.token }
|
||||
let(:request) { download_artifact }
|
||||
end
|
||||
|
|
|
|||
|
|
@ -595,7 +595,8 @@ RSpec.describe API::ComposerPackages, feature_category: :package_registry do
|
|||
let(:branch) { project.repository.find_branch('master') }
|
||||
let(:sha) { branch.target }
|
||||
|
||||
it_behaves_like 'enforcing job token policies', :read_packages do
|
||||
it_behaves_like 'enforcing job token policies', :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry do
|
||||
before_all do
|
||||
project.add_developer(user)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -43,6 +43,11 @@ RSpec.describe API::Conan::V2::ProjectPackages, feature_category: :package_regis
|
|||
it_behaves_like 'accept get request on private project with access to package registry for everyone'
|
||||
it_behaves_like 'project not found by project id'
|
||||
|
||||
it_behaves_like 'enforcing job token policies', :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry do
|
||||
let(:headers) { job_basic_auth_header(target_job) }
|
||||
end
|
||||
|
||||
context 'when feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(conan_package_revisions_support: false)
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@ RSpec.describe API::Deployments, feature_category: :continuous_delivery do
|
|||
get api("/projects/#{project.id}/deployments", user), params: params
|
||||
end
|
||||
|
||||
it_behaves_like 'enforcing job token policies', :read_deployments do
|
||||
it_behaves_like 'enforcing job token policies', :read_deployments,
|
||||
allow_public_access_for_enabled_project_features: [:repository, :builds, :environments] do
|
||||
let(:request) do
|
||||
get api("/projects/#{source_project.id}/deployments"), params: { job_token: target_job.token }
|
||||
end
|
||||
|
|
@ -174,7 +175,8 @@ RSpec.describe API::Deployments, feature_category: :continuous_delivery do
|
|||
shared_examples "returns project deployments" do
|
||||
let(:project) { deployment.environment.project }
|
||||
|
||||
it_behaves_like 'enforcing job token policies', :read_deployments do
|
||||
it_behaves_like 'enforcing job token policies', :read_deployments,
|
||||
allow_public_access_for_enabled_project_features: [:repository, :builds, :environments] do
|
||||
let(:request) do
|
||||
get api("/projects/#{source_project.id}/deployments/#{deployment.id}"),
|
||||
params: { job_token: target_job.token }
|
||||
|
|
@ -670,7 +672,8 @@ RSpec.describe API::Deployments, feature_category: :continuous_delivery do
|
|||
|
||||
subject { get api("/projects/#{project.id}/deployments/#{deployment.id}/merge_requests", user) }
|
||||
|
||||
it_behaves_like 'enforcing job token policies', :read_deployments do
|
||||
it_behaves_like 'enforcing job token policies', :read_deployments,
|
||||
allow_public_access_for_enabled_project_features: [:repository, :builds, :environments] do
|
||||
let(:request) do
|
||||
get api("/projects/#{source_project.id}/deployments/#{deployment.id}/merge_requests"), params: { job_token: target_job.token }
|
||||
end
|
||||
|
|
|
|||
|
|
@ -124,7 +124,8 @@ RSpec.describe API::Environments, feature_category: :continuous_delivery do
|
|||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'enforcing job token policies', :read_environments do
|
||||
it_behaves_like 'enforcing job token policies', :read_environments,
|
||||
allow_public_access_for_enabled_project_features: [:repository, :builds, :environments] do
|
||||
let(:request) do
|
||||
get api("/projects/#{source_project.id}/environments"), params: { job_token: target_job.token }
|
||||
end
|
||||
|
|
@ -646,7 +647,8 @@ RSpec.describe API::Environments, feature_category: :continuous_delivery do
|
|||
let_it_be(:bridge_job) { create(:ci_bridge, :running, project: project, user: user) }
|
||||
let_it_be(:build_job) { create(:ci_build, :running, project: project, user: user) }
|
||||
|
||||
it_behaves_like 'enforcing job token policies', :read_environments do
|
||||
it_behaves_like 'enforcing job token policies', :read_environments,
|
||||
allow_public_access_for_enabled_project_features: [:repository, :builds, :environments] do
|
||||
let(:request) do
|
||||
get api("/projects/#{source_project.id}/environments/#{environment.id}"),
|
||||
params: { job_token: target_job.token }
|
||||
|
|
|
|||
|
|
@ -691,7 +691,8 @@ RSpec.describe API::GenericPackages, feature_category: :package_registry do
|
|||
let_it_be(:package) { create(:generic_package, project: project) }
|
||||
let_it_be(:package_file) { create(:package_file, :generic, package: package) }
|
||||
|
||||
it_behaves_like 'enforcing job token policies', :read_packages do
|
||||
it_behaves_like 'enforcing job token policies', :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry do
|
||||
before do
|
||||
source_project.add_developer(user)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -190,7 +190,8 @@ RSpec.describe API::GoProxy, feature_category: :package_registry do
|
|||
it_behaves_like 'a missing module version list resource'
|
||||
end
|
||||
|
||||
it_behaves_like 'enforcing job token policies', :read_packages do
|
||||
it_behaves_like 'enforcing job token policies', :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry do
|
||||
let(:module_name) { base }
|
||||
let(:resource) { 'list' }
|
||||
let(:request) { get_resource(job_token: target_job.token) }
|
||||
|
|
@ -250,7 +251,8 @@ RSpec.describe API::GoProxy, feature_category: :package_registry do
|
|||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'enforcing job token policies', :read_packages do
|
||||
it_behaves_like 'enforcing job token policies', :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry do
|
||||
let(:module_name) { base }
|
||||
let(:resource) { 'v1.0.1.info' }
|
||||
let(:request) { get_resource(job_token: target_job.token) }
|
||||
|
|
@ -278,7 +280,8 @@ RSpec.describe API::GoProxy, feature_category: :package_registry do
|
|||
it_behaves_like 'a missing module file resource', 'v1.0.1', path: '/mod'
|
||||
end
|
||||
|
||||
it_behaves_like 'enforcing job token policies', :read_packages do
|
||||
it_behaves_like 'enforcing job token policies', :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry do
|
||||
let(:module_name) { base }
|
||||
let(:resource) { 'v1.0.1.mod' }
|
||||
let(:request) { get_resource(job_token: target_job.token) }
|
||||
|
|
@ -306,7 +309,8 @@ RSpec.describe API::GoProxy, feature_category: :package_registry do
|
|||
it_behaves_like 'a module archive resource', 'v2.0.0', ['go.mod', 'a.go', 'x.go'], path: '/v2'
|
||||
end
|
||||
|
||||
it_behaves_like 'enforcing job token policies', :read_packages do
|
||||
it_behaves_like 'enforcing job token policies', :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry do
|
||||
let(:module_name) { base }
|
||||
let(:resource) { 'v1.0.1.zip' }
|
||||
let(:request) { get_resource(job_token: target_job.token) }
|
||||
|
|
|
|||
|
|
@ -475,7 +475,8 @@ RSpec.describe API::MavenPackages, feature_category: :package_registry do
|
|||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'enforcing job token policies', :read_packages do
|
||||
it_behaves_like 'enforcing job token policies', :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry do
|
||||
before_all do
|
||||
project.add_maintainer(user)
|
||||
end
|
||||
|
|
@ -649,7 +650,8 @@ RSpec.describe API::MavenPackages, feature_category: :package_registry do
|
|||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'enforcing job token policies', :read_packages do
|
||||
it_behaves_like 'enforcing job token policies', :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry do
|
||||
let(:request) do
|
||||
download_file(file_name: package_file.file_name, params: { job_token: target_job.token })
|
||||
end
|
||||
|
|
@ -842,7 +844,8 @@ RSpec.describe API::MavenPackages, feature_category: :package_registry do
|
|||
|
||||
subject { download_file_with_token(file_name: package_file.file_name) }
|
||||
|
||||
it_behaves_like 'enforcing job token policies', :read_packages do
|
||||
it_behaves_like 'enforcing job token policies', :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry do
|
||||
let(:request) do
|
||||
download_file(file_name: package_file.file_name, params: { job_token: target_job.token })
|
||||
end
|
||||
|
|
|
|||
|
|
@ -203,7 +203,8 @@ RSpec.describe API::NpmProjectPackages, feature_category: :package_registry do
|
|||
project.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
|
||||
end
|
||||
|
||||
it_behaves_like 'enforcing job token policies', :read_packages do
|
||||
it_behaves_like 'enforcing job token policies', :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry do
|
||||
let(:headers) { build_token_auth_header(target_job.token) }
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@ RSpec.describe API::PackageFiles, feature_category: :package_registry do
|
|||
project.add_developer(user)
|
||||
end
|
||||
|
||||
it_behaves_like 'enforcing job token policies', :read_packages do
|
||||
it_behaves_like 'enforcing job token policies', :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry do
|
||||
let(:request) { get api(url), params: { job_token: target_job.token } }
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@ RSpec.describe API::ProjectPackages, feature_category: :package_registry do
|
|||
|
||||
subject(:request) { get api(url), params: params }
|
||||
|
||||
it_behaves_like 'enforcing job token policies', :read_packages do
|
||||
it_behaves_like 'enforcing job token policies', :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry do
|
||||
let(:params) { { job_token: target_job.token } }
|
||||
end
|
||||
|
||||
|
|
@ -231,7 +232,8 @@ RSpec.describe API::ProjectPackages, feature_category: :package_registry do
|
|||
|
||||
subject { get api(package_url, user) }
|
||||
|
||||
it_behaves_like 'enforcing job token policies', :read_packages do
|
||||
it_behaves_like 'enforcing job token policies', :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry do
|
||||
let(:request) { get api(package_url), params: { job_token: target_job.token } }
|
||||
end
|
||||
|
||||
|
|
@ -421,7 +423,8 @@ RSpec.describe API::ProjectPackages, feature_category: :package_registry do
|
|||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'enforcing job token policies', :read_packages do
|
||||
it_behaves_like 'enforcing job token policies', :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry do
|
||||
let(:request) { get api(package_pipelines_url), params: { job_token: target_job.token } }
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@ RSpec.describe API::Release::Links, feature_category: :release_orchestration do
|
|||
end
|
||||
|
||||
describe 'GET /projects/:id/releases/:tag_name/assets/links' do
|
||||
it_behaves_like 'enforcing job token policies', :read_releases do
|
||||
it_behaves_like 'enforcing job token policies', :read_releases,
|
||||
allow_public_access_for_enabled_project_features: :releases do
|
||||
let_it_be(:user) { maintainer }
|
||||
let(:request) do
|
||||
get api("/projects/#{source_project.id}/releases/v0.1/assets/links"),
|
||||
|
|
@ -114,7 +115,8 @@ RSpec.describe API::Release::Links, feature_category: :release_orchestration do
|
|||
describe 'GET /projects/:id/releases/:tag_name/assets/links/:link_id' do
|
||||
let!(:release_link) { create(:release_link, release: release) }
|
||||
|
||||
it_behaves_like 'enforcing job token policies', :read_releases do
|
||||
it_behaves_like 'enforcing job token policies', :read_releases,
|
||||
allow_public_access_for_enabled_project_features: :releases do
|
||||
let_it_be(:user) { maintainer }
|
||||
let(:request) do
|
||||
get api("/projects/#{source_project.id}/releases/v0.1/assets/links/#{release_link.id}"),
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@ RSpec.describe API::Releases, :aggregate_failures, feature_category: :release_or
|
|||
end
|
||||
|
||||
describe 'GET /projects/:id/releases', :use_clean_rails_redis_caching do
|
||||
it_behaves_like 'enforcing job token policies', :read_releases do
|
||||
it_behaves_like 'enforcing job token policies', :read_releases,
|
||||
allow_public_access_for_enabled_project_features: [:repository, :releases] do
|
||||
let(:user) { developer }
|
||||
let(:request) do
|
||||
get api("/projects/#{source_project.id}/releases"), params: { job_token: target_job.token }
|
||||
|
|
@ -326,7 +327,8 @@ RSpec.describe API::Releases, :aggregate_failures, feature_category: :release_or
|
|||
)
|
||||
end
|
||||
|
||||
it_behaves_like 'enforcing job token policies', :read_releases do
|
||||
it_behaves_like 'enforcing job token policies', :read_releases,
|
||||
allow_public_access_for_enabled_project_features: [:repository, :releases] do
|
||||
let(:user) { developer }
|
||||
let(:request) do
|
||||
get api("/projects/#{source_project.id}/releases/v0.1"), params: { job_token: target_job.token }
|
||||
|
|
@ -595,7 +597,8 @@ RSpec.describe API::Releases, :aggregate_failures, feature_category: :release_or
|
|||
context 'with a valid release tag' do
|
||||
context 'when filepath is provided' do
|
||||
context 'when filepath exists' do
|
||||
it_behaves_like 'enforcing job token policies', :read_releases, expected_success_status: :redirect do
|
||||
it_behaves_like 'enforcing job token policies', :read_releases, expected_success_status: :redirect,
|
||||
allow_public_access_for_enabled_project_features: [:repository, :releases] do
|
||||
let(:user) { developer }
|
||||
let(:request) do
|
||||
get api("/projects/#{source_project.id}/releases/v0.1/downloads#{filepath}"),
|
||||
|
|
@ -731,7 +734,8 @@ RSpec.describe API::Releases, :aggregate_failures, feature_category: :release_or
|
|||
)
|
||||
end
|
||||
|
||||
it_behaves_like 'enforcing job token policies', :read_releases, expected_success_status: :redirect do
|
||||
it_behaves_like 'enforcing job token policies', :read_releases, expected_success_status: :redirect,
|
||||
allow_public_access_for_enabled_project_features: [:repository, :releases] do
|
||||
let(:user) { developer }
|
||||
let(:request) do
|
||||
get api("/projects/#{source_project.id}/releases/permalink/latest"), params: { job_token: target_job.token }
|
||||
|
|
|
|||
|
|
@ -855,7 +855,8 @@ RSpec.describe API::Repositories, feature_category: :source_code_management do
|
|||
end
|
||||
|
||||
describe 'GET /projects/:id/repository/changelog' do
|
||||
it_behaves_like 'enforcing job token policies', :read_releases do
|
||||
it_behaves_like 'enforcing job token policies', :read_releases,
|
||||
allow_public_access_for_enabled_project_features: :repository do
|
||||
before do
|
||||
allow(Repositories::ChangelogService).to receive(:new)
|
||||
.and_return(instance_spy(Repositories::ChangelogService))
|
||||
|
|
|
|||
|
|
@ -1,13 +1,23 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.shared_examples 'enforcing job token policies' do |policies, expected_success_status: :success|
|
||||
RSpec.shared_examples 'enforcing job token policies' do |policies, expected_success_status: :success,
|
||||
allow_public_access_for_enabled_project_features: nil|
|
||||
|
||||
context 'when authenticating with a CI job token from another project' do
|
||||
let(:source_project) { project }
|
||||
let(:target_job) { create(:ci_build, :running, user: user) }
|
||||
let(:job_user) { user }
|
||||
let(:target_job) { create(:ci_build, :running, user: job_user) }
|
||||
let(:allowed_policies) { Array(policies) }
|
||||
let(:default_permissions) { false }
|
||||
let!(:features_state) do
|
||||
source_project.project_feature.attributes
|
||||
.slice(*::ProjectFeature::FEATURES.map { |feature| "#{feature}_access_level" })
|
||||
end
|
||||
|
||||
before do
|
||||
# Make all project features private
|
||||
enable_project_features(source_project, nil)
|
||||
|
||||
create(:ci_job_token_project_scope_link,
|
||||
source_project: source_project,
|
||||
target_project: target_job.project,
|
||||
|
|
@ -17,6 +27,11 @@ RSpec.shared_examples 'enforcing job token policies' do |policies, expected_succ
|
|||
)
|
||||
end
|
||||
|
||||
after do
|
||||
# Reinstate the initial project features
|
||||
source_project.project_feature.update!(features_state)
|
||||
end
|
||||
|
||||
subject(:do_request) do
|
||||
request
|
||||
response
|
||||
|
|
@ -58,5 +73,59 @@ RSpec.shared_examples 'enforcing job token policies' do |policies, expected_succ
|
|||
it { is_expected.to have_gitlab_http_status(expected_success_status) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the source project is public and the target job user is not a member of the source project' do
|
||||
let(:visibility_level) { source_project.visibility_level }
|
||||
let(:job_user) { create(:user) }
|
||||
|
||||
before do
|
||||
if visibility_level != ::Gitlab::VisibilityLevel::PUBLIC
|
||||
source_project.update!(visibility_level: ::Gitlab::VisibilityLevel::PUBLIC)
|
||||
end
|
||||
end
|
||||
|
||||
after do
|
||||
if visibility_level != ::Gitlab::VisibilityLevel::PUBLIC
|
||||
source_project.update!(visibility_level: visibility_level)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when policies are not allowed, but the specified project features allow public access',
|
||||
if: allow_public_access_for_enabled_project_features.present? do
|
||||
let(:allowed_policies) { [] }
|
||||
|
||||
context 'when all project features are private' do
|
||||
it { is_expected.to have_gitlab_http_status(:forbidden) }
|
||||
end
|
||||
|
||||
context 'when the specified project features are public' do
|
||||
before do
|
||||
enable_project_features(source_project, allow_public_access_for_enabled_project_features)
|
||||
end
|
||||
|
||||
it { is_expected.to have_gitlab_http_status(expected_success_status) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when policies are allowed and all project features are public',
|
||||
unless: allow_public_access_for_enabled_project_features.present? do
|
||||
before do
|
||||
enable_project_features(source_project, ::ProjectFeature::FEATURES)
|
||||
end
|
||||
|
||||
it 'denies access' do
|
||||
expect(do_request).to have_gitlab_http_status(:forbidden)
|
||||
.or have_gitlab_http_status(:unauthorized)
|
||||
.or have_gitlab_http_status(:bad_request)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def enable_project_features(project, project_features)
|
||||
attrs = ::ProjectFeature::FEATURES.index_with(::ProjectFeature::PRIVATE)
|
||||
attrs.merge!(Array(project_features).index_with(::ProjectFeature::ENABLED)) if project_features.present?
|
||||
attrs.transform_keys! { |feature| "#{feature}_access_level" }
|
||||
project.project_feature.update!(attrs)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -40,6 +40,15 @@ RSpec.shared_examples Integrations::Base::Discord do
|
|||
end
|
||||
end
|
||||
|
||||
describe '.help' do
|
||||
it 'links to help page correctly' do
|
||||
expect(described_class.help).to include(
|
||||
'user/project/integrations/discord_notifications.md',
|
||||
'How do I set up this integration?'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#execute' do
|
||||
include StubRequests
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,15 @@ RSpec.shared_examples Integrations::Base::HangoutsChat do
|
|||
let(:webhook_url_regex) { /\A#{webhook_url}.*/ }
|
||||
let(:query_params) { { messageReplyOption: Integrations::HangoutsChat::REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD } }
|
||||
|
||||
describe '.help' do
|
||||
it 'links to help page correctly' do
|
||||
expect(described_class.help).to include(
|
||||
'user/project/integrations/hangouts_chat.md',
|
||||
'How do I set up a Google Chat webhook?'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#execute" do
|
||||
let_it_be(:user) { create(:user) }
|
||||
let_it_be(:project) { create(:project, :repository, :wiki_repo) }
|
||||
|
|
|
|||
|
|
@ -23,6 +23,15 @@ RSpec.shared_examples Integrations::Base::Irker do
|
|||
end
|
||||
end
|
||||
|
||||
describe '.help' do
|
||||
it 'links to help page correctly' do
|
||||
expect(described_class.help).to include(
|
||||
'help/user/project/integrations/irker.md#set-up-an-irker-daemon',
|
||||
'Learn More'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Execute' do
|
||||
let_it_be(:user) { create(:user) }
|
||||
let_it_be(:project) { create(:project, :repository) }
|
||||
|
|
|
|||
|
|
@ -131,7 +131,8 @@ RSpec.shared_examples 'handling get metadata requests' do |scope: :project|
|
|||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'enforcing job token policies', :read_packages do
|
||||
it_behaves_like 'enforcing job token policies', :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry do
|
||||
let(:headers) { build_token_auth_header(target_job.token) }
|
||||
end
|
||||
|
||||
|
|
@ -346,7 +347,8 @@ RSpec.shared_examples 'handling audit request' do |path:, scope: :project|
|
|||
it_behaves_like 'accept audit request', status: :ok
|
||||
end
|
||||
|
||||
it_behaves_like 'enforcing job token policies', :read_packages do
|
||||
it_behaves_like 'enforcing job token policies', :read_packages,
|
||||
allow_public_access_for_enabled_project_features: scope == :project ? :package_registry : nil do
|
||||
before_all do
|
||||
project.add_reporter(user)
|
||||
end
|
||||
|
|
@ -491,7 +493,8 @@ RSpec.shared_examples 'handling get dist tags requests' do |scope: :project|
|
|||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'enforcing job token policies', :read_packages do
|
||||
it_behaves_like 'enforcing job token policies', :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry do
|
||||
let(:headers) { build_token_auth_header(target_job.token) }
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -101,7 +101,8 @@ RSpec.shared_examples 'job token for package GET requests' do
|
|||
end
|
||||
|
||||
RSpec.shared_examples 'enforcing read_packages job token policy' do
|
||||
it_behaves_like 'enforcing job token policies', :read_packages do
|
||||
it_behaves_like 'enforcing job token policies', :read_packages,
|
||||
allow_public_access_for_enabled_project_features: :package_registry do
|
||||
let(:headers) { job_basic_auth_header(target_job) }
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -24,6 +24,73 @@ RSpec.describe Ci::ExecuteBuildHooksWorker, feature_category: :pipeline_composit
|
|||
describe '#perform' do
|
||||
subject(:perform) { described_class.new.perform(project.id, build_data) }
|
||||
|
||||
context 'when build_data has string keys' do
|
||||
let(:string_build_data) do
|
||||
{
|
||||
'object_kind' => 'build',
|
||||
'ref' => 'main',
|
||||
'build_id' => build.id,
|
||||
'build_name' => build.name,
|
||||
'build_stage' => build.stage_name,
|
||||
'build_status' => build.status,
|
||||
'project_id' => project.id,
|
||||
'project_name' => project.full_name
|
||||
}
|
||||
end
|
||||
|
||||
it 'converts data to indifferent access' do
|
||||
allow_next_instance_of(Project) do |project|
|
||||
expect(project).to receive(:execute_hooks).with(
|
||||
kind_of(ActiveSupport::HashWithIndifferentAccess),
|
||||
:job_hooks
|
||||
)
|
||||
end
|
||||
|
||||
described_class.new.perform(project.id, string_build_data)
|
||||
end
|
||||
|
||||
it 'allows both string and symbol access to build data' do
|
||||
allow_next_instance_of(Project) do |project|
|
||||
allow(project).to receive(:has_active_hooks?).and_return(true)
|
||||
expect(project).to receive(:execute_hooks) do |data, _hook_type|
|
||||
expect(data[:object_kind]).to eq('build')
|
||||
expect(data['object_kind']).to eq('build')
|
||||
expect(data[:build_name]).to eq(build.name)
|
||||
expect(data['build_name']).to eq(build.name)
|
||||
end
|
||||
end
|
||||
|
||||
described_class.new.perform(project.id, string_build_data)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when build_data has symbol keys' do
|
||||
it 'converts data to indifferent access' do
|
||||
allow_next_instance_of(Project) do |project|
|
||||
expect(project).to receive(:execute_hooks).with(
|
||||
kind_of(ActiveSupport::HashWithIndifferentAccess),
|
||||
:job_hooks
|
||||
)
|
||||
end
|
||||
|
||||
perform
|
||||
end
|
||||
|
||||
it 'allows both string and symbol access to build data' do
|
||||
allow_next_instance_of(Project) do |project|
|
||||
allow(project).to receive(:has_active_hooks?).and_return(true)
|
||||
expect(project).to receive(:execute_hooks) do |data, _hook_type|
|
||||
expect(data[:object_kind]).to eq('build')
|
||||
expect(data['object_kind']).to eq('build')
|
||||
expect(data[:build_name]).to eq(build.name)
|
||||
expect(data['build_name']).to eq(build.name)
|
||||
end
|
||||
end
|
||||
|
||||
perform
|
||||
end
|
||||
end
|
||||
|
||||
context 'when project exists' do
|
||||
context 'with project services' do
|
||||
let!(:integration) { create(:integration, active: true, job_events: true, project: project) }
|
||||
|
|
|
|||
|
|
@ -1436,10 +1436,10 @@
|
|||
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-3.123.0.tgz#1fa3b1a709755ff7c8ef67e18c0442101655ebf0"
|
||||
integrity sha512-yjVn+utOTIKk8d9JlvGo6EgJ4TQ+CKpe3RddflAqtsQqQuL/2MlVdtaUePybxYzWIaumFuh5LouQ6BrWyw1niQ==
|
||||
|
||||
"@gitlab/ui@108.3.1":
|
||||
version "108.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-108.3.1.tgz#eb1db6c1ddc0ad7a239e6bcf21624fd1bc54b27b"
|
||||
integrity sha512-O4haNCEJl3nHK8DB1mi01YRJOZomNXI0sBA600BLrbptm/NAO9oVE7O/U8sFEdXM7EtFHYwRYcF/LrWwfJmE9g==
|
||||
"@gitlab/ui@108.4.1":
|
||||
version "108.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-108.4.1.tgz#d45dbcc3a9f568694f53eebb795544157ddbf44f"
|
||||
integrity sha512-o3mcR/AQ5tkKd3mMClMvsJIHhLWzU6n1L0m3bp4Yr4zaNtRG3c8gEGF7MR6pMhlnyb5r/FQk2wigxHaUuOSblQ==
|
||||
dependencies:
|
||||
"@floating-ui/dom" "1.4.3"
|
||||
echarts "^5.3.2"
|
||||
|
|
|
|||
Loading…
Reference in New Issue