Add latest changes from gitlab-org/gitlab@master
|
|
@ -835,11 +835,6 @@ rspec-ee unit pg14:
|
|||
- .rspec-ee-unit-parallel
|
||||
- .rails:rules:ee-only-unit
|
||||
|
||||
rspec-ee unit pg14 es8:
|
||||
extends:
|
||||
- .rspec-ee-base-pg14-es8
|
||||
- .rspec-ee-unit-parallel
|
||||
|
||||
rspec-ee unit pg14 single-db:
|
||||
extends:
|
||||
- rspec-ee unit pg14
|
||||
|
|
@ -874,11 +869,6 @@ rspec-ee integration pg14:
|
|||
- .rspec-ee-integration-parallel
|
||||
- .rails:rules:ee-only-integration
|
||||
|
||||
rspec-ee integration pg14 es8:
|
||||
extends:
|
||||
- .rspec-ee-base-pg14-es8
|
||||
- .rspec-ee-integration-parallel
|
||||
|
||||
rspec-ee integration pg14 single-db:
|
||||
extends:
|
||||
- rspec-ee integration pg14
|
||||
|
|
@ -928,11 +918,6 @@ rspec-ee system pg14:
|
|||
- .rspec-ee-system-parallel
|
||||
- .rails:rules:ee-only-system
|
||||
|
||||
rspec-ee system pg14 es8:
|
||||
extends:
|
||||
- .rspec-ee-base-pg14-es8
|
||||
- .rspec-ee-system-parallel
|
||||
|
||||
rspec-ee system pg14 single-db:
|
||||
extends:
|
||||
- rspec-ee system pg14
|
||||
|
|
@ -1038,80 +1023,7 @@ rspec system pg16:
|
|||
#####################################
|
||||
# EE: default branch nightly scheduled jobs #
|
||||
|
||||
# PG14
|
||||
rspec-ee unit pg14 opensearch1:
|
||||
extends:
|
||||
- .rspec-ee-base-pg14-opensearch1
|
||||
- .rspec-ee-unit-parallel
|
||||
- .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
|
||||
rspec-ee unit pg14 opensearch2:
|
||||
extends:
|
||||
- .rspec-ee-base-pg14-opensearch2
|
||||
- .rspec-ee-unit-parallel
|
||||
- .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
|
||||
rspec-ee integration pg14 opensearch1:
|
||||
extends:
|
||||
- .rspec-ee-base-pg14-opensearch1
|
||||
- .rspec-ee-integration-parallel
|
||||
- .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
|
||||
rspec-ee integration pg14 opensearch2:
|
||||
extends:
|
||||
- .rspec-ee-base-pg14-opensearch2
|
||||
- .rspec-ee-integration-parallel
|
||||
- .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
|
||||
rspec-ee system pg14 opensearch1:
|
||||
extends:
|
||||
- .rspec-ee-base-pg14-opensearch1
|
||||
- .rspec-ee-system-parallel
|
||||
- .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
|
||||
rspec-ee system pg14 opensearch2:
|
||||
extends:
|
||||
- .rspec-ee-base-pg14-opensearch2
|
||||
- .rspec-ee-system-parallel
|
||||
- .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
|
||||
# PG15
|
||||
rspec-ee unit pg15 opensearch1:
|
||||
extends:
|
||||
- .rspec-ee-base-pg15-opensearch1
|
||||
- .rspec-ee-unit-parallel
|
||||
- .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
|
||||
rspec-ee unit pg15 opensearch2:
|
||||
extends:
|
||||
- .rspec-ee-base-pg15-opensearch2
|
||||
- .rspec-ee-unit-parallel
|
||||
- .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
|
||||
rspec-ee integration pg15 opensearch1:
|
||||
extends:
|
||||
- .rspec-ee-base-pg15-opensearch1
|
||||
- .rspec-ee-integration-parallel
|
||||
- .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
|
||||
rspec-ee integration pg15 opensearch2:
|
||||
extends:
|
||||
- .rspec-ee-base-pg15-opensearch2
|
||||
- .rspec-ee-integration-parallel
|
||||
- .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
|
||||
rspec-ee system pg15 opensearch1:
|
||||
extends:
|
||||
- .rspec-ee-base-pg15-opensearch1
|
||||
- .rspec-ee-system-parallel
|
||||
- .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
|
||||
rspec-ee system pg15 opensearch2:
|
||||
extends:
|
||||
- .rspec-ee-base-pg15-opensearch2
|
||||
- .rspec-ee-system-parallel
|
||||
- .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
|
||||
rspec-ee migration pg15:
|
||||
extends:
|
||||
- .rspec-ee-base-pg15
|
||||
|
|
@ -1132,33 +1044,18 @@ rspec-ee unit pg15:
|
|||
- .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
- .rspec-ee-unit-parallel
|
||||
|
||||
rspec-ee unit pg15 es8:
|
||||
extends:
|
||||
- .rspec-ee-base-pg15-es8
|
||||
- .rspec-ee-unit-parallel
|
||||
|
||||
rspec-ee integration pg15:
|
||||
extends:
|
||||
- .rspec-ee-base-pg15
|
||||
- .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
- .rspec-ee-integration-parallel
|
||||
|
||||
rspec-ee integration pg15 es8:
|
||||
extends:
|
||||
- .rspec-ee-base-pg15-es8
|
||||
- .rspec-ee-integration-parallel
|
||||
|
||||
rspec-ee system pg15:
|
||||
extends:
|
||||
- .rspec-ee-base-pg15
|
||||
- .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
- .rspec-ee-system-parallel
|
||||
|
||||
rspec-ee system pg15 es8:
|
||||
extends:
|
||||
- .rspec-ee-base-pg15-es8
|
||||
- .rspec-ee-system-parallel
|
||||
|
||||
# PG16
|
||||
rspec-ee migration pg16:
|
||||
extends:
|
||||
|
|
@ -1192,62 +1089,61 @@ rspec-ee system pg16:
|
|||
- .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
- .rspec-ee-system-parallel
|
||||
|
||||
# We have too many jobs in nightly pipeline, more than 2k+,
|
||||
# which exceeds the limit of jobs a pipeline can have. Disable below for now.
|
||||
#
|
||||
# rspec-ee unit pg16 opensearch1:
|
||||
# extends:
|
||||
# - .rspec-ee-base-pg16-opensearch1
|
||||
# - .rspec-ee-unit-parallel
|
||||
# - .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
# Integration tests with Elastic Search and the actual PG production version (PG16)
|
||||
# https://gitlab.com/gitlab-org/quality/engineering-productivity/team/-/issues/534
|
||||
rspec-ee unit pg16 opensearch1:
|
||||
extends:
|
||||
- .rspec-ee-base-pg16-opensearch1
|
||||
- .rspec-ee-unit-parallel
|
||||
- .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
|
||||
# rspec-ee unit pg16 opensearch2:
|
||||
# extends:
|
||||
# - .rspec-ee-base-pg16-opensearch2
|
||||
# - .rspec-ee-unit-parallel
|
||||
# - .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
rspec-ee unit pg16 opensearch2:
|
||||
extends:
|
||||
- .rspec-ee-base-pg16-opensearch2
|
||||
- .rspec-ee-unit-parallel
|
||||
- .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
|
||||
# rspec-ee integration pg16 opensearch1:
|
||||
# extends:
|
||||
# - .rspec-ee-base-pg16-opensearch1
|
||||
# - .rspec-ee-integration-parallel
|
||||
# - .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
rspec-ee integration pg16 opensearch1:
|
||||
extends:
|
||||
- .rspec-ee-base-pg16-opensearch1
|
||||
- .rspec-ee-integration-parallel
|
||||
- .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
|
||||
# rspec-ee integration pg16 opensearch2:
|
||||
# extends:
|
||||
# - .rspec-ee-base-pg16-opensearch2
|
||||
# - .rspec-ee-integration-parallel
|
||||
# - .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
rspec-ee integration pg16 opensearch2:
|
||||
extends:
|
||||
- .rspec-ee-base-pg16-opensearch2
|
||||
- .rspec-ee-integration-parallel
|
||||
- .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
|
||||
# rspec-ee system pg16 opensearch1:
|
||||
# extends:
|
||||
# - .rspec-ee-base-pg16-opensearch1
|
||||
# - .rspec-ee-system-parallel
|
||||
# - .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
rspec-ee system pg16 opensearch1:
|
||||
extends:
|
||||
- .rspec-ee-base-pg16-opensearch1
|
||||
- .rspec-ee-system-parallel
|
||||
- .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
|
||||
# rspec-ee system pg16 opensearch2:
|
||||
# extends:
|
||||
# - .rspec-ee-base-pg16-opensearch2
|
||||
# - .rspec-ee-system-parallel
|
||||
# - .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
rspec-ee system pg16 opensearch2:
|
||||
extends:
|
||||
- .rspec-ee-base-pg16-opensearch2
|
||||
- .rspec-ee-system-parallel
|
||||
- .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
|
||||
# rspec-ee unit pg16 es8:
|
||||
# extends:
|
||||
# - .rspec-ee-base-pg16-es8
|
||||
# - .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
# - .rspec-ee-unit-parallel
|
||||
rspec-ee unit pg16 es8:
|
||||
extends:
|
||||
- .rspec-ee-base-pg16-es8
|
||||
- .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
- .rspec-ee-unit-parallel
|
||||
|
||||
# rspec-ee integration pg16 es8:
|
||||
# extends:
|
||||
# - .rspec-ee-base-pg16-es8
|
||||
# - .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
# - .rspec-ee-integration-parallel
|
||||
rspec-ee integration pg16 es8:
|
||||
extends:
|
||||
- .rspec-ee-base-pg16-es8
|
||||
- .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
- .rspec-ee-integration-parallel
|
||||
|
||||
# rspec-ee system pg16 es8:
|
||||
# extends:
|
||||
# - .rspec-ee-base-pg16-es8
|
||||
# - .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
# - .rspec-ee-system-parallel
|
||||
rspec-ee system pg16 es8:
|
||||
extends:
|
||||
- .rspec-ee-base-pg16-es8
|
||||
- .rails:rules:default-branch-schedule-nightly--code-backstage-ee-only
|
||||
- .rspec-ee-system-parallel
|
||||
# EE: default branch nightly scheduled jobs #
|
||||
#####################################
|
||||
|
||||
|
|
|
|||
|
|
@ -243,47 +243,11 @@ include:
|
|||
- .rspec-base
|
||||
- .use-pg14-es7-ee
|
||||
|
||||
.rspec-ee-base-pg14-es8:
|
||||
extends:
|
||||
- .rspec-base
|
||||
- .use-pg14-es8-ee
|
||||
- .rails:rules:run-search-tests
|
||||
|
||||
.rspec-ee-base-pg14-opensearch1:
|
||||
extends:
|
||||
- .rspec-base
|
||||
- .use-pg14-opensearch1-ee
|
||||
- .rails:rules:run-search-tests
|
||||
|
||||
.rspec-ee-base-pg14-opensearch2:
|
||||
extends:
|
||||
- .rspec-base
|
||||
- .use-pg14-opensearch2-ee
|
||||
- .rails:rules:run-search-tests
|
||||
|
||||
.rspec-ee-base-pg15:
|
||||
extends:
|
||||
- .rspec-base
|
||||
- .use-pg15-es7-ee
|
||||
|
||||
.rspec-ee-base-pg15-es8:
|
||||
extends:
|
||||
- .rspec-base
|
||||
- .use-pg15-es8-ee
|
||||
- .rails:rules:run-search-tests
|
||||
|
||||
.rspec-ee-base-pg15-opensearch1:
|
||||
extends:
|
||||
- .rspec-base
|
||||
- .use-pg15-opensearch1-ee
|
||||
- .rails:rules:run-search-tests
|
||||
|
||||
.rspec-ee-base-pg15-opensearch2:
|
||||
extends:
|
||||
- .rspec-base
|
||||
- .use-pg15-opensearch2-ee
|
||||
- .rails:rules:run-search-tests
|
||||
|
||||
.rspec-ee-base-pg16:
|
||||
extends:
|
||||
- .rspec-base
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ Layout/EmptyLinesAroundMethodBody:
|
|||
- 'app/models/repository.rb'
|
||||
- 'app/services/members/destroy_service.rb'
|
||||
- 'ee/app/models/software_license.rb'
|
||||
- 'ee/lib/gitlab/elastic/helper.rb'
|
||||
- 'ee/spec/support/helpers/identity_verification_helpers.rb'
|
||||
- 'lib/api/helpers/packages_helpers.rb'
|
||||
- 'lib/gitlab/background_migration/batched_migration_job.rb'
|
||||
|
|
|
|||
|
|
@ -195,7 +195,6 @@ Style/RedundantSelf:
|
|||
- 'ee/lib/gitlab/auth/smartcard.rb'
|
||||
- 'ee/lib/gitlab/ci/reports/license_scanning/report.rb'
|
||||
- 'ee/lib/gitlab/elastic/client.rb'
|
||||
- 'ee/lib/gitlab/elastic/helper.rb'
|
||||
- 'ee/lib/gitlab/geo.rb'
|
||||
- 'ee/lib/gitlab/geo/oauth/login_state.rb'
|
||||
- 'ee/lib/gitlab/geo/oauth/logout_state.rb'
|
||||
|
|
|
|||
4
Gemfile
|
|
@ -698,8 +698,8 @@ gem 'valid_email', '~> 0.1', feature_category: :shared
|
|||
gem 'jsonb_accessor', '~> 1.4', feature_category: :shared
|
||||
gem 'json', '~> 2.10.0', feature_category: :shared
|
||||
gem 'json_schemer', '~> 2.3.0', feature_category: :shared
|
||||
gem 'oj', '~> 3.13.21', feature_category: :shared
|
||||
gem 'oj-introspect', '~> 0.7', feature_category: :shared
|
||||
gem 'oj', '~> 3.16.0', '>=3.16.10', feature_category: :shared
|
||||
gem 'oj-introspect', '~> 0.8', feature_category: :shared
|
||||
gem 'multi_json', '~> 1.14.1', feature_category: :shared
|
||||
gem 'yajl-ruby', '~> 1.4.3', require: 'yajl', feature_category: :shared
|
||||
|
||||
|
|
|
|||
|
|
@ -447,8 +447,8 @@
|
|||
{"name":"oauth2","version":"2.0.9","platform":"ruby","checksum":"b21f9defcf52dc1610e0dfab4c868342173dcd707fd15c777d9f4f04e153f7fb"},
|
||||
{"name":"octokit","version":"9.2.0","platform":"ruby","checksum":"4fa47ff35ce654127edf2c836ab9269bcc8829f5542dc1e86871f697ce7f4316"},
|
||||
{"name":"ohai","version":"18.1.18","platform":"ruby","checksum":"42ee8196945cb935fdeec93ba7aaee757d1d552f7b933912a1f25863c3cc1ff0"},
|
||||
{"name":"oj","version":"3.13.23","platform":"ruby","checksum":"206dfdc4020ad9974705037f269cfba211d61b7662a58c717cce771829ccef51"},
|
||||
{"name":"oj-introspect","version":"0.7.2","platform":"ruby","checksum":"c415a44567ed2870d8e963a69421d9322128e194fab7867e37e54d5a25d5333d"},
|
||||
{"name":"oj","version":"3.16.10","platform":"ruby","checksum":"7f26bed974e331e16d579b470b0865010757f6fe6ee30ea9b67df653fbe13d7c"},
|
||||
{"name":"oj-introspect","version":"0.8.0","platform":"ruby","checksum":"5cbb15309d60294881e5c2f65ceb22e3b5798f26d0a1e65ae47a6342b87d9264"},
|
||||
{"name":"omniauth","version":"2.1.2","platform":"ruby","checksum":"def03277298b8f8a5d3ff16cdb2eb5edb9bffed60ee7dda24cc0c89b3ae6a0ce"},
|
||||
{"name":"omniauth-alicloud","version":"3.0.0","platform":"ruby","checksum":"9c5c4f3abb40d774b946015f177d503fbde99b2b57c0858284c25cc39369013e"},
|
||||
{"name":"omniauth-atlassian-oauth2","version":"0.2.0","platform":"ruby","checksum":"eb07574a188ab8a03376ce288bce86bc2dd4a1382ffa5781cb5e2b7bc15d76c9"},
|
||||
|
|
@ -709,7 +709,7 @@
|
|||
{"name":"spring-commands-rspec","version":"1.0.4","platform":"ruby","checksum":"6202e54fa4767452e3641461a83347645af478bf45dddcca9737b43af0dd1a2c"},
|
||||
{"name":"sprite-factory","version":"1.7.1","platform":"ruby","checksum":"5586524a1aec003241f1abc6852b61433e988aba5ee2b55f906387bf49b01ba2"},
|
||||
{"name":"sprockets","version":"3.7.2","platform":"ruby","checksum":"5ea1d7facd09203c1aa196afd6178208cd25abdbcc2a9978810a2f0754e152a0"},
|
||||
{"name":"sprockets-rails","version":"3.5.1","platform":"ruby","checksum":"c44626cb3887a1a8b572ca258685db33b4ebd041aa73428a716eac444ee5ef48"},
|
||||
{"name":"sprockets-rails","version":"3.5.2","platform":"ruby","checksum":"a9e88e6ce9f8c912d349aa5401509165ec42326baf9e942a85de4b76dbc4119e"},
|
||||
{"name":"ssh_data","version":"1.3.0","platform":"ruby","checksum":"ec7c1e95a3aebeee412147998f4c147b4b05da6ed0aafda6083f9449318eaac0"},
|
||||
{"name":"ssrf_filter","version":"1.0.8","platform":"ruby","checksum":"03f49f54837e407d43ee93ec733a8a94dc1bcf8185647ac61606e63aaedaa0db"},
|
||||
{"name":"stackprof","version":"0.2.27","platform":"ruby","checksum":"aff6d28656c852e74cf632cc2046f849033dc1dedffe7cb8c030d61b5745e80c"},
|
||||
|
|
|
|||
16
Gemfile.lock
|
|
@ -122,7 +122,7 @@ PATH
|
|||
specs:
|
||||
ipynbdiff (0.4.8)
|
||||
diffy (~> 3.4)
|
||||
oj (~> 3.13.16)
|
||||
oj (~> 3.16, >= 3.16.10)
|
||||
|
||||
PATH
|
||||
remote: vendor/gems/attr_encrypted
|
||||
|
|
@ -1243,9 +1243,11 @@ GEM
|
|||
plist (~> 3.1)
|
||||
train-core
|
||||
wmi-lite (~> 1.0)
|
||||
oj (3.13.23)
|
||||
oj-introspect (0.7.2)
|
||||
oj (>= 3.13.23)
|
||||
oj (3.16.10)
|
||||
bigdecimal (>= 3.0)
|
||||
ostruct (>= 0.2)
|
||||
oj-introspect (0.8.0)
|
||||
oj (>= 3.16.10)
|
||||
omniauth (2.1.2)
|
||||
hashie (>= 3.4.6)
|
||||
rack (>= 2.2.3)
|
||||
|
|
@ -1808,7 +1810,7 @@ GEM
|
|||
sprockets (3.7.2)
|
||||
concurrent-ruby (~> 1.0)
|
||||
rack (> 1, < 3)
|
||||
sprockets-rails (3.5.1)
|
||||
sprockets-rails (3.5.2)
|
||||
actionpack (>= 6.1)
|
||||
activesupport (>= 6.1)
|
||||
sprockets (>= 3.0.0)
|
||||
|
|
@ -2208,8 +2210,8 @@ DEPENDENCIES
|
|||
oauth2 (~> 2.0)
|
||||
octokit (~> 9.0)
|
||||
ohai (~> 18.1)
|
||||
oj (~> 3.13.21)
|
||||
oj-introspect (~> 0.7)
|
||||
oj (~> 3.16.0, >= 3.16.10)
|
||||
oj-introspect (~> 0.8)
|
||||
omniauth (~> 2.1.0)
|
||||
omniauth-alicloud (~> 3.0.0)
|
||||
omniauth-atlassian-oauth2 (~> 0.2.0)
|
||||
|
|
|
|||
|
|
@ -450,8 +450,8 @@
|
|||
{"name":"oauth2","version":"2.0.9","platform":"ruby","checksum":"b21f9defcf52dc1610e0dfab4c868342173dcd707fd15c777d9f4f04e153f7fb"},
|
||||
{"name":"octokit","version":"9.2.0","platform":"ruby","checksum":"4fa47ff35ce654127edf2c836ab9269bcc8829f5542dc1e86871f697ce7f4316"},
|
||||
{"name":"ohai","version":"18.1.18","platform":"ruby","checksum":"42ee8196945cb935fdeec93ba7aaee757d1d552f7b933912a1f25863c3cc1ff0"},
|
||||
{"name":"oj","version":"3.13.23","platform":"ruby","checksum":"206dfdc4020ad9974705037f269cfba211d61b7662a58c717cce771829ccef51"},
|
||||
{"name":"oj-introspect","version":"0.7.2","platform":"ruby","checksum":"c415a44567ed2870d8e963a69421d9322128e194fab7867e37e54d5a25d5333d"},
|
||||
{"name":"oj","version":"3.16.10","platform":"ruby","checksum":"7f26bed974e331e16d579b470b0865010757f6fe6ee30ea9b67df653fbe13d7c"},
|
||||
{"name":"oj-introspect","version":"0.8.0","platform":"ruby","checksum":"5cbb15309d60294881e5c2f65ceb22e3b5798f26d0a1e65ae47a6342b87d9264"},
|
||||
{"name":"omniauth","version":"2.1.2","platform":"ruby","checksum":"def03277298b8f8a5d3ff16cdb2eb5edb9bffed60ee7dda24cc0c89b3ae6a0ce"},
|
||||
{"name":"omniauth-alicloud","version":"3.0.0","platform":"ruby","checksum":"9c5c4f3abb40d774b946015f177d503fbde99b2b57c0858284c25cc39369013e"},
|
||||
{"name":"omniauth-atlassian-oauth2","version":"0.2.0","platform":"ruby","checksum":"eb07574a188ab8a03376ce288bce86bc2dd4a1382ffa5781cb5e2b7bc15d76c9"},
|
||||
|
|
@ -720,7 +720,7 @@
|
|||
{"name":"spring-commands-rspec","version":"1.0.4","platform":"ruby","checksum":"6202e54fa4767452e3641461a83347645af478bf45dddcca9737b43af0dd1a2c"},
|
||||
{"name":"sprite-factory","version":"1.7.1","platform":"ruby","checksum":"5586524a1aec003241f1abc6852b61433e988aba5ee2b55f906387bf49b01ba2"},
|
||||
{"name":"sprockets","version":"3.7.2","platform":"ruby","checksum":"5ea1d7facd09203c1aa196afd6178208cd25abdbcc2a9978810a2f0754e152a0"},
|
||||
{"name":"sprockets-rails","version":"3.5.1","platform":"ruby","checksum":"c44626cb3887a1a8b572ca258685db33b4ebd041aa73428a716eac444ee5ef48"},
|
||||
{"name":"sprockets-rails","version":"3.5.2","platform":"ruby","checksum":"a9e88e6ce9f8c912d349aa5401509165ec42326baf9e942a85de4b76dbc4119e"},
|
||||
{"name":"ssh_data","version":"1.3.0","platform":"ruby","checksum":"ec7c1e95a3aebeee412147998f4c147b4b05da6ed0aafda6083f9449318eaac0"},
|
||||
{"name":"ssrf_filter","version":"1.0.8","platform":"ruby","checksum":"03f49f54837e407d43ee93ec733a8a94dc1bcf8185647ac61606e63aaedaa0db"},
|
||||
{"name":"stackprof","version":"0.2.27","platform":"ruby","checksum":"aff6d28656c852e74cf632cc2046f849033dc1dedffe7cb8c030d61b5745e80c"},
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ PATH
|
|||
specs:
|
||||
ipynbdiff (0.4.8)
|
||||
diffy (~> 3.4)
|
||||
oj (~> 3.13.16)
|
||||
oj (~> 3.16, >= 3.16.10)
|
||||
|
||||
PATH
|
||||
remote: vendor/gems/attr_encrypted
|
||||
|
|
@ -1260,9 +1260,11 @@ GEM
|
|||
plist (~> 3.1)
|
||||
train-core
|
||||
wmi-lite (~> 1.0)
|
||||
oj (3.13.23)
|
||||
oj-introspect (0.7.2)
|
||||
oj (>= 3.13.23)
|
||||
oj (3.16.10)
|
||||
bigdecimal (>= 3.0)
|
||||
ostruct (>= 0.2)
|
||||
oj-introspect (0.8.0)
|
||||
oj (>= 3.16.10)
|
||||
omniauth (2.1.2)
|
||||
hashie (>= 3.4.6)
|
||||
rack (>= 2.2.3)
|
||||
|
|
@ -1841,7 +1843,7 @@ GEM
|
|||
sprockets (3.7.2)
|
||||
concurrent-ruby (~> 1.0)
|
||||
rack (> 1, < 3)
|
||||
sprockets-rails (3.5.1)
|
||||
sprockets-rails (3.5.2)
|
||||
actionpack (>= 6.1)
|
||||
activesupport (>= 6.1)
|
||||
sprockets (>= 3.0.0)
|
||||
|
|
@ -2243,8 +2245,8 @@ DEPENDENCIES
|
|||
oauth2 (~> 2.0)
|
||||
octokit (~> 9.0)
|
||||
ohai (~> 18.1)
|
||||
oj (~> 3.13.21)
|
||||
oj-introspect (~> 0.7)
|
||||
oj (~> 3.16.0, >= 3.16.10)
|
||||
oj-introspect (~> 0.8)
|
||||
omniauth (~> 2.1.0)
|
||||
omniauth-alicloud (~> 3.0.0)
|
||||
omniauth-atlassian-oauth2 (~> 0.2.0)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import {
|
|||
SCHEDULE_SOURCE,
|
||||
MERGE_TRAIN_EVENT_TYPE,
|
||||
MERGED_RESULT_EVENT_TYPE,
|
||||
PIPELINE_TYPE_BRANCH,
|
||||
PIPELINE_TYPE_TAG,
|
||||
} from '../constants';
|
||||
|
||||
export default {
|
||||
|
|
@ -37,6 +39,12 @@ export default {
|
|||
isMergedResultsPipeline() {
|
||||
return this.mergeRequestEventType === MERGED_RESULT_EVENT_TYPE;
|
||||
},
|
||||
isBranchPipeline() {
|
||||
return this.pipeline.type === PIPELINE_TYPE_BRANCH;
|
||||
},
|
||||
isTagPipeline() {
|
||||
return this.pipeline.type === PIPELINE_TYPE_TAG;
|
||||
},
|
||||
isDetachedPipeline() {
|
||||
return this.mergeRequestEventType === DETACHED_EVENT_TYPE;
|
||||
},
|
||||
|
|
@ -64,6 +72,8 @@ export default {
|
|||
latest: this.pipeline.latest,
|
||||
mergeTrainPipeline: this.isMergeTrainPipeline,
|
||||
mergedResultsPipeline: this.isMergedResultsPipeline,
|
||||
branchPipeline: this.isBranchPipeline,
|
||||
tagPipeline: this.isTagPipeline,
|
||||
detached: this.isDetachedPipeline,
|
||||
failed: Boolean(this.failureReason),
|
||||
autoDevops: this.isAutoDevopsPipeline,
|
||||
|
|
@ -109,7 +119,7 @@ export default {
|
|||
<gl-badge
|
||||
v-if="badges.latest"
|
||||
v-gl-tooltip
|
||||
:title="__('Latest pipeline for the most recent commit on this branch')"
|
||||
:title="__('Latest pipeline for the most recent commit on this ref')"
|
||||
variant="success"
|
||||
>
|
||||
{{ s__('Pipelines|latest') }}
|
||||
|
|
@ -166,6 +176,22 @@ export default {
|
|||
>
|
||||
{{ s__('Pipelines|merged results') }}
|
||||
</gl-badge>
|
||||
<gl-badge
|
||||
v-if="badges.branchPipeline"
|
||||
v-gl-tooltip
|
||||
:title="s__('Pipelines|This pipeline ran for a branch.')"
|
||||
variant="info"
|
||||
>
|
||||
{{ s__('Pipelines|branch') }}
|
||||
</gl-badge>
|
||||
<gl-badge
|
||||
v-if="badges.tagPipeline"
|
||||
v-gl-tooltip
|
||||
:title="s__('Pipelines|This pipeline ran for a tag.')"
|
||||
variant="info"
|
||||
>
|
||||
{{ s__('Pipelines|tag') }}
|
||||
</gl-badge>
|
||||
<gl-badge
|
||||
v-if="badges.stuck"
|
||||
v-gl-tooltip
|
||||
|
|
|
|||
|
|
@ -5,3 +5,5 @@ export const AUTO_DEVOPS_SOURCE = 'AUTO_DEVOPS_SOURCE';
|
|||
export const DETACHED_EVENT_TYPE = 'DETACHED';
|
||||
export const MERGED_RESULT_EVENT_TYPE = 'MERGED_RESULT';
|
||||
export const MERGE_TRAIN_EVENT_TYPE = 'MERGE_TRAIN';
|
||||
export const PIPELINE_TYPE_BRANCH = 'branch';
|
||||
export const PIPELINE_TYPE_TAG = 'tag';
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ query getPipelineHeaderData($fullPath: ID!, $iid: ID!) {
|
|||
name
|
||||
totalJobs
|
||||
refText
|
||||
type
|
||||
triggeredByPath
|
||||
stuck
|
||||
child
|
||||
|
|
|
|||
|
|
@ -41,6 +41,12 @@ export default {
|
|||
this.pipeline.flags.merged_result_pipeline && !this.pipeline.flags.merge_train_pipeline
|
||||
);
|
||||
},
|
||||
showBranchBadge() {
|
||||
return this.pipeline.flags.type === 'branch';
|
||||
},
|
||||
showTagBadge() {
|
||||
return this.pipeline.flags.type === 'tag';
|
||||
},
|
||||
autoDevopsTagId() {
|
||||
return `pipeline-url-autodevops-${this.pipeline.id}`;
|
||||
},
|
||||
|
|
@ -76,7 +82,7 @@ export default {
|
|||
<gl-badge
|
||||
v-if="pipeline.flags.latest"
|
||||
v-gl-tooltip
|
||||
:title="__('Latest pipeline for the most recent commit on this branch')"
|
||||
:title="__('Latest pipeline for the most recent commit on this ref')"
|
||||
variant="success"
|
||||
data-testid="pipeline-url-latest"
|
||||
>{{ __('latest') }}</gl-badge
|
||||
|
|
@ -149,6 +155,22 @@ export default {
|
|||
<gl-badge v-if="pipeline.flags.stuck" variant="warning" data-testid="pipeline-url-stuck">{{
|
||||
__('stuck')
|
||||
}}</gl-badge>
|
||||
<gl-badge
|
||||
v-if="showTagBadge"
|
||||
v-gl-tooltip
|
||||
:title="s__(`Pipeline|This pipeline ran for a tag.`)"
|
||||
variant="info"
|
||||
data-testid="pipeline-url-tag"
|
||||
>{{ s__('Pipeline|tag') }}</gl-badge
|
||||
>
|
||||
<gl-badge
|
||||
v-if="showBranchBadge"
|
||||
v-gl-tooltip
|
||||
:title="s__(`Pipeline|This pipeline ran for a branch.`)"
|
||||
variant="info"
|
||||
data-testid="pipeline-url-branch"
|
||||
>{{ s__('Pipeline|branch') }}</gl-badge
|
||||
>
|
||||
<gl-badge
|
||||
v-if="pipeline.flags.detached_merge_request_pipeline"
|
||||
v-gl-tooltip
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
fragment TroubleshootJob on Pipeline {
|
||||
# Overridden in EE
|
||||
id
|
||||
}
|
||||
|
|
@ -1,10 +1,12 @@
|
|||
#import "ee_else_ce/ci/pipelines_page/graphql/fragments/troubleshoot_job.fragment.graphql"
|
||||
|
||||
query getPipelineFailedJobs($fullPath: ID!, $pipelineIid: ID!) {
|
||||
project(fullPath: $fullPath) {
|
||||
id
|
||||
pipeline(iid: $pipelineIid) {
|
||||
id
|
||||
active
|
||||
troubleshootJobWithAi
|
||||
...TroubleshootJob
|
||||
jobs(statuses: [FAILED], retried: false) {
|
||||
count
|
||||
nodes {
|
||||
|
|
|
|||
|
|
@ -39,10 +39,10 @@ export default {
|
|||
</script>
|
||||
<template>
|
||||
<div id="peek-view-add-request" class="view gl-flex">
|
||||
<gl-form class="gl-flex gl-items-center" @submit.prevent="addRequest">
|
||||
<gl-form class="gl-flex gl-items-center gl-gap-4" @submit.prevent="addRequest">
|
||||
<gl-button
|
||||
v-gl-tooltip.viewport
|
||||
class="gl-mr-2"
|
||||
class="!gl-text-neutral-0"
|
||||
category="tertiary"
|
||||
variant="link"
|
||||
icon="plus"
|
||||
|
|
@ -57,17 +57,16 @@ export default {
|
|||
type="text"
|
||||
:placeholder="$options.i18n.inputLabel"
|
||||
:aria-label="$options.i18n.inputLabel"
|
||||
class="gl-ml-2 !gl-px-3 !gl-py-2"
|
||||
class="gl-w-20 !gl-bg-alpha-light-24 !gl-text-neutral-0 !gl-placeholder-neutral-0"
|
||||
@keyup.esc="clearForm"
|
||||
/>
|
||||
<gl-button
|
||||
v-gl-tooltip.viewport
|
||||
class="gl-ml-2"
|
||||
category="tertiary"
|
||||
type="submit"
|
||||
variant="link"
|
||||
icon="file-addition-solid"
|
||||
size="small"
|
||||
class="!gl-text-neutral-0"
|
||||
:aria-label="$options.i18n.submitLabel"
|
||||
>
|
||||
{{ $options.i18n.submitLabel }}
|
||||
|
|
|
|||
|
|
@ -59,17 +59,24 @@ export default {
|
|||
return this.currentRequest.details[this.metric];
|
||||
},
|
||||
metricDetailsSummary() {
|
||||
const summary = {};
|
||||
const summary = [];
|
||||
|
||||
if (!this.metricDetails.summaryOptions?.hideTotal) {
|
||||
summary[__('Total')] = this.metricDetails.calls;
|
||||
if (this.metricDetails.calls && !this.metricDetails.summaryOptions?.hideTotal) {
|
||||
summary.push([__('Total'), this.metricDetails.calls]);
|
||||
}
|
||||
|
||||
if (!this.metricDetails.summaryOptions?.hideDuration) {
|
||||
summary[s__('PerformanceBar|Total duration')] = this.metricDetails.duration;
|
||||
if (this.metricDetails.duration && !this.metricDetails.summaryOptions?.hideDuration) {
|
||||
summary.push([s__('PerformanceBar|Total duration'), this.metricDetails.duration]);
|
||||
}
|
||||
|
||||
return { ...summary, ...(this.metricDetails.summary || {}) };
|
||||
for (const entry of Object.entries(this.metricDetails.summary ?? {})) {
|
||||
// Filter out entries which have no value
|
||||
if (entry[1]) {
|
||||
summary.push(entry);
|
||||
}
|
||||
}
|
||||
|
||||
return summary;
|
||||
},
|
||||
metricDetailsLabel() {
|
||||
if (this.metricDetails.duration && this.metricDetails.calls) {
|
||||
|
|
@ -146,7 +153,7 @@ export default {
|
|||
<gl-button
|
||||
v-gl-tooltip.viewport
|
||||
v-gl-modal="modalId"
|
||||
class="gl-mr-2"
|
||||
class="gl-mr-2 !gl-text-neutral-0"
|
||||
:title="header"
|
||||
variant="link"
|
||||
>
|
||||
|
|
@ -154,11 +161,19 @@ export default {
|
|||
{{ metricDetailsLabel }}
|
||||
</span>
|
||||
</gl-button>
|
||||
<gl-modal :modal-id="modalId" :title="header" size="lg" footer-class="!gl-hidden" scrollable>
|
||||
<gl-modal
|
||||
:modal-id="modalId"
|
||||
:title="header"
|
||||
size="lg"
|
||||
scrollable
|
||||
hide-backdrop
|
||||
hide-footer
|
||||
no-focus-on-show
|
||||
>
|
||||
<div class="gl-flex gl-items-center gl-justify-between">
|
||||
<div class="gl-flex gl-items-center" data-testid="performance-bar-summary">
|
||||
<div v-for="(value, name) in metricDetailsSummary" :key="name" class="gl-pr-8">
|
||||
<div v-if="value" data-testid="performance-bar-summary-item">
|
||||
<div class="gl-flex gl-items-center gl-gap-8" data-testid="performance-bar-summary">
|
||||
<div v-for="[name, value] in metricDetailsSummary" :key="name">
|
||||
<div data-testid="performance-bar-summary-item">
|
||||
<div>{{ name }}</div>
|
||||
<div class="gl-text-size-h1 gl-font-semibold">{{ value }}</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ export default {
|
|||
<div class="view gl-flex gl-gap-2">
|
||||
<gl-button
|
||||
icon="information-o"
|
||||
class="!gl-text-neutral-0"
|
||||
variant="link"
|
||||
:aria-label="s__('PerformanceBar|Debugging information')"
|
||||
@click="showInfoModal"
|
||||
|
|
@ -52,12 +53,13 @@ export default {
|
|||
size="sm"
|
||||
hide-backdrop
|
||||
hide-footer
|
||||
no-focus-on-show
|
||||
>
|
||||
<div class="gl-pb-6">
|
||||
<div class="gl-flex gl-flex-col gl-text-lg">
|
||||
<strong class="gl-border-b gl-mb-4 gl-w-full gl-font-bold">
|
||||
{{ s__('PerformanceBar|Host') }}</strong
|
||||
>
|
||||
<strong class="gl-border-b gl-mb-4 gl-w-full gl-font-bold gl-text-neutral-0">
|
||||
{{ s__('PerformanceBar|Host') }}
|
||||
</strong>
|
||||
<div>
|
||||
<gl-emoji data-testid="host-emoji" data-name="computer" />
|
||||
<span>{{ hostInfo }} </span>
|
||||
|
|
|
|||
|
|
@ -138,6 +138,18 @@ export default {
|
|||
this.store.findRequest(this.currentRequestId).fullUrl,
|
||||
);
|
||||
},
|
||||
backgroundClass() {
|
||||
if (this.env === 'production') {
|
||||
return 'gl-bg-neutral-950';
|
||||
}
|
||||
if (this.env === 'staging') {
|
||||
return 'gl-bg-purple-950 dark:gl-bg-purple-50';
|
||||
}
|
||||
if (this.env === 'development') {
|
||||
return 'gl-bg-red-900 dark:gl-bg-red-50';
|
||||
}
|
||||
return 'gl-bg-neutral-1000';
|
||||
},
|
||||
},
|
||||
created() {
|
||||
if (!this.showZoekt) {
|
||||
|
|
@ -167,7 +179,7 @@ export default {
|
|||
};
|
||||
</script>
|
||||
<template>
|
||||
<div id="js-peek" :class="env">
|
||||
<div id="js-peek" :class="[env, backgroundClass]">
|
||||
<div
|
||||
v-if="currentRequest"
|
||||
class="container-fluid gl-flex gl-overflow-x-auto"
|
||||
|
|
@ -189,14 +201,16 @@ export default {
|
|||
id="peek-view-trace"
|
||||
class="view"
|
||||
>
|
||||
<gl-link class="gl-underline" :href="currentRequest.details.tracing.tracing_url">{{
|
||||
s__('PerformanceBar|Trace')
|
||||
}}</gl-link>
|
||||
<gl-link
|
||||
class="!gl-text-neutral-0 gl-underline"
|
||||
:href="currentRequest.details.tracing.tracing_url"
|
||||
>{{ s__('PerformanceBar|Trace') }}</gl-link
|
||||
>
|
||||
</div>
|
||||
<div v-if="showFlamegraphButtons" id="peek-flamegraph" class="view">
|
||||
<gl-link
|
||||
v-gl-tooltip.viewport
|
||||
class="gl-text-sm"
|
||||
class="gl-text-sm !gl-text-neutral-0"
|
||||
:href="flamegraphPath('wall', currentRequestId)"
|
||||
:title="s__('PerformanceBar|Wall flamegraph')"
|
||||
>{{ s__('PerformanceBar|Wall') }}</gl-link
|
||||
|
|
@ -204,7 +218,7 @@ export default {
|
|||
/
|
||||
<gl-link
|
||||
v-gl-tooltip.viewport
|
||||
class="gl-text-sm"
|
||||
class="gl-text-sm !gl-text-neutral-0"
|
||||
:href="flamegraphPath('cpu', currentRequestId)"
|
||||
:title="s__('PerformanceBar|CPU flamegraph')"
|
||||
>{{ s__('PerformanceBar|CPU') }}</gl-link
|
||||
|
|
@ -212,7 +226,7 @@ export default {
|
|||
/
|
||||
<gl-link
|
||||
v-gl-tooltip.viewport
|
||||
class="gl-text-sm"
|
||||
class="gl-text-sm !gl-text-neutral-0"
|
||||
:href="flamegraphPath('object', currentRequestId)"
|
||||
:title="s__('PerformanceBar|Object flamegraph')"
|
||||
>{{ s__('PerformanceBar|Object') }}</gl-link
|
||||
|
|
@ -226,7 +240,7 @@ export default {
|
|||
v-if="currentRequest.details"
|
||||
id="peek-download"
|
||||
v-gl-tooltip.viewport
|
||||
class="view gl-text-sm"
|
||||
class="view gl-text-sm !gl-text-neutral-0"
|
||||
is-unsafe-link
|
||||
:download="downloadName"
|
||||
:href="downloadPath"
|
||||
|
|
@ -237,7 +251,7 @@ export default {
|
|||
v-if="showMemoryReportButton"
|
||||
id="peek-memory-report"
|
||||
v-gl-tooltip.viewport
|
||||
class="view gl-text-sm"
|
||||
class="view gl-text-sm !gl-text-neutral-0"
|
||||
:href="memoryReportPath"
|
||||
:title="s__('PerformanceBar|Download memory report')"
|
||||
>{{ s__('PerformanceBar|Memory report') }}</gl-link
|
||||
|
|
@ -245,7 +259,7 @@ export default {
|
|||
<gl-link
|
||||
v-if="statsUrl"
|
||||
v-gl-tooltip.viewport
|
||||
class="view gl-text-sm"
|
||||
class="view gl-text-sm !gl-text-neutral-0"
|
||||
:href="statsUrl"
|
||||
:title="s__('PerformanceBar|Show stats')"
|
||||
>{{ s__('PerformanceBar|Stats') }}</gl-link
|
||||
|
|
|
|||
|
|
@ -29,7 +29,10 @@ export default {
|
|||
</script>
|
||||
<template>
|
||||
<div id="peek-request-selector" data-testid="request-dropdown" class="view gl-mr-5">
|
||||
<gl-form-select v-model="currentRequestId">
|
||||
<gl-form-select
|
||||
v-model="currentRequestId"
|
||||
select-class="gl-bg-alpha-light-24 gl-text-neutral-0 gl-w-26"
|
||||
>
|
||||
<option
|
||||
v-for="request in requests"
|
||||
:key="request.id"
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ const REPLACE_BLOB_MODAL_ID = 'modal-replace-blob';
|
|||
|
||||
export default {
|
||||
i18n: {
|
||||
replace: __('Replace file'),
|
||||
replace: __('Replace'),
|
||||
},
|
||||
replaceBlobModalId: REPLACE_BLOB_MODAL_ID,
|
||||
components: {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { setUrlParams, relativePathToAbsolute, getBaseURL } from '~/lib/utils/ur
|
|||
import { DEFAULT_BLOB_INFO } from '~/repository/constants';
|
||||
|
||||
export const i18n = {
|
||||
btnCopyContentsTitle: __('Copy file contents'),
|
||||
btnCopyContentsTitle: s__('BlobViewer|Copy contents'),
|
||||
btnDownloadTitle: __('Download'),
|
||||
btnRawTitle: s__('BlobViewer|Open raw'),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ import BlobButtonGroup from './blob_button_group.vue';
|
|||
import BlobDeleteFileGroup from './blob_delete_file_group.vue';
|
||||
|
||||
export const i18n = {
|
||||
dropdownLabel: __('Actions'),
|
||||
dropdownLabel: __('File actions'),
|
||||
dropdownTooltip: __('Actions'),
|
||||
fetchError: __('An error occurred while fetching lock information, please try again.'),
|
||||
};
|
||||
|
||||
|
|
@ -117,7 +118,7 @@ export default {
|
|||
</script>
|
||||
<template>
|
||||
<gl-disclosure-dropdown
|
||||
v-gl-tooltip-directive.hover="$options.i18n.dropdownLabel"
|
||||
v-gl-tooltip-directive.hover="$options.i18n.dropdownTooltip"
|
||||
no-caret
|
||||
icon="ellipsis_v"
|
||||
data-testid="default-actions-container"
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ import {
|
|||
} from '~/work_items/utils';
|
||||
import { TYPENAME_MERGE_REQUEST, TYPENAME_VULNERABILITY } from '~/graphql_shared/constants';
|
||||
import {
|
||||
I18N_WORK_ITEM_CREATE_BUTTON_LABEL,
|
||||
I18N_WORK_ITEM_ERROR_CREATING,
|
||||
sprintfWorkItem,
|
||||
i18n,
|
||||
|
|
@ -382,7 +381,7 @@ export default {
|
|||
return sprintfWorkItem(I18N_WORK_ITEM_ERROR_CREATING, this.selectedWorkItemTypeName);
|
||||
},
|
||||
createWorkItemText() {
|
||||
return sprintfWorkItem(I18N_WORK_ITEM_CREATE_BUTTON_LABEL, this.selectedWorkItemTypeName);
|
||||
return sprintfWorkItem(s__('WorkItem|Create %{workItemType}'), this.selectedWorkItemTypeName);
|
||||
},
|
||||
makeConfidentialText() {
|
||||
return sprintfWorkItem(
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import { __, s__ } from '~/locale';
|
|||
import { isMetaClick } from '~/lib/utils/common_utils';
|
||||
import { convertTypeEnumToName, newWorkItemPath } from '~/work_items/utils';
|
||||
import {
|
||||
I18N_NEW_WORK_ITEM_BUTTON_LABEL,
|
||||
sprintfWorkItem,
|
||||
ROUTES,
|
||||
RELATED_ITEM_ID_URL_QUERY_PARAM,
|
||||
|
|
@ -138,11 +137,14 @@ export default {
|
|||
},
|
||||
newWorkItemButtonText() {
|
||||
return this.alwaysShowWorkItemTypeSelect && this.workItemTypeName
|
||||
? sprintfWorkItem(I18N_NEW_WORK_ITEM_BUTTON_LABEL, '')
|
||||
? sprintfWorkItem(s__('WorkItem|New %{workItemType}'), '')
|
||||
: this.newWorkItemText;
|
||||
},
|
||||
newWorkItemText() {
|
||||
return sprintfWorkItem(I18N_NEW_WORK_ITEM_BUTTON_LABEL, this.selectedWorkItemTypeLowercase);
|
||||
return sprintfWorkItem(
|
||||
s__('WorkItem|New %{workItemType}'),
|
||||
this.selectedWorkItemTypeLowercase,
|
||||
);
|
||||
},
|
||||
workItemCreatedText() {
|
||||
return sprintfWorkItem(
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ import {
|
|||
WORK_ITEMS_TYPE_MAP,
|
||||
I18N_WORK_ITEM_SEARCH_INPUT_PLACEHOLDER,
|
||||
I18N_WORK_ITEM_SEARCH_ERROR,
|
||||
I18N_WORK_ITEM_NO_MATCHES_FOUND,
|
||||
sprintfWorkItem,
|
||||
} from '../../constants';
|
||||
import { formatAncestors, isReference } from '../../utils';
|
||||
|
|
@ -232,7 +231,6 @@ export default {
|
|||
},
|
||||
},
|
||||
i18n: {
|
||||
noMatchesFoundMessage: I18N_WORK_ITEM_NO_MATCHES_FOUND,
|
||||
addInputPlaceholder: I18N_WORK_ITEM_SEARCH_INPUT_PLACEHOLDER,
|
||||
},
|
||||
safeHtmlConfig: { ADD_TAGS: ['strong', 'span'] },
|
||||
|
|
@ -276,7 +274,7 @@ export default {
|
|||
</template>
|
||||
<template #no-results-content>
|
||||
<span data-testid="no-match-found-namespace-message">{{
|
||||
$options.i18n.noMatchesFoundMessage
|
||||
s__('WorkItem|No matches found')
|
||||
}}</span>
|
||||
</template>
|
||||
</gl-token-selector>
|
||||
|
|
|
|||
|
|
@ -24,10 +24,6 @@ import {
|
|||
BASE_ALLOWED_CREATE_TYPES,
|
||||
WORK_ITEM_TYPE_VALUE_KEY_RESULT,
|
||||
WORK_ITEM_TYPE_VALUE_OBJECTIVE,
|
||||
I18N_WORK_ITEM_COPY_CREATE_NOTE_EMAIL,
|
||||
I18N_WORK_ITEM_ERROR_COPY_REFERENCE,
|
||||
I18N_WORK_ITEM_ERROR_COPY_EMAIL,
|
||||
I18N_WORK_ITEM_NEW_RELATED_ITEM,
|
||||
WORK_ITEM_TYPE_ENUM_EPIC,
|
||||
WORK_ITEM_TYPE_VALUE_EPIC,
|
||||
WORK_ITEM_TYPE_VALUE_MAP,
|
||||
|
|
@ -260,19 +256,26 @@ export default {
|
|||
this.workItemType,
|
||||
),
|
||||
copyCreateNoteEmail: sprintfWorkItem(
|
||||
I18N_WORK_ITEM_COPY_CREATE_NOTE_EMAIL,
|
||||
s__('WorkItem|Copy %{workItemType} email address'),
|
||||
this.workItemType,
|
||||
),
|
||||
copyReferenceError: sprintfWorkItem(
|
||||
s__(
|
||||
'WorkItem|Something went wrong while copying the %{workItemType} reference. Please try again.',
|
||||
),
|
||||
this.workItemType,
|
||||
),
|
||||
copyReferenceError: sprintfWorkItem(I18N_WORK_ITEM_ERROR_COPY_REFERENCE, this.workItemType),
|
||||
copyCreateNoteEmailError: sprintfWorkItem(
|
||||
I18N_WORK_ITEM_ERROR_COPY_EMAIL,
|
||||
s__(
|
||||
'WorkItem|Something went wrong while copying the %{workItemType} email address. Please try again.',
|
||||
),
|
||||
this.workItemType,
|
||||
),
|
||||
};
|
||||
},
|
||||
newRelatedItemLabel() {
|
||||
return this.workItemType === WORK_ITEM_TYPE_VALUE_EPIC
|
||||
? sprintfWorkItem(I18N_WORK_ITEM_NEW_RELATED_ITEM, this.workItemType)
|
||||
? sprintfWorkItem(s__('WorkItem|New related %{workItemType}'), this.workItemType)
|
||||
: s__('WorkItem|New related item');
|
||||
},
|
||||
areYouSureDeleteMessage() {
|
||||
|
|
|
|||
|
|
@ -12,9 +12,6 @@ import {
|
|||
FORM_TYPES,
|
||||
WORK_ITEMS_TYPE_MAP,
|
||||
WORK_ITEM_TYPE_ENUM_TASK,
|
||||
I18N_WORK_ITEM_CREATE_BUTTON_LABEL,
|
||||
I18N_WORK_ITEM_ADD_BUTTON_LABEL,
|
||||
I18N_WORK_ITEM_ADD_MULTIPLE_BUTTON_LABEL,
|
||||
I18N_WORK_ITEM_CONFIDENTIALITY_CHECKBOX_LABEL,
|
||||
I18N_WORK_ITEM_CONFIDENTIALITY_CHECKBOX_TOOLTIP,
|
||||
WORK_ITEM_TYPE_VALUE_EPIC,
|
||||
|
|
@ -192,12 +189,12 @@ export default {
|
|||
},
|
||||
addOrCreateButtonLabel() {
|
||||
if (this.isCreateForm) {
|
||||
return sprintfWorkItem(I18N_WORK_ITEM_CREATE_BUTTON_LABEL, this.childrenTypeName);
|
||||
return sprintfWorkItem(s__('WorkItem|Create %{workItemType}'), this.childrenTypeName);
|
||||
}
|
||||
if (this.workItemsToAdd.length > 1) {
|
||||
return sprintfWorkItem(I18N_WORK_ITEM_ADD_MULTIPLE_BUTTON_LABEL, this.childrenTypeName);
|
||||
return sprintfWorkItem(s__('WorkItem|Add %{workItemType}s'), this.childrenTypeName);
|
||||
}
|
||||
return sprintfWorkItem(I18N_WORK_ITEM_ADD_BUTTON_LABEL, this.childrenTypeName);
|
||||
return sprintfWorkItem(s__('WorkItem|Add %{workItemType}'), this.childrenTypeName);
|
||||
},
|
||||
confidentialityCheckboxLabel() {
|
||||
return sprintfWorkItem(I18N_WORK_ITEM_CONFIDENTIALITY_CHECKBOX_LABEL, this.childrenTypeName);
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import { getParameterByName } from '~/lib/utils/url_utility';
|
|||
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
|
||||
import {
|
||||
FORM_TYPES,
|
||||
WORK_ITEMS_TREE_TEXT,
|
||||
WORK_ITEM_TYPE_VALUE_MAP,
|
||||
WORK_ITEMS_TYPE_MAP,
|
||||
WORK_ITEM_TYPE_ENUM_OBJECTIVE,
|
||||
|
|
@ -42,7 +41,6 @@ import WorkItemRolledUpCount from './work_item_rolled_up_count.vue';
|
|||
|
||||
export default {
|
||||
FORM_TYPES,
|
||||
WORK_ITEMS_TREE_TEXT,
|
||||
WORK_ITEM_TYPE_ENUM_OBJECTIVE,
|
||||
WORK_ITEM_TYPE_ENUM_KEY_RESULT,
|
||||
components: {
|
||||
|
|
@ -390,7 +388,7 @@ export default {
|
|||
<template>
|
||||
<crud-component
|
||||
ref="workItemTree"
|
||||
:title="$options.WORK_ITEMS_TREE_TEXT.title"
|
||||
:title="s__('WorkItem|Child items')"
|
||||
:anchor-id="widgetName"
|
||||
:is-loading="isLoadingChildren && !fetchNextPageInProgress"
|
||||
is-collapsible
|
||||
|
|
@ -463,7 +461,11 @@ export default {
|
|||
</template>
|
||||
|
||||
<template v-if="showEmptyMessage" #empty>
|
||||
{{ $options.WORK_ITEMS_TREE_TEXT.empty }}
|
||||
{{
|
||||
s__(
|
||||
'WorkItem|No child items are currently assigned. Use child items to break down work into smaller parts.',
|
||||
)
|
||||
}}
|
||||
</template>
|
||||
|
||||
<template #default>
|
||||
|
|
|
|||
|
|
@ -76,18 +76,12 @@ export const I18N_WORK_ITEM_FETCH_AWARD_EMOJI_ERROR = s__(
|
|||
'WorkItem|Something went wrong while fetching work item award emojis. Please try again.',
|
||||
);
|
||||
|
||||
export const I18N_NEW_WORK_ITEM_BUTTON_LABEL = s__('WorkItem|New %{workItemType}');
|
||||
export const I18N_WORK_ITEM_CREATE_BUTTON_LABEL = s__('WorkItem|Create %{workItemType}');
|
||||
export const I18N_WORK_ITEM_NEW_RELATED_ITEM = s__('WorkItem|New related %{workItemType}');
|
||||
export const I18N_WORK_ITEM_ADD_BUTTON_LABEL = s__('WorkItem|Add %{workItemType}');
|
||||
export const I18N_WORK_ITEM_ADD_MULTIPLE_BUTTON_LABEL = s__('WorkItem|Add %{workItemType}s');
|
||||
export const I18N_WORK_ITEM_SEARCH_INPUT_PLACEHOLDER = s__(
|
||||
'WorkItem|Search existing items, paste URL, or enter reference ID',
|
||||
);
|
||||
export const I18N_WORK_ITEM_SEARCH_ERROR = s__(
|
||||
'WorkItem|Something went wrong while fetching the %{workItemType}. Please try again.',
|
||||
);
|
||||
export const I18N_WORK_ITEM_NO_MATCHES_FOUND = s__('WorkItem|No matches found');
|
||||
export const I18N_WORK_ITEM_CONFIDENTIALITY_CHECKBOX_LABEL = s__(
|
||||
'WorkItem|This %{workItemType} is confidential and should only be visible to team members with at least the Planner role',
|
||||
);
|
||||
|
|
@ -95,17 +89,6 @@ export const I18N_WORK_ITEM_CONFIDENTIALITY_CHECKBOX_TOOLTIP = s__(
|
|||
'WorkItem|A non-confidential %{workItemType} cannot be assigned to a confidential parent %{parentWorkItemType}.',
|
||||
);
|
||||
|
||||
export const I18N_WORK_ITEM_ERROR_COPY_REFERENCE = s__(
|
||||
'WorkItem|Something went wrong while copying the %{workItemType} reference. Please try again.',
|
||||
);
|
||||
export const I18N_WORK_ITEM_ERROR_COPY_EMAIL = s__(
|
||||
'WorkItem|Something went wrong while copying the %{workItemType} email address. Please try again.',
|
||||
);
|
||||
|
||||
export const I18N_WORK_ITEM_COPY_CREATE_NOTE_EMAIL = s__(
|
||||
'WorkItem|Copy %{workItemType} email address',
|
||||
);
|
||||
|
||||
export const MAX_WORK_ITEMS = 10;
|
||||
|
||||
export const I18N_MAX_WORK_ITEMS_ERROR_MESSAGE = sprintf(
|
||||
|
|
@ -205,13 +188,6 @@ export const WORK_ITEM_TYPE_VALUE_MAP = {
|
|||
[WORK_ITEM_TYPE_VALUE_TICKET]: WORK_ITEM_TYPE_ENUM_TICKET,
|
||||
};
|
||||
|
||||
export const WORK_ITEMS_TREE_TEXT = {
|
||||
title: s__('WorkItem|Child items'),
|
||||
empty: s__(
|
||||
'WorkItem|No child items are currently assigned. Use child items to break down work into smaller parts.',
|
||||
),
|
||||
};
|
||||
|
||||
export const FORM_TYPES = {
|
||||
create: 'create',
|
||||
add: 'add',
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ export function optimisticAwardUpdate({ note, name, fullPath, workItemIid }) {
|
|||
const { mutation } = getMutation({ note, name });
|
||||
|
||||
const currentUserId = window.gon.current_user_id;
|
||||
const currentUserFullName = window.gon.current_user_fullname;
|
||||
|
||||
return (store) => {
|
||||
store.updateQuery(
|
||||
|
|
@ -52,7 +53,7 @@ export function optimisticAwardUpdate({ note, name, fullPath, workItemIid }) {
|
|||
user: {
|
||||
__typename: 'UserCore',
|
||||
id: convertToGraphQLId(TYPENAME_USER, currentUserId),
|
||||
name: null,
|
||||
name: currentUserFullName,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -357,9 +357,6 @@ $gl-bronze-plan: #cd7f32;
|
|||
/*
|
||||
Performance Bar
|
||||
*/
|
||||
$perf-bar-production: $gray-950;
|
||||
$perf-bar-staging: $purple-950;
|
||||
$perf-bar-development: $red-900;
|
||||
$perf-bar-bucket-bg: $black;
|
||||
$perf-bar-bucket-box-shadow-from: rgba($white, 0.2);
|
||||
$perf-bar-bucket-box-shadow-to: rgba($black, 0.25);
|
||||
|
|
|
|||
|
|
@ -9,60 +9,18 @@
|
|||
z-index: #{$zindex-modal-backdrop - 1};
|
||||
|
||||
height: $performance-bar-height;
|
||||
background: $black;
|
||||
font-size: $gl-font-size-small;
|
||||
line-height: $performance-bar-height;
|
||||
color: $gray-50;
|
||||
|
||||
select {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
input {
|
||||
width: $input-short-width - 60px;
|
||||
}
|
||||
|
||||
select,
|
||||
input {
|
||||
color: inherit;
|
||||
background-color: rgba($white, 0.2);
|
||||
|
||||
&::placeholder {
|
||||
color: rgba($white, 0.7);
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
color: initial;
|
||||
}
|
||||
|
||||
// stylelint-disable-next-line gitlab/no-gl-class
|
||||
.gl-link,
|
||||
.gl-button {
|
||||
color: $white;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.production {
|
||||
background-color: $perf-bar-production;
|
||||
}
|
||||
|
||||
&.staging {
|
||||
background-color: $perf-bar-staging;
|
||||
}
|
||||
|
||||
&.development {
|
||||
background-color: $perf-bar-development;
|
||||
|
||||
// stylelint-disable-next-line gitlab/no-gl-class
|
||||
.gl-dark & {
|
||||
background-color: $red-950;
|
||||
}
|
||||
}
|
||||
|
||||
// UI Elements
|
||||
.bucket {
|
||||
background: $perf-bar-bucket-bg;
|
||||
|
|
@ -87,22 +45,6 @@
|
|||
color: $perf-bar-canary-text;
|
||||
}
|
||||
|
||||
strong {
|
||||
color: $white;
|
||||
}
|
||||
|
||||
table {
|
||||
color: $black;
|
||||
|
||||
td {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.backtrace-row {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.view {
|
||||
flex-shrink: 0;
|
||||
|
||||
|
|
@ -126,19 +68,4 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.performance-bar-modal {
|
||||
.modal-body {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#modal-peek-pg-queries-content {
|
||||
color: $black;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -409,6 +409,8 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
|
|||
)
|
||||
end
|
||||
|
||||
display_max_limit_warning
|
||||
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
# use next to appease Rubocop
|
||||
|
|
@ -683,6 +685,14 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
|
|||
view: diff_view
|
||||
)
|
||||
end
|
||||
|
||||
def display_max_limit_warning
|
||||
return unless @merge_request.reached_versions_limit?
|
||||
|
||||
flash[:alert] = format(
|
||||
_("This merge request has reached the maximum limit of %{limit} versions and cannot be updated further. " \
|
||||
"Close this merge request and create a new one instead."), limit: MergeRequest::DIFF_VERSION_LIMIT)
|
||||
end
|
||||
end
|
||||
|
||||
Projects::MergeRequestsController.prepend_mod_with('Projects::MergeRequestsController')
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ class Projects::PipelinesController < Projects::ApplicationController
|
|||
def create
|
||||
service_response = Ci::CreatePipelineService
|
||||
.new(project, current_user, create_params)
|
||||
.execute(:web, ignore_skip_ci: true, save_on_errors: false)
|
||||
.execute(:web, ignore_skip_ci: true, save_on_errors: false, **create_execute_params)
|
||||
|
||||
@pipeline = service_response.payload
|
||||
|
||||
|
|
@ -262,6 +262,10 @@ class Projects::PipelinesController < Projects::ApplicationController
|
|||
params.require(:pipeline).permit(:ref, variables_attributes: %i[key variable_type secret_value])
|
||||
end
|
||||
|
||||
def create_execute_params
|
||||
params.require(:pipeline).permit(inputs: {}).to_h.symbolize_keys
|
||||
end
|
||||
|
||||
def ensure_pipeline
|
||||
render_404 unless pipeline
|
||||
end
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ module Ci
|
|||
all_runners
|
||||
end
|
||||
|
||||
items = by_ids(items)
|
||||
items = search(items)
|
||||
items = by_active(items)
|
||||
items = by_status(items)
|
||||
|
|
@ -45,6 +46,12 @@ module Ci
|
|||
|
||||
attr_reader :group, :project
|
||||
|
||||
def by_ids(items)
|
||||
return items unless @params[:id_in]
|
||||
|
||||
items.id_in(@params[:id_in])
|
||||
end
|
||||
|
||||
def runner_type
|
||||
@params[:type_type]&.to_sym
|
||||
end
|
||||
|
|
|
|||
|
|
@ -134,3 +134,5 @@ module Mutations
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
Mutations::Namespace::PackageSettings::Update.prepend_mod
|
||||
|
|
|
|||
|
|
@ -71,6 +71,8 @@ module Types
|
|||
|
||||
field :nuget_symbol_server_enabled, GraphQL::Types::Boolean,
|
||||
null: false,
|
||||
description: 'Indicates wheather the NuGet symbol server is enabled for this namespace.'
|
||||
description: 'Indicates whether the NuGet symbol server is enabled for this namespace.'
|
||||
end
|
||||
end
|
||||
|
||||
Types::Namespace::PackageSettingsType.prepend_mod
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ class MergeRequest < ApplicationRecord
|
|||
SORTING_PREFERENCE_FIELD = :merge_requests_sort
|
||||
CI_MERGE_REQUEST_DESCRIPTION_MAX_LENGTH = 2700
|
||||
MERGE_LEASE_TIMEOUT = 15.minutes.to_i
|
||||
DIFF_VERSION_LIMIT = 1_000
|
||||
|
||||
belongs_to :target_project, class_name: "Project"
|
||||
belongs_to :source_project, class_name: "Project"
|
||||
|
|
@ -333,6 +334,11 @@ class MergeRequest < ApplicationRecord
|
|||
includes(:target_project)
|
||||
end
|
||||
scope :by_commit_sha, ->(sha) do
|
||||
Gitlab::AppLogger.info(
|
||||
event: 'merge_request_by_commit_sha_call',
|
||||
message: "MergeRequest.by_commit_sha called via #{caller_locations.reject { |line| line.path.include?('/gems/') }.first}"
|
||||
)
|
||||
|
||||
where('EXISTS (?)', MergeRequestDiff.select(1).where('merge_requests.latest_merge_request_diff_id = merge_request_diffs.id').by_commit_sha(sha)).reorder(nil)
|
||||
end
|
||||
scope :by_merge_commit_sha, ->(sha) do
|
||||
|
|
@ -348,6 +354,11 @@ class MergeRequest < ApplicationRecord
|
|||
from_union([by_squash_commit_sha(sha), by_merge_commit_sha(sha), by_merged_commit_sha(sha)])
|
||||
end
|
||||
scope :by_related_commit_sha, ->(sha) do
|
||||
Gitlab::AppLogger.info(
|
||||
event: 'merge_request_by_related_commit_sha_call',
|
||||
message: "MergeRequest.by_related_commit_sha called via #{caller_locations.reject { |line| line.path.include?('/gems/') }.first}"
|
||||
)
|
||||
|
||||
from_union(
|
||||
[
|
||||
by_commit_sha(sha),
|
||||
|
|
@ -2454,6 +2465,12 @@ class MergeRequest < ApplicationRecord
|
|||
|
||||
delegate :squash_always?, :squash_never?, :squash_enabled_by_default?, :squash_readonly?, to: :squash_option
|
||||
|
||||
def reached_versions_limit?
|
||||
return false if Feature.disabled?(:merge_requests_diffs_limit, target_project)
|
||||
|
||||
merge_request_diffs.count >= DIFF_VERSION_LIMIT
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def merge_base_pipelines
|
||||
|
|
|
|||
|
|
@ -75,6 +75,11 @@ class MergeRequestDiff < ApplicationRecord
|
|||
scope :viewable, -> { without_state(:empty) }
|
||||
scope :by_head_commit_sha, ->(sha) { where(head_commit_sha: sha) }
|
||||
scope :by_commit_sha, ->(sha) do
|
||||
Gitlab::AppLogger.info(
|
||||
event: 'merge_request_diff_by_commit_sha_call',
|
||||
message: "MergeRequestDiff.by_commit_sha called via #{caller_locations.reject { |line| line.path.include?('/gems/') }.first}"
|
||||
)
|
||||
|
||||
joins(:merge_request_diff_commits).where(merge_request_diff_commits: { sha: sha }).reorder(nil)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ class MergeRequestDiffCommit < ApplicationRecord
|
|||
def message
|
||||
Gitlab::AppLogger.info(
|
||||
event: 'mrdc_message_method',
|
||||
message: "mrdc#message called via #{caller_locations(2, 1).first.path}"
|
||||
message: "mrdc#message called via #{caller_locations.reject { |line| line.path.include?('/gems/') }.first}"
|
||||
)
|
||||
|
||||
if ::Feature.enabled?(:disable_message_attribute_on_mr_diff_commits, project)
|
||||
|
|
|
|||
|
|
@ -50,3 +50,5 @@ class Namespace::PackageSetting < ApplicationRecord
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
Namespace::PackageSetting.prepend_mod
|
||||
|
|
|
|||
|
|
@ -2613,6 +2613,7 @@ class Project < ApplicationRecord
|
|||
.append(key: 'CI_PROJECT_PATH', value: full_path)
|
||||
.append(key: 'CI_PROJECT_PATH_SLUG', value: full_path_slug)
|
||||
.append(key: 'CI_PROJECT_NAMESPACE', value: namespace.full_path)
|
||||
.append(key: 'CI_PROJECT_NAMESPACE_SLUG', value: Gitlab::Utils.slugify(namespace.full_path))
|
||||
.append(key: 'CI_PROJECT_NAMESPACE_ID', value: namespace.id.to_s)
|
||||
.append(key: 'CI_PROJECT_ROOT_NAMESPACE', value: namespace.root_ancestor.path)
|
||||
.append(key: 'CI_PROJECT_URL', value: web_url)
|
||||
|
|
|
|||
|
|
@ -901,9 +901,13 @@ class Repository
|
|||
options[:start_repository] = start_project.repository.raw_repository
|
||||
end
|
||||
|
||||
skip_target_sha = options.delete(:skip_target_sha)
|
||||
unless skip_target_sha
|
||||
options[:target_sha] = self.commit(options[:branch_name])&.sha
|
||||
if Feature.enabled?(:commit_files_target_sha, project)
|
||||
options[:target_sha] = self.commit(options[:branch_name])&.sha || blank_ref
|
||||
else
|
||||
skip_target_sha = options.delete(:skip_target_sha)
|
||||
unless skip_target_sha
|
||||
options[:target_sha] = self.commit(options[:branch_name])&.sha
|
||||
end
|
||||
end
|
||||
|
||||
with_cache_hooks { raw.commit_files(user, **options) }
|
||||
|
|
|
|||
|
|
@ -13,6 +13,11 @@ class BasePolicy < DeclarativePolicy::Base
|
|||
end
|
||||
end
|
||||
|
||||
desc "The current instance is a GitLab Dedicated instance"
|
||||
condition :gitlab_dedicated do
|
||||
Gitlab::CurrentSettings.gitlab_dedicated_instance?
|
||||
end
|
||||
|
||||
desc "User is blocked"
|
||||
with_options scope: :user, score: 0
|
||||
condition(:blocked) { @user&.blocked? }
|
||||
|
|
@ -92,6 +97,10 @@ class BasePolicy < DeclarativePolicy::Base
|
|||
enable :change_repository_storage
|
||||
end
|
||||
|
||||
rule { gitlab_dedicated & admin }.policy do
|
||||
enable :read_dedicated_hosted_runner_usage
|
||||
end
|
||||
|
||||
rule { default }.enable :read_cross_project
|
||||
|
||||
condition(:is_gitlab_com, score: 0, scope: :global) { ::Gitlab.com? }
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@ module MergeRequests
|
|||
|
||||
def execute
|
||||
old_diff_refs = merge_request.diff_refs
|
||||
|
||||
return if merge_request.reached_versions_limit?
|
||||
|
||||
new_diff = merge_request.create_merge_request_diff
|
||||
|
||||
clear_cache(new_diff)
|
||||
|
|
|
|||
|
|
@ -47,8 +47,14 @@ module Namespaces
|
|||
end
|
||||
|
||||
def package_settings_params
|
||||
@params.slice(*ALLOWED_ATTRIBUTES)
|
||||
@params.slice(*allowed_attributes)
|
||||
end
|
||||
|
||||
def allowed_attributes
|
||||
ALLOWED_ATTRIBUTES
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Namespaces::PackageSettings::UpdateService.prepend_mod
|
||||
|
|
|
|||
|
|
@ -126,6 +126,8 @@ module Snippets
|
|||
end
|
||||
|
||||
def commit_attrs(snippet, msg)
|
||||
return super if Feature.enabled?(:commit_files_target_sha, snippet.project)
|
||||
|
||||
super.merge(skip_target_sha: true)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
name: commit_files_target_sha
|
||||
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/517122
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/181459
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/520058
|
||||
milestone: '17.10'
|
||||
group: group::source code
|
||||
type: gitlab_com_derisk
|
||||
default_enabled: false
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
name: merge_requests_diffs_limit
|
||||
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/517497
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/183063
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/521970
|
||||
milestone: '17.10'
|
||||
group: group::source code
|
||||
type: gitlab_com_derisk
|
||||
default_enabled: false
|
||||
|
|
@ -8,14 +8,6 @@ description: Keeps approval merge request rules
|
|||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/8497
|
||||
milestone: '11.7'
|
||||
gitlab_schema: gitlab_main_cell
|
||||
desired_sharding_key:
|
||||
project_id:
|
||||
references: projects
|
||||
backfill_via:
|
||||
parent:
|
||||
foreign_key: merge_request_id
|
||||
table: merge_requests
|
||||
sharding_key: target_project_id
|
||||
belongs_to: merge_request
|
||||
desired_sharding_key_migration_job_name: BackfillApprovalMergeRequestRulesProjectId
|
||||
table_size: medium
|
||||
sharding_key:
|
||||
project_id: projects
|
||||
|
|
|
|||
|
|
@ -17,5 +17,4 @@ desired_sharding_key:
|
|||
table: approval_merge_request_rules
|
||||
sharding_key: project_id
|
||||
belongs_to: approval_merge_request_rule
|
||||
awaiting_backfill_on_parent: true
|
||||
table_size: small
|
||||
|
|
|
|||
|
|
@ -17,5 +17,4 @@ desired_sharding_key:
|
|||
table: approval_merge_request_rules
|
||||
sharding_key: project_id
|
||||
belongs_to: approval_merge_request_rule
|
||||
awaiting_backfill_on_parent: true
|
||||
table_size: large
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
migration_job_name: BackfillScanResultPoliciesNamespaceId
|
||||
description: Backfills sharding key `scan_result_policies.namespace_id` from `security_orchestration_policy_configurations`.
|
||||
feature_category: security_policy_management
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/183125
|
||||
milestone: '17.10'
|
||||
queued_migration_version: 20250301125858
|
||||
finalized_by: # version of the migration that finalized this BBM
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
migration_job_name: BackfillScanResultPoliciesProjectId
|
||||
description: Backfills sharding key `scan_result_policies.project_id` from `security_orchestration_policy_configurations`.
|
||||
feature_category: security_policy_management
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/183125
|
||||
milestone: '17.10'
|
||||
queued_migration_version: 20250301125534
|
||||
finalized_by: # version of the migration that finalized this BBM
|
||||
|
|
@ -26,3 +26,6 @@ desired_sharding_key:
|
|||
sharding_key: namespace_id
|
||||
belongs_to: security_orchestration_policy_configuration
|
||||
table_size: small
|
||||
desired_sharding_key_migration_job_name:
|
||||
- BackfillScanResultPoliciesProjectId
|
||||
- BackfillScanResultPoliciesNamespaceId
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddAuditEventsEnabledToNamespacePackageSettings < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.10'
|
||||
|
||||
def up
|
||||
add_column :namespace_package_settings, :audit_events_enabled, :boolean, default: false, null: false,
|
||||
if_not_exists: true
|
||||
end
|
||||
|
||||
def down
|
||||
remove_column :namespace_package_settings, :audit_events_enabled, if_exists: true
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddBillingMonthYearIndex < Gitlab::Database::Migration[2.2]
|
||||
disable_ddl_transaction!
|
||||
milestone '17.10'
|
||||
|
||||
INDEX_NAME = 'idx_gitlab_hosted_runner_monthly_usages_on_billing_month_year'
|
||||
|
||||
def up
|
||||
add_concurrent_index :ci_gitlab_hosted_runner_monthly_usages, "EXTRACT(YEAR FROM billing_month)", name: INDEX_NAME,
|
||||
using: :btree
|
||||
end
|
||||
|
||||
def down
|
||||
remove_concurrent_index_by_name :ci_gitlab_hosted_runner_monthly_usages, name: INDEX_NAME
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddNamespaceIdToScanResultPolicies < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.10'
|
||||
|
||||
def change
|
||||
add_column :scan_result_policies, :namespace_id, :bigint
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ValidateApprovalMergeRequestRulesProjectIdNotNullConstraint < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.10'
|
||||
|
||||
def up
|
||||
validate_not_null_constraint :approval_merge_request_rules, :project_id
|
||||
end
|
||||
|
||||
def down
|
||||
# no-op
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddScanResultPoliciesProjectIdTrigger < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.10'
|
||||
|
||||
def up
|
||||
install_sharding_key_assignment_trigger(
|
||||
table: :scan_result_policies,
|
||||
sharding_key: :project_id,
|
||||
parent_table: :security_orchestration_policy_configurations,
|
||||
parent_sharding_key: :project_id,
|
||||
foreign_key: :security_orchestration_policy_configuration_id
|
||||
)
|
||||
end
|
||||
|
||||
def down
|
||||
remove_sharding_key_assignment_trigger(
|
||||
table: :scan_result_policies,
|
||||
sharding_key: :project_id,
|
||||
parent_table: :security_orchestration_policy_configurations,
|
||||
parent_sharding_key: :project_id,
|
||||
foreign_key: :security_orchestration_policy_configuration_id
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class QueueBackfillScanResultPoliciesProjectId < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.10'
|
||||
restrict_gitlab_migration gitlab_schema: :gitlab_main_cell
|
||||
|
||||
MIGRATION = "BackfillScanResultPoliciesProjectId"
|
||||
DELAY_INTERVAL = 2.minutes
|
||||
BATCH_SIZE = 1000
|
||||
SUB_BATCH_SIZE = 100
|
||||
|
||||
def up
|
||||
queue_batched_background_migration(
|
||||
MIGRATION,
|
||||
:scan_result_policies,
|
||||
:id,
|
||||
:project_id,
|
||||
:security_orchestration_policy_configurations,
|
||||
:project_id,
|
||||
:security_orchestration_policy_configuration_id,
|
||||
job_interval: DELAY_INTERVAL,
|
||||
batch_size: BATCH_SIZE,
|
||||
sub_batch_size: SUB_BATCH_SIZE
|
||||
)
|
||||
end
|
||||
|
||||
def down
|
||||
delete_batched_background_migration(
|
||||
MIGRATION,
|
||||
:scan_result_policies,
|
||||
:id,
|
||||
[
|
||||
:project_id,
|
||||
:security_orchestration_policy_configurations,
|
||||
:project_id,
|
||||
:security_orchestration_policy_configuration_id
|
||||
]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class IndexScanResultPoliciesOnNamespaceId < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.10'
|
||||
disable_ddl_transaction!
|
||||
|
||||
INDEX_NAME = 'index_scan_result_policies_on_namespace_id'
|
||||
|
||||
def up
|
||||
add_concurrent_index :scan_result_policies, :namespace_id, name: INDEX_NAME
|
||||
end
|
||||
|
||||
def down
|
||||
remove_concurrent_index_by_name :scan_result_policies, INDEX_NAME
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddScanResultPoliciesNamespaceIdFk < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.10'
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
add_concurrent_foreign_key :scan_result_policies, :namespaces, column: :namespace_id, on_delete: :cascade
|
||||
end
|
||||
|
||||
def down
|
||||
with_lock_retries do
|
||||
remove_foreign_key :scan_result_policies, column: :namespace_id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddScanResultPoliciesNamespaceIdTrigger < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.10'
|
||||
|
||||
def up
|
||||
install_sharding_key_assignment_trigger(
|
||||
table: :scan_result_policies,
|
||||
sharding_key: :namespace_id,
|
||||
parent_table: :security_orchestration_policy_configurations,
|
||||
parent_sharding_key: :namespace_id,
|
||||
foreign_key: :security_orchestration_policy_configuration_id
|
||||
)
|
||||
end
|
||||
|
||||
def down
|
||||
remove_sharding_key_assignment_trigger(
|
||||
table: :scan_result_policies,
|
||||
sharding_key: :namespace_id,
|
||||
parent_table: :security_orchestration_policy_configurations,
|
||||
parent_sharding_key: :namespace_id,
|
||||
foreign_key: :security_orchestration_policy_configuration_id
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class QueueBackfillScanResultPoliciesNamespaceId < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.10'
|
||||
restrict_gitlab_migration gitlab_schema: :gitlab_main_cell
|
||||
|
||||
MIGRATION = "BackfillScanResultPoliciesNamespaceId"
|
||||
DELAY_INTERVAL = 2.minutes
|
||||
BATCH_SIZE = 1000
|
||||
SUB_BATCH_SIZE = 100
|
||||
|
||||
def up
|
||||
queue_batched_background_migration(
|
||||
MIGRATION,
|
||||
:scan_result_policies,
|
||||
:id,
|
||||
:namespace_id,
|
||||
:security_orchestration_policy_configurations,
|
||||
:namespace_id,
|
||||
:security_orchestration_policy_configuration_id,
|
||||
job_interval: DELAY_INTERVAL,
|
||||
batch_size: BATCH_SIZE,
|
||||
sub_batch_size: SUB_BATCH_SIZE
|
||||
)
|
||||
end
|
||||
|
||||
def down
|
||||
delete_batched_background_migration(
|
||||
MIGRATION,
|
||||
:scan_result_policies,
|
||||
:id,
|
||||
[
|
||||
:namespace_id,
|
||||
:security_orchestration_policy_configurations,
|
||||
:namespace_id,
|
||||
:security_orchestration_policy_configuration_id
|
||||
]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
93e562375a953780fe30c5ef8781f6a78f5fcb0de8ad77021dbdb2e846f2f016
|
||||
|
|
@ -0,0 +1 @@
|
|||
77fa54ab6762eb8c9ba172d6bbfdf7d51f599445a06b2d2b60f206e0c19ccd83
|
||||
|
|
@ -0,0 +1 @@
|
|||
80718abeb6da1c012b1b339f5ad3e57746cffb0473185f95d37edb4b76fb494a
|
||||
|
|
@ -0,0 +1 @@
|
|||
56f1db3bdeea1aeef9df49e501eb7e1dac093f18f05a4e07172cb4bbd55ceecd
|
||||
|
|
@ -0,0 +1 @@
|
|||
3226c5fca1dd5555283876ef828ba17e805a246ee2e441d4d05498edfc735e2e
|
||||
|
|
@ -0,0 +1 @@
|
|||
3a0f04fc4a380d6617e65f9d39dfab44de21cc5584b54c5857ea46e15250561e
|
||||
|
|
@ -0,0 +1 @@
|
|||
35b534dc4a99b72d70f522fba4cbf4b624cd2ec01439ea13656e72f9204a48f9
|
||||
|
|
@ -0,0 +1 @@
|
|||
8352e0e9e20603bdb7e4fccac26214043c30d8e34dbe8b8b8a998a1716865adb
|
||||
|
|
@ -0,0 +1 @@
|
|||
f152eb71fe1e65c715bdd5341625103e799e6dbf76f13a0c344179770157cdc9
|
||||
|
|
@ -0,0 +1 @@
|
|||
1f93c1cf8cc282f62a840707a186c9b78eea50ab89511a5c838b5c4226b86a00
|
||||
|
|
@ -1990,6 +1990,22 @@ RETURN NEW;
|
|||
END
|
||||
$$;
|
||||
|
||||
CREATE FUNCTION trigger_4c320a13bc8d() RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
BEGIN
|
||||
IF NEW."project_id" IS NULL THEN
|
||||
SELECT "project_id"
|
||||
INTO NEW."project_id"
|
||||
FROM "security_orchestration_policy_configurations"
|
||||
WHERE "security_orchestration_policy_configurations"."id" = NEW."security_orchestration_policy_configuration_id";
|
||||
END IF;
|
||||
|
||||
RETURN NEW;
|
||||
|
||||
END
|
||||
$$;
|
||||
|
||||
CREATE FUNCTION trigger_4cc5c3ac4d7f() RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
|
|
@ -3171,6 +3187,22 @@ RETURN NEW;
|
|||
END
|
||||
$$;
|
||||
|
||||
CREATE FUNCTION trigger_b83b7e51e2f5() RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
BEGIN
|
||||
IF NEW."namespace_id" IS NULL THEN
|
||||
SELECT "namespace_id"
|
||||
INTO NEW."namespace_id"
|
||||
FROM "security_orchestration_policy_configurations"
|
||||
WHERE "security_orchestration_policy_configurations"."id" = NEW."security_orchestration_policy_configuration_id";
|
||||
END IF;
|
||||
|
||||
RETURN NEW;
|
||||
|
||||
END
|
||||
$$;
|
||||
|
||||
CREATE FUNCTION trigger_b8eecea7f351() RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
|
|
@ -8597,6 +8629,7 @@ CREATE TABLE approval_merge_request_rules (
|
|||
role_approvers integer[] DEFAULT '{}'::integer[] NOT NULL,
|
||||
approval_policy_action_idx smallint DEFAULT 0 NOT NULL,
|
||||
CONSTRAINT check_6fca5928b2 CHECK ((char_length(section) <= 255)),
|
||||
CONSTRAINT check_90caab37e0 CHECK ((project_id IS NOT NULL)),
|
||||
CONSTRAINT check_approval_m_r_rules_allowed_role_approvers_valid_entries CHECK (((role_approvers = '{}'::integer[]) OR (role_approvers <@ ARRAY[20, 30, 40, 50, 60])))
|
||||
);
|
||||
|
||||
|
|
@ -16925,6 +16958,7 @@ CREATE TABLE namespace_package_settings (
|
|||
nuget_symbol_server_enabled boolean DEFAULT false NOT NULL,
|
||||
terraform_module_duplicates_allowed boolean DEFAULT false NOT NULL,
|
||||
terraform_module_duplicate_exception_regex text DEFAULT ''::text NOT NULL,
|
||||
audit_events_enabled boolean DEFAULT false NOT NULL,
|
||||
CONSTRAINT check_31340211b1 CHECK ((char_length(generic_duplicate_exception_regex) <= 255)),
|
||||
CONSTRAINT check_d63274b2b6 CHECK ((char_length(maven_duplicate_exception_regex) <= 255)),
|
||||
CONSTRAINT check_eedcf85c48 CHECK ((char_length(nuget_duplicate_exception_regex) <= 255)),
|
||||
|
|
@ -21177,6 +21211,7 @@ CREATE TABLE scan_result_policies (
|
|||
action_idx smallint DEFAULT 0 NOT NULL,
|
||||
custom_roles bigint[] DEFAULT '{}'::bigint[] NOT NULL,
|
||||
licenses jsonb DEFAULT '{}'::jsonb NOT NULL,
|
||||
namespace_id bigint,
|
||||
CONSTRAINT age_value_null_or_positive CHECK (((age_value IS NULL) OR (age_value >= 0))),
|
||||
CONSTRAINT check_scan_result_policies_rule_idx_positive CHECK (((rule_idx IS NULL) OR (rule_idx >= 0))),
|
||||
CONSTRAINT custom_roles_array_check CHECK ((array_position(custom_roles, NULL::bigint) IS NULL))
|
||||
|
|
@ -27358,9 +27393,6 @@ ALTER TABLE ONLY project_type_ci_runners_e59bb2812d
|
|||
ALTER TABLE ONLY group_type_ci_runners_e59bb2812d
|
||||
ADD CONSTRAINT check_81b90172a6 UNIQUE (id);
|
||||
|
||||
ALTER TABLE approval_merge_request_rules
|
||||
ADD CONSTRAINT check_90caab37e0 CHECK ((project_id IS NOT NULL)) NOT VALID;
|
||||
|
||||
ALTER TABLE approvals
|
||||
ADD CONSTRAINT check_9da7c942dc CHECK ((project_id IS NOT NULL)) NOT VALID;
|
||||
|
||||
|
|
@ -31123,6 +31155,8 @@ CREATE UNIQUE INDEX idx_external_audit_event_destination_id_key_uniq ON audit_ev
|
|||
|
||||
CREATE INDEX idx_external_status_checks_on_id_and_project_id ON external_status_checks USING btree (id, project_id);
|
||||
|
||||
CREATE INDEX idx_gitlab_hosted_runner_monthly_usages_on_billing_month_year ON ci_gitlab_hosted_runner_monthly_usages USING btree (EXTRACT(year FROM billing_month));
|
||||
|
||||
CREATE INDEX idx_gpg_keys_on_user_externally_verified ON gpg_keys USING btree (user_id) WHERE (externally_verified = true);
|
||||
|
||||
CREATE INDEX idx_group_audit_events_on_author_id_created_at_id ON ONLY group_audit_events USING btree (author_id, created_at, id);
|
||||
|
|
@ -35045,6 +35079,8 @@ CREATE UNIQUE INDEX index_scan_execution_policy_rules_on_unique_policy_rule_inde
|
|||
|
||||
CREATE UNIQUE INDEX index_scan_result_policies_on_configuration_action_and_rule_idx ON scan_result_policies USING btree (security_orchestration_policy_configuration_id, project_id, orchestration_policy_idx, rule_idx, action_idx);
|
||||
|
||||
CREATE INDEX index_scan_result_policies_on_namespace_id ON scan_result_policies USING btree (namespace_id);
|
||||
|
||||
CREATE INDEX index_scan_result_policies_on_project_id ON scan_result_policies USING btree (project_id);
|
||||
|
||||
CREATE INDEX index_scan_result_policy_violations_on_approval_policy_rule_id ON scan_result_policy_violations USING btree (approval_policy_rule_id);
|
||||
|
|
@ -38485,6 +38521,8 @@ CREATE TRIGGER trigger_4ad9a52a6614 BEFORE INSERT OR UPDATE ON sbom_occurrences_
|
|||
|
||||
CREATE TRIGGER trigger_4b43790d717f BEFORE INSERT OR UPDATE ON protected_environment_approval_rules FOR EACH ROW EXECUTE FUNCTION trigger_4b43790d717f();
|
||||
|
||||
CREATE TRIGGER trigger_4c320a13bc8d BEFORE INSERT OR UPDATE ON scan_result_policies FOR EACH ROW EXECUTE FUNCTION trigger_4c320a13bc8d();
|
||||
|
||||
CREATE TRIGGER trigger_4cc5c3ac4d7f BEFORE INSERT OR UPDATE ON bulk_import_export_uploads FOR EACH ROW EXECUTE FUNCTION trigger_4cc5c3ac4d7f();
|
||||
|
||||
CREATE TRIGGER trigger_4dc8ec48e038 BEFORE INSERT OR UPDATE ON requirements_management_test_reports FOR EACH ROW EXECUTE FUNCTION trigger_4dc8ec48e038();
|
||||
|
|
@ -38637,6 +38675,8 @@ CREATE TRIGGER trigger_b75e5731e305 BEFORE INSERT OR UPDATE ON dast_profiles_pip
|
|||
|
||||
CREATE TRIGGER trigger_b7abb8fc4cf0 BEFORE INSERT OR UPDATE ON work_item_progresses FOR EACH ROW EXECUTE FUNCTION trigger_b7abb8fc4cf0();
|
||||
|
||||
CREATE TRIGGER trigger_b83b7e51e2f5 BEFORE INSERT OR UPDATE ON scan_result_policies FOR EACH ROW EXECUTE FUNCTION trigger_b83b7e51e2f5();
|
||||
|
||||
CREATE TRIGGER trigger_b8eecea7f351 BEFORE INSERT OR UPDATE ON dependency_proxy_manifest_states FOR EACH ROW EXECUTE FUNCTION trigger_b8eecea7f351();
|
||||
|
||||
CREATE TRIGGER trigger_b9839c6d713f BEFORE INSERT ON application_settings FOR EACH ROW EXECUTE FUNCTION function_for_trigger_b9839c6d713f();
|
||||
|
|
@ -39810,6 +39850,9 @@ ALTER TABLE ONLY push_rules
|
|||
ALTER TABLE ONLY merge_request_diffs
|
||||
ADD CONSTRAINT fk_8483f3258f FOREIGN KEY (merge_request_id) REFERENCES merge_requests(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY scan_result_policies
|
||||
ADD CONSTRAINT fk_84d4bc9abe FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY requirements
|
||||
ADD CONSTRAINT fk_85044baef0 FOREIGN KEY (issue_id) REFERENCES issues(id) ON DELETE CASCADE;
|
||||
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
|
@ -61,7 +61,7 @@ The banner can be customized with a specific message.
|
|||
|
||||
An error is displayed when a user tries to perform a write operation that isn't allowed.
|
||||
|
||||

|
||||

|
||||
|
||||
{{< alert type="note" >}}
|
||||
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
|
@ -17,7 +17,7 @@ You can analyze your users' GitLab activities over time.
|
|||
How do you interpret the user cohorts table? Let's review an example with the
|
||||
following user cohorts:
|
||||
|
||||

|
||||

|
||||
|
||||
For the cohort of March 2020, three users were added to this server and have
|
||||
been active since this month. One month later (April 2020), two users are still
|
||||
|
|
|
|||
|
|
@ -409,6 +409,12 @@ Returns [`CiConfig`](#ciconfig).
|
|||
| <a id="queryciconfigsha"></a>`sha` | [`String`](#string) | Sha for the pipeline. |
|
||||
| <a id="queryciconfigskipverifyprojectsha"></a>`skipVerifyProjectSha` {{< icon name="warning-solid" >}} | [`Boolean`](#boolean) | **Introduced** in GitLab 16.5. **Status**: Experiment. If the provided `sha` is found in the project's repository but is not associated with a Git reference (a detached commit), the verification fails and a validation error is returned. Otherwise, verification passes, even if the `sha` is invalid. Set to `true` to skip this verification process. |
|
||||
|
||||
### `Query.ciDedicatedHostedRunnerFilters`
|
||||
|
||||
Returns available filters for GitLab Dedicated runner usage data.
|
||||
|
||||
Returns [`CiDedicatedHostedRunnerFilters`](#cidedicatedhostedrunnerfilters).
|
||||
|
||||
### `Query.ciDedicatedHostedRunnerUsage`
|
||||
|
||||
Compute usage data for runners across namespaces on GitLab Dedicated. Defaults to the current year if no year or billing month is specified. Ultimate only.
|
||||
|
|
@ -11400,6 +11406,7 @@ Input type: `UpdateNamespacePackageSettingsInput`
|
|||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="mutationupdatenamespacepackagesettingsauditeventsenabled"></a>`auditEventsEnabled` {{< icon name="warning-solid" >}} | [`Boolean`](#boolean) | **Deprecated:** **Status**: Experiment. Introduced in GitLab 17.10. |
|
||||
| <a id="mutationupdatenamespacepackagesettingsclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
|
||||
| <a id="mutationupdatenamespacepackagesettingsgenericduplicateexceptionregex"></a>`genericDuplicateExceptionRegex` | [`UntrustedRegexp`](#untrustedregexp) | When generic_duplicates_allowed is false, you can publish duplicate packages with names that match this regex. Otherwise, this setting has no effect. |
|
||||
| <a id="mutationupdatenamespacepackagesettingsgenericduplicatesallowed"></a>`genericDuplicatesAllowed` | [`Boolean`](#boolean) | Indicates whether duplicate generic packages are allowed for this namespace. |
|
||||
|
|
@ -11413,7 +11420,7 @@ Input type: `UpdateNamespacePackageSettingsInput`
|
|||
| <a id="mutationupdatenamespacepackagesettingsnpmpackagerequestsforwarding"></a>`npmPackageRequestsForwarding` | [`Boolean`](#boolean) | Indicates whether npm package forwarding is allowed for this namespace. |
|
||||
| <a id="mutationupdatenamespacepackagesettingsnugetduplicateexceptionregex"></a>`nugetDuplicateExceptionRegex` | [`UntrustedRegexp`](#untrustedregexp) | When nuget_duplicates_allowed is false, you can publish duplicate packages with names that match this regex. Otherwise, this setting has no effect. |
|
||||
| <a id="mutationupdatenamespacepackagesettingsnugetduplicatesallowed"></a>`nugetDuplicatesAllowed` | [`Boolean`](#boolean) | Indicates whether duplicate NuGet packages are allowed for this namespace. |
|
||||
| <a id="mutationupdatenamespacepackagesettingsnugetsymbolserverenabled"></a>`nugetSymbolServerEnabled` | [`Boolean`](#boolean) | Indicates wheather the NuGet symbol server is enabled for this namespace. |
|
||||
| <a id="mutationupdatenamespacepackagesettingsnugetsymbolserverenabled"></a>`nugetSymbolServerEnabled` | [`Boolean`](#boolean) | Indicates whether the NuGet symbol server is enabled for this namespace. |
|
||||
| <a id="mutationupdatenamespacepackagesettingspypipackagerequestsforwarding"></a>`pypiPackageRequestsForwarding` | [`Boolean`](#boolean) | Indicates whether PyPI package forwarding is allowed for this namespace. |
|
||||
| <a id="mutationupdatenamespacepackagesettingsterraformmoduleduplicateexceptionregex"></a>`terraformModuleDuplicateExceptionRegex` | [`UntrustedRegexp`](#untrustedregexp) | When terraform_module_duplicates_allowed is false, you can publish duplicate packages with names that match this regex. Otherwise, this setting has no effect. |
|
||||
| <a id="mutationupdatenamespacepackagesettingsterraformmoduleduplicatesallowed"></a>`terraformModuleDuplicatesAllowed` | [`Boolean`](#boolean) | Indicates whether duplicate Terraform packages are allowed for this namespace. |
|
||||
|
|
@ -21732,6 +21739,17 @@ CI/CD config variables.
|
|||
| <a id="ciconfigvariablevalue"></a>`value` | [`String`](#string) | Value of the variable. |
|
||||
| <a id="ciconfigvariablevalueoptions"></a>`valueOptions` | [`[String!]`](#string) | Value options for the variable. |
|
||||
|
||||
### `CiDedicatedHostedRunnerFilters`
|
||||
|
||||
Filter options available for GitLab Dedicated runner usage data.
|
||||
|
||||
#### Fields
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="cidedicatedhostedrunnerfiltersrunners"></a>`runners` | [`CiRunnerConnection`](#cirunnerconnection) | List of unique runners with usage data. (see [Connections](#connections)) |
|
||||
| <a id="cidedicatedhostedrunnerfiltersyears"></a>`years` | [`[Int!]`](#int) | List of years with available usage data. |
|
||||
|
||||
### `CiDedicatedHostedRunnerUsage`
|
||||
|
||||
Compute usage data for hosted runners on GitLab Dedicated.
|
||||
|
|
@ -32641,6 +32659,7 @@ Namespace-level Package Registry settings.
|
|||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="packagesettingsauditeventsenabled"></a>`auditEventsEnabled` {{< icon name="warning-solid" >}} | [`Boolean`](#boolean) | **Introduced** in GitLab 17.10. **Status**: Experiment. Indicates whether audit events are created when publishing or deleting a package in the namespace (Premium and Ultimate only). Returns `null` if `package_registry_audit_events` feature flag is disabled. |
|
||||
| <a id="packagesettingsgenericduplicateexceptionregex"></a>`genericDuplicateExceptionRegex` | [`UntrustedRegexp`](#untrustedregexp) | When generic_duplicates_allowed is false, you can publish duplicate packages with names that match this regex. Otherwise, this setting has no effect. |
|
||||
| <a id="packagesettingsgenericduplicatesallowed"></a>`genericDuplicatesAllowed` | [`Boolean!`](#boolean) | Indicates whether duplicate generic packages are allowed for this namespace. |
|
||||
| <a id="packagesettingslockmavenpackagerequestsforwarding"></a>`lockMavenPackageRequestsForwarding` | [`Boolean!`](#boolean) | Indicates whether Maven package forwarding is locked for all descendent namespaces. |
|
||||
|
|
@ -32654,7 +32673,7 @@ Namespace-level Package Registry settings.
|
|||
| <a id="packagesettingsnpmpackagerequestsforwardinglocked"></a>`npmPackageRequestsForwardingLocked` | [`Boolean!`](#boolean) | Indicates whether npm package forwarding settings are locked by a parent namespace. |
|
||||
| <a id="packagesettingsnugetduplicateexceptionregex"></a>`nugetDuplicateExceptionRegex` | [`UntrustedRegexp`](#untrustedregexp) | When nuget_duplicates_allowed is false, you can publish duplicate packages with names that match this regex. Otherwise, this setting has no effect. |
|
||||
| <a id="packagesettingsnugetduplicatesallowed"></a>`nugetDuplicatesAllowed` | [`Boolean!`](#boolean) | Indicates whether duplicate NuGet packages are allowed for this namespace. |
|
||||
| <a id="packagesettingsnugetsymbolserverenabled"></a>`nugetSymbolServerEnabled` | [`Boolean!`](#boolean) | Indicates wheather the NuGet symbol server is enabled for this namespace. |
|
||||
| <a id="packagesettingsnugetsymbolserverenabled"></a>`nugetSymbolServerEnabled` | [`Boolean!`](#boolean) | Indicates whether the NuGet symbol server is enabled for this namespace. |
|
||||
| <a id="packagesettingspypipackagerequestsforwarding"></a>`pypiPackageRequestsForwarding` | [`Boolean`](#boolean) | Indicates whether PyPI package forwarding is allowed for this namespace. |
|
||||
| <a id="packagesettingspypipackagerequestsforwardinglocked"></a>`pypiPackageRequestsForwardingLocked` | [`Boolean!`](#boolean) | Indicates whether PyPI package forwarding settings are locked by a parent namespace. |
|
||||
| <a id="packagesettingsterraformmoduleduplicateexceptionregex"></a>`terraformModuleDuplicateExceptionRegex` | [`UntrustedRegexp`](#untrustedregexp) | When terraform_module_duplicates_allowed is false, you can publish duplicate packages with names that match this regex. Otherwise, this setting has no effect. |
|
||||
|
|
|
|||
|
|
@ -30,6 +30,16 @@ in GitLab 15.0. Iterating pages of results with a number (`?page=2`) is unsuppor
|
|||
|
||||
{{< /alert >}}
|
||||
|
||||
{{< alert type="warning" >}}
|
||||
|
||||
In version 17.7, the error handling behavior when a requested path is not found is updated.
|
||||
The endpoint now returns a status code `404 Not Found`. Previously, the status code was `200 OK`.
|
||||
|
||||
If your implementation relies on receiving a `200` status code with an empty array for
|
||||
missing paths, you must update your error handling to handle the new `404` responses.
|
||||
|
||||
{{< /alert >}}
|
||||
|
||||
```plaintext
|
||||
GET /projects/:id/repository/tree
|
||||
```
|
||||
|
|
|
|||
|
|
@ -44,7 +44,11 @@ There are a few ways to view a list of environments for a given project:
|
|||
|
||||

|
||||
|
||||
Deployments show up in this list only after a deployment job has created them.
|
||||
Deployments show up in this list only after a deployment job has created them.
|
||||
|
||||
- To view a list of all manual jobs in a deployment pipeline, select the **Run** ({{< icon name="play" >}}) dropdown list.
|
||||
|
||||

|
||||
|
||||
### Environment URL
|
||||
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 21 KiB |
|
|
@ -27,6 +27,7 @@ These types of pipelines all appear on the **Pipelines** tab of a merge request.
|
|||
Your pipeline can run every time you commit changes to a branch.
|
||||
|
||||
This type of pipeline is called a *branch pipeline*.
|
||||
They display a `branch` label in pipeline lists.
|
||||
|
||||
This pipeline runs by default. No configuration is required.
|
||||
|
||||
|
|
@ -43,6 +44,7 @@ Branch pipelines:
|
|||
A pipeline can run every time you create or push a new [tag](../../user/project/repository/tags/_index.md).
|
||||
|
||||
This type of pipeline is called a *tag pipeline*.
|
||||
They display a `tag` label in pipeline lists.
|
||||
|
||||
This pipeline runs by default. No configuration is required.
|
||||
|
||||
|
|
@ -60,6 +62,7 @@ Instead of a branch pipeline, you can configure your pipeline to run every time
|
|||
source branch in a merge request.
|
||||
|
||||
This type of pipeline is called a *merge request pipeline*.
|
||||
They display a `merge request` label in pipeline lists.
|
||||
|
||||
Merge request pipelines do not run by default. You must configure
|
||||
the jobs in the `.gitlab-ci.yml` file to run as merge request pipelines.
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@ Predefined variables become available at three different phases of pipeline exec
|
|||
| `CI_PROJECT_NAME` | Pre-pipeline | The name of the directory for the project. For example if the project URL is `gitlab.example.com/group-name/project-1`, `CI_PROJECT_NAME` is `project-1`. |
|
||||
| `CI_PROJECT_NAMESPACE` | Pre-pipeline | The project namespace (username or group name) of the job. |
|
||||
| `CI_PROJECT_NAMESPACE_ID` | Pre-pipeline | The project namespace ID of the job. Introduced in GitLab 15.7. |
|
||||
| `CI_PROJECT_NAMESPACE_SLUG` | Pre-pipeline | `$CI_PROJECT_NAMESPACE` in lowercase with characters that are not `a-z` or `0-9` replaced with - and shortened to 63 bytes. |
|
||||
| `CI_PROJECT_PATH_SLUG` | Pre-pipeline | `$CI_PROJECT_PATH` in lowercase with characters that are not `a-z` or `0-9` replaced with `-` and shortened to 63 bytes. Use in URLs and domain names. |
|
||||
| `CI_PROJECT_PATH` | Pre-pipeline | The project namespace with the project name included. |
|
||||
| `CI_PROJECT_REPOSITORY_LANGUAGES` | Pre-pipeline | A comma-separated, lowercase list of the languages used in the repository. For example `ruby,javascript,html,css`. The maximum number of languages is limited to 5. An issue [proposes to increase the limit](https://gitlab.com/gitlab-org/gitlab/-/issues/368925). |
|
||||
|
|
|
|||
|
|
@ -271,6 +271,7 @@ predicate:
|
|||
CI_PROJECT_ID: '45821955'
|
||||
CI_PROJECT_NAME: npm-provenance-example
|
||||
CI_PROJECT_NAMESPACE: strongjz
|
||||
CI_PROJECT_NAMESPACE_SLUG: strongjz
|
||||
CI_PROJECT_NAMESPACE_ID: '36018'
|
||||
CI_PROJECT_PATH: strongjz/npm-provenance-example
|
||||
CI_PROJECT_PATH_SLUG: strongjz-npm-provenance-example
|
||||
|
|
|
|||
|
|
@ -5,9 +5,61 @@ info: Any user with at least the Maintainer role can merge updates to this conte
|
|||
title: Application secrets
|
||||
---
|
||||
|
||||
This page is a development guide for application secrets.
|
||||
GitLab must be able to access various secrets such as access tokens and other credentials to function.
|
||||
These secrets are encrypted and stored at rest and may be found in different data stores depending on use.
|
||||
Use this guide to understand how different kinds of secrets are stored and managed.
|
||||
|
||||
## Secret entries
|
||||
## Application secrets and operational secrets
|
||||
|
||||
Broadly speaking, there are two classes of secrets:
|
||||
|
||||
1. **Application secrets.** The GitLab application uses these to implement a particular feature or function.
|
||||
An example would be access tokens or private keys to create cryptographic signatures. We store
|
||||
these secrets in the database in encrypted columns.
|
||||
See [Secure Coding Guidelines: At rest](secure_coding_guidelines.md#at-rest).
|
||||
1. **Operational secrets.** Used to read and store other secrets or bootstrap the application. For this reason,
|
||||
they cannot be stored in the database.
|
||||
These secrets are stored as [Rails credentials](https://guides.rubyonrails.org/security.html#environmental-security)
|
||||
in the `config/secrets.yml` file, directly for source installation, or through an installer like Omnibus or Helm (where
|
||||
actual secrets can be stored in an external secrets container like
|
||||
[Kubernetes secrets](https://kubernetes.io/docs/concepts/configuration/secret/) or [Vault](https://www.vaultproject.io/)).
|
||||
|
||||
## Application secrets
|
||||
|
||||
Application secrets should be stored in postgres using `ActiveRecord::Encryption`:
|
||||
|
||||
```ruby
|
||||
class MyModel < ApplicationRecord
|
||||
encrypts :my_secret
|
||||
end
|
||||
```
|
||||
|
||||
{{< alert type="note" >}}
|
||||
Until recently, we used `attr_encrypted` instead of `ActiveRecord::Encryption`. We are in the process of
|
||||
migrating all columns to use the new Rails-native encryption framework (see [epic 15420](https://gitlab.com/groups/gitlab-org/-/epics/15420)).
|
||||
{{< /alert >}}
|
||||
|
||||
{{< alert type="note" >}}
|
||||
Despite there being precedent, application secrets should not be stored as an `ApplicationSetting`.
|
||||
This can lead to the entire application malfunctioning if this secret fails to decode. To reduce
|
||||
coupling to other features, isolate secrets into dedicated tables.
|
||||
{{< /alert >}}
|
||||
|
||||
{{< alert type="note" >}}
|
||||
In some cases, it can be undesirable to store secrets in the database. For example, if the secret is needed
|
||||
to bootstrap the Rails application, it may have to access the database in an initializer, which can lead to
|
||||
initialization races as the database connection itself may not yet be ready. In this case, store the secret
|
||||
as an operational secret instead.
|
||||
{{< /alert >}}
|
||||
|
||||
## Operational secrets
|
||||
|
||||
We maintain a number of operational secrets in `config/secrets.yml`, primarily to manage other secrets. Historically, GitLab
|
||||
used this approach for all secrets, including application secrets, but has meanwhile moved most of these into postgres.
|
||||
The only exception is `openid_connect_signing_key` since it needs to be accessed from a Rails initializer before
|
||||
the database may be ready.
|
||||
|
||||
### Secret entries
|
||||
|
||||
|Entry |Description |
|
||||
|--- |--- |
|
||||
|
|
@ -20,7 +72,7 @@ This page is a development guide for application secrets.
|
|||
| `active_record_encryption_deterministic_key` | The base key to deterministically-encrypt data for `ActiveRecord::Encryption` encrypted columns |
|
||||
| `active_record_encryption_key_derivation_salt` | The derivation salt to encrypt data for `ActiveRecord::Encryption` encrypted columns |
|
||||
|
||||
## Where the secrets are stored
|
||||
### Where the secrets are stored
|
||||
|
||||
|Installation type |Location |
|
||||
|--- |--- |
|
||||
|
|
@ -28,9 +80,9 @@ This page is a development guide for application secrets.
|
|||
| Cloud Native GitLab Charts |[Kubernetes Secrets](https://docs.gitlab.com/charts/installation/secrets.html#gitlab-rails-secret) |
|
||||
| Self-compiled |`<path-to-gitlab-rails>/config/secrets.yml` (Automatically generated by [`config/initializers/01_secret_token.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/initializers/01_secret_token.rb)) |
|
||||
|
||||
## Warning: Before you add a new secret to application secrets
|
||||
### Warning: Before you add a new secret to application secrets
|
||||
|
||||
### Add support to Omnibus GitLab and the Cloud Native GitLab charts
|
||||
#### Add support to Omnibus GitLab and the Cloud Native GitLab charts
|
||||
|
||||
Before you add a new secret to
|
||||
[`config/initializers/01_secret_token.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/initializers/01_secret_token.rb),
|
||||
|
|
@ -45,45 +97,36 @@ have write access.
|
|||
- [Change for Omnibus GitLab installation](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/8026)
|
||||
- [Change for Cloud Native installation](https://gitlab.com/gitlab-org/charts/gitlab/-/merge_requests/3988)
|
||||
|
||||
### Populate the secrets in live environments
|
||||
#### Populate the secrets in live environments
|
||||
|
||||
Additionally, in case you need the secret to have the same value on all nodes (which is usually the case),
|
||||
you need to make sure
|
||||
[it's configured for all live environments (GitLab.com, staging, pre)](https://gitlab.com/gitlab-com/gl-infra/k8s-workloads/gitlab-com/-/blob/master/releases/gitlab-external-secrets/values/values.yaml.gotmpl)
|
||||
prior to changing this file.
|
||||
|
||||
### Document the new secrets
|
||||
#### Document the new secrets
|
||||
|
||||
#### Add the new secrets to this documentation file
|
||||
1. Add the new secrets to this documentation file.
|
||||
1. Mention the new secrets in the next release upgrade notes.
|
||||
For instance, for the 17.8 release, the notes would go in `data/release_posts/17_8/17-8-upgrade.yml` and contain something like the following:
|
||||
|
||||
The new secrets should be documented in `doc/development/application_secrets.md`.
|
||||
```yaml
|
||||
---
|
||||
upgrades:
|
||||
- reporter: <your username> # item author username
|
||||
description: |
|
||||
In Gitlab 17.8, three new secrets have been added to support the upcoming encryption framework:
|
||||
- `active_record_encryption_primary_key`
|
||||
- `active_record_encryption_deterministic_key`
|
||||
- `active_record_encryption_key_derivation_salt`
|
||||
|
||||
#### Mention the new secrets in the next release upgrade notes
|
||||
**If you have a multi-node configuration, you should ensure these secrets are the same on all nodes.** Otherwise, the application will automatically generate the missing secrets.
|
||||
|
||||
The new secrets should be mentioned in the next release notes, in the upgrade section.
|
||||
If you use the [GitLab helm chart](https://docs.gitlab.com/charts/) and disabled the [shared-secrets chart](https://docs.gitlab.com/charts/charts/shared-secrets/), you will need to [manually create these secrets](https://docs.gitlab.com/charts/installation/secrets.html#gitlab-rails-secret).
|
||||
```
|
||||
|
||||
For instance, for the 17.8 release, the notes would go in `data/release_posts/17_8/17-8-upgrade.yml` and contain something like the following:
|
||||
|
||||
```yaml
|
||||
---
|
||||
upgrades:
|
||||
- reporter: <your username> # item author username
|
||||
description: |
|
||||
In Gitlab 17.8, three new secrets have been added to support the upcoming encryption framework:
|
||||
- `active_record_encryption_primary_key`
|
||||
- `active_record_encryption_deterministic_key`
|
||||
- `active_record_encryption_key_derivation_salt`
|
||||
|
||||
**If you have a multi-node configuration, you should ensure these secrets are the same on all nodes.** Otherwise, the application will automatically generate the missing secrets.
|
||||
|
||||
If you use the [GitLab helm chart](https://docs.gitlab.com/charts/) and disabled the [shared-secrets chart](https://docs.gitlab.com/charts/charts/shared-secrets/), you will need to [manually create these secrets](https://docs.gitlab.com/charts/installation/secrets.html#gitlab-rails-secret).
|
||||
```
|
||||
|
||||
#### Mention the new secrets in the next Cloud Native GitLab charts upgrade notes
|
||||
|
||||
The new secrets should be mentioned in the current major release upgrade notes.
|
||||
|
||||
For instance, for 8.8, you should document the new secrets in <https://docs.gitlab.com/charts/releases/8_0.html>.
|
||||
1. Mention the new secrets in the next Cloud Native GitLab charts upgrade notes.
|
||||
For instance, for 8.8, you should document the new secrets in <https://docs.gitlab.com/charts/releases/8_0.html>.
|
||||
|
||||
## Further iteration
|
||||
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 119 KiB After Width: | Height: | Size: 119 KiB |
|
|
@ -91,7 +91,7 @@ To view the list of traces:
|
|||
1. Select **Monitor > Traces**.
|
||||
1. Optional. To view the details of a trace, select it from the list.
|
||||
|
||||

|
||||

|
||||
|
||||
The trace details page and a list of spans are displayed.
|
||||
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
|
@ -96,12 +96,12 @@ To view the full timestamp of an error:
|
|||
|
||||
In the following example, the error happened at 11:41 CEST:
|
||||
|
||||

|
||||

|
||||
|
||||
The **Last 24 hours** graph measures how many times this error occurred per hour.
|
||||
By pointing at the `11 am` bar, the dialog shows the error was seen 239 times:
|
||||
|
||||

|
||||

|
||||
|
||||
The **Last seen** field does not update until the full hour is complete, due to
|
||||
the library used for the call
|
||||
|
|
|
|||
|
|
@ -499,7 +499,7 @@ To resolve a vulnerability, you can either:
|
|||
- [Resolve a vulnerability with a merge request](#resolve-a-vulnerability-with-a-merge-request).
|
||||
- [Resolve a vulnerability manually](#resolve-a-vulnerability-manually).
|
||||
|
||||

|
||||

|
||||
|
||||
### Resolve a vulnerability with a merge request
|
||||
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
|
|
@ -444,8 +444,8 @@ Audit event types belong to the following product categories.
|
|||
|
||||
| Type name | Event triggered when | Saved to database | Introduced in | Scope |
|
||||
|:----------|:---------------------|:------------------|:--------------|:------|
|
||||
| [`package_registry_package_deleted`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/178181) | A package was deleted from GitLab package registry. Available only when the feature flag `package_registry_audit_events` is enabled. | {{< icon name="check-circle" >}} Yes | GitLab [17.10](https://gitlab.com/gitlab-org/gitlab/-/issues/329588) | Project, Group |
|
||||
| [`package_registry_package_published`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/178181) | A package was published to GitLab package registry. Available only when the feature flag `package_registry_audit_events` is enabled. | {{< icon name="check-circle" >}} Yes | GitLab [17.9](https://gitlab.com/gitlab-org/gitlab/-/issues/329588) | Project, Group |
|
||||
| [`package_registry_package_deleted`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/178181) | A package was deleted from GitLab package registry. Available only when the feature flag `package_registry_audit_events` is enabled and the namespace's package setting `audit_events_enabled` is true. | {{< icon name="check-circle" >}} Yes | GitLab [17.10](https://gitlab.com/gitlab-org/gitlab/-/issues/329588) | Project, Group |
|
||||
| [`package_registry_package_published`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/178181) | A package was published to GitLab package registry. Available only when the feature flag `package_registry_audit_events` is enabled and the namespace's package setting `audit_events_enabled` is true. | {{< icon name="check-circle" >}} Yes | GitLab [17.9](https://gitlab.com/gitlab-org/gitlab/-/issues/329588) | Project, Group |
|
||||
|
||||
### Permissions
|
||||
|
||||
|
|
|
|||
|
|
@ -199,6 +199,28 @@ Several known issues exist when you allow anyone to pull from the package regist
|
|||
- It does not work with the [Composer](../composer_repository/_index.md#install-a-composer-package), because Composer only has a group endpoint.
|
||||
- It works with Conan, but using [`conan search`](../conan_repository/_index.md#search-for-conan-packages-in-the-package-registry) does not work.
|
||||
|
||||
## Audit events
|
||||
|
||||
{{< details >}}
|
||||
|
||||
- Tier: Premium, Ultimate
|
||||
- Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
|
||||
|
||||
{{< /details >}}
|
||||
|
||||
{{< history >}}
|
||||
|
||||
- [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/329588) in GitLab 17.10 [with a flag](../../../administration/feature_flags.md) named `package_registry_audit_events`. Disabled by default.
|
||||
|
||||
{{< /history >}}
|
||||
|
||||
Create audit events when a package is published or deleted. Namespace Owners can turn on the `audit_events_enabled` setting through the [GraphQl API](../../../api/graphql/reference/_index.md#packagesettings).
|
||||
|
||||
You can view audit events:
|
||||
|
||||
- On the [**Group audit events**](../../compliance/audit_events.md#group-audit-events) page if the package's project is in a group.
|
||||
- On the [**Project audit events**](../../compliance/audit_events.md#project-audit-events) page if the package's project is in a user namespace.
|
||||
|
||||
## Accepting contributions
|
||||
|
||||
This table lists unsupported package manager formats that we are accepting contributions for.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,225 @@
|
|||
---
|
||||
stage: Package
|
||||
group: Package Registry
|
||||
info: For assistance with this tutorial, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments-to-other-projects-and-subjects.
|
||||
title: 'Tutorial: Structure the package registry for enterprise scale'
|
||||
---
|
||||
|
||||
As your organization grows, package management can become increasingly complex.
|
||||
The GitLab package registry model offers a powerful solution for enterprise package management.
|
||||
Understanding how to leverage the package registry is important to working with packages securely, simply, and at scale.
|
||||
|
||||
In this tutorial, you'll learn how to incorporate the GitLab package registry model into an enterprise group structure. Although the examples provided here are specific to Maven and npm packages, you can extend the concepts of this tutorial to any package supported by the GitLab package registry.
|
||||
|
||||
When you finish this tutorial, you'll know how to:
|
||||
|
||||
1. [Set up a single root or **top-level group** to structure your work](#create-an-enterprise-structure).
|
||||
1. [Configure projects for publishing packages with clear ownership](#set-up-a-top-level-group).
|
||||
1. [Set up top-level group package consumption for simplified access](#publish-packages).
|
||||
1. [Add deploy tokens so your team can access your organization's packages](#add-deploy-tokens).
|
||||
1. [Configure CI/CD to work with your packages securely](#use-packages-with-cicd).
|
||||
|
||||
## Before you begin
|
||||
|
||||
You'll need the following to complete this tutorial:
|
||||
|
||||
- An npm or Maven package.
|
||||
- Familiarity with the GitLab package registry.
|
||||
- A test project. You can use an existing project, or create one for this tutorial.
|
||||
|
||||
## Understand the GitLab package registry
|
||||
|
||||
Traditional package managers like JFrog Artifactory and Sonatype Nexus use a single, centralized repository to store and update your packages.
|
||||
With GitLab, you manage packages directly in your group or project. This means:
|
||||
|
||||
- Teams publish packages to projects that store code.
|
||||
- Teams consume packages from root group registries that aggregate all packages below them.
|
||||
- Access control is inherited from your existing GitLab permissions.
|
||||
|
||||
Because your packages are stored and managed like code, you can add package management to your existing projects or groups.
|
||||
This model offers several advantages:
|
||||
|
||||
- Clear ownership of packages alongside their source code
|
||||
- Granular access control without additional configuration
|
||||
- Simplified CI/CD integration
|
||||
- Natural alignment with team structures
|
||||
- Single URL for accessing all company packages through root group consumption
|
||||
|
||||
## Create an enterprise structure
|
||||
|
||||
Consider organizing your code under a single top-level group. For example:
|
||||
|
||||
```plaintext
|
||||
company/ (top-level group)
|
||||
├── retail-division/
|
||||
│ ├── shared-libraries/ # Division-specific shared code
|
||||
│ └── teams/
|
||||
│ ├── checkout/ # Team publishes packages here
|
||||
│ └── inventory/ # Team publishes packages here
|
||||
├── banking-division/
|
||||
│ ├── shared-libraries/ # Division-specific shared code
|
||||
│ └── teams/
|
||||
│ ├── payments/ # Team publishes packages here
|
||||
│ └── fraud/ # Team publishes packages here
|
||||
└── shared-platform/ # Enterprise-wide shared code
|
||||
├── java-commons/ # Shared Java libraries
|
||||
└── ui-components/ # Shared UI components
|
||||
```
|
||||
|
||||
In this structure, all the teams in a company publish code and packages to their own projects,
|
||||
while inheriting the configurations of the top-level `company/` group.
|
||||
|
||||
## Set up a top-level group
|
||||
|
||||
You can use an existing top-level group if you have one, and you have the Owner role.
|
||||
|
||||
If you don't have a group, create one:
|
||||
|
||||
1. On the left sidebar, at the top, select **Create new** ({{< icon name="plus" >}}) and **New group**.
|
||||
1. In **Group name**, enter a name for the group.
|
||||
1. In **Group URL**, enter a path for the group, which is used as the namespace.
|
||||
1. Choose the [visibility level](../../public_access.md).
|
||||
1. Optional. Fill in information to personalize your experience.
|
||||
1. Select **Create group**.
|
||||
|
||||
This group will store the other groups and projects in your organization. If you have other projects and groups, you can
|
||||
[transfer them to the new top-level group](../../group/manage.md#transfer-a-group) for management.
|
||||
|
||||
Before you move on, make sure you have at least:
|
||||
|
||||
- A top-level group.
|
||||
- A project that belongs to the top-level group or one of its subgroups.
|
||||
|
||||
## Publish packages
|
||||
|
||||
To maintain clear ownership, teams should publish packages to their own package registries.
|
||||
This keeps packages with their source code and ensures version history is tied to project activity.
|
||||
|
||||
{{< tabs >}}
|
||||
|
||||
{{< tab title="Maven projects" >}}
|
||||
|
||||
To publish Maven packages:
|
||||
|
||||
- Configure your `pom.xml` file to publish to the project's package registry:
|
||||
|
||||
```xml
|
||||
<!-- checkout/pom.xml -->
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>gitlab-maven</id>
|
||||
<url>${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/maven</url>
|
||||
</repository>
|
||||
</distributionManagement>
|
||||
```
|
||||
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab title="npm projects" >}}
|
||||
|
||||
To publish npm packages:
|
||||
|
||||
- Configure your `package.json` file:
|
||||
|
||||
```json
|
||||
// ui-components/package.json
|
||||
{
|
||||
"name": "@company/ui-components",
|
||||
"publishConfig": {
|
||||
"registry": "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/npm/"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
{{< /tab >}}
|
||||
|
||||
{{< /tabs >}}
|
||||
|
||||
## Consume packages
|
||||
|
||||
Because your projects are organized under a single top-level group, your packages are still accessible to
|
||||
the organization. Let's configure a single API endpoint for your teams to consume packages from.
|
||||
|
||||
{{< tabs >}}
|
||||
|
||||
{{< tab title="Maven projects" >}}
|
||||
|
||||
- Configure your `pom.xml` to access packages from the top-level group:
|
||||
|
||||
```xml
|
||||
<!-- Any project's pom.xml -->
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>gitlab-maven</id>
|
||||
<url>https://gitlab.example.com/api/v4/groups/company/-/packages/maven</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
```
|
||||
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab title="npm projects" >}}
|
||||
|
||||
- Configure your `.npmrc` file:
|
||||
|
||||
```shell
|
||||
# Any project's .npmrc
|
||||
@company:registry=https://gitlab.example.com/api/v4/groups/company/-/packages/npm/
|
||||
```
|
||||
|
||||
{{< /tab >}}
|
||||
|
||||
{{< /tabs >}}
|
||||
|
||||
This configuration automatically provides access to all packages across your organization while maintaining the benefits of project-based publishing.
|
||||
|
||||
## Add deploy tokens
|
||||
|
||||
Next, we'll add a read-only deploy token. This token provides access to the packages stored in the subgroups and projects of the organization,
|
||||
so your teams can use them for development.
|
||||
|
||||
1. In your top-level group, on the left sidebar, select **Settings > Repository**.
|
||||
1. Expand **Deploy tokens**.
|
||||
1. Select **Add token**.
|
||||
1. Complete the fields, and set the scope to `read_repository`.
|
||||
1. Select **Create deploy token**.
|
||||
|
||||
You can add as many deploy tokens to your top-level group as you need.
|
||||
Remember to rotate your tokens periodically. If you suspect a token has been exposed, revoke and replace it immediately.
|
||||
|
||||
## Use packages with CI/CD
|
||||
|
||||
When CI/CD jobs need to access the package registry, they authenticate with the predefined CI/CD variable
|
||||
`CI_JOB_TOKEN`. This authentication happens automatically, so you don't need to do any extra configuration:
|
||||
|
||||
```yaml
|
||||
publish:
|
||||
script:
|
||||
- mvn deploy # For Maven packages
|
||||
# or
|
||||
- npm publish # For npm packages
|
||||
# CI_JOB_TOKEN provides automatic authentication
|
||||
```
|
||||
|
||||
## Summary and next steps
|
||||
|
||||
Organizing your GitLab projects under one top-level group confers several benfits:
|
||||
|
||||
- **Simplified configuration**
|
||||
- One URL for all package access
|
||||
- Consistent setup across teams
|
||||
- Easy token rotation
|
||||
- **Clear ownership**
|
||||
- Packages stay with their source code
|
||||
- Teams maintain control over publishing
|
||||
- Version history is tied to project activity
|
||||
- **Natural organization**
|
||||
- Your groups match your company structure
|
||||
- Teams can collaborate while remaining autonomous
|
||||
|
||||
The GitLab package registry model offers a powerful solution for enterprise package management. By combining project-based publishing with top-level group consumption,
|
||||
you get the best of both worlds: clear ownership and simplified access.
|
||||
|
||||
This approach scales naturally with your organization while maintaining security and ease of use.
|
||||
Start by implementing this model with a single team or division, and expand as you see the benefits of this integrated approach.
|
||||
Remember that while this tutorial focused on Maven and npm, the same principles apply to all package types supported by GitLab.
|
||||
|
|
@ -104,7 +104,7 @@ When you select a description template, its content is copied to the description
|
|||
|
||||
To discard any changes to the description you've made after selecting the template: expand the **Choose a template** dropdown list and select **Reset template**.
|
||||
|
||||

|
||||

|
||||
|
||||
{{< alert type="note" >}}
|
||||
|
||||
|
|
|
|||