Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2025-05-30 15:07:41 +00:00
parent a03b068814
commit d49e08600d
183 changed files with 1038 additions and 1644 deletions

View File

@ -1 +1 @@
8d2aec4790ee36f775501f5b660ae99fe873bf7a
e2066411a33d13e6758f827dda7367b8a8ff5024

10
Gemfile
View File

@ -1,5 +1,9 @@
# frozen_string_literal: true
def next?
File.basename(__FILE__) == "Gemfile.next"
end
source 'https://rubygems.org'
if ENV.fetch('BUNDLER_CHECKSUM_VERIFICATION_OPT_IN', 'false') != 'false' # this verification is still experimental
@ -21,7 +25,11 @@ gem 'bundler-checksum', '~> 0.1.0', path: 'vendor/gems/bundler-checksum', requir
# See https://docs.gitlab.com/ee/development/gemfile.html#upgrade-rails for guidelines when upgrading Rails
gem 'rails', '~> 7.1.5.1', feature_category: :shared
if next?
gem 'rails', '~> 7.2.2.1', feature_category: :shared
else
gem 'rails', '~> 7.1.5.1', feature_category: :shared
end
gem 'activerecord-gitlab', path: 'gems/activerecord-gitlab', feature_category: :shared
# This can be dropped after upgrading to Rails 7.2: https://github.com/rails/rails/pull/49674

View File

@ -2,18 +2,18 @@
{"name":"CFPropertyList","version":"3.0.7","platform":"ruby","checksum":"c45721614aca8d5eb6fa216f2ec28ec38de1a94505e9766a20e98745492c3c4c"},
{"name":"RedCloth","version":"4.3.4","platform":"ruby","checksum":"5231b2fdd91a933915cba330e5fd1a74025e77b56f57b7404c7191ebf2812297"},
{"name":"acme-client","version":"2.0.21","platform":"ruby","checksum":"e0a044f993cd26f0ba7f8b13a3b2b007ef864cfaa333075a2d8865b087297641"},
{"name":"actioncable","version":"7.1.5.1","platform":"ruby","checksum":"764637b5b2d97b94e412d562c177bfd16b0fd769d55c98846362f5263e8aaa0d"},
{"name":"actionmailbox","version":"7.1.5.1","platform":"ruby","checksum":"c3c20589fe43e6fa88bba2d76a6f9805ffdd02531f4a9a4af8197d59f5a5360a"},
{"name":"actionmailer","version":"7.1.5.1","platform":"ruby","checksum":"b213d6d880b23b093ccfef3b4f87a3d27e4666442f71b5b634b2d19e19a49759"},
{"name":"actionpack","version":"7.1.5.1","platform":"ruby","checksum":"2bc263d9f43f16cc3b3360f59659ab11f140577602f371f1a968e2672b38d718"},
{"name":"actiontext","version":"7.1.5.1","platform":"ruby","checksum":"b8e261cfad5bc6a78b3f15be5e7c7f32190041b3dc6f027a3a353b4392d2f7ec"},
{"name":"actionview","version":"7.1.5.1","platform":"ruby","checksum":"8c559a213501798e29b50b5341a643a70bbf6fa0aa2abaf571d0efc59dc4f6aa"},
{"name":"activejob","version":"7.1.5.1","platform":"ruby","checksum":"7633376c857f4c491d06b5a7f5d86d9f07afc595398354a3f1abe80eb7e35767"},
{"name":"activemodel","version":"7.1.5.1","platform":"ruby","checksum":"74727466854a7fbdfe8f2702ca3112b23877500d4926bf7e02e921ad542191f1"},
{"name":"activerecord","version":"7.1.5.1","platform":"ruby","checksum":"f40ad1609bf33b9ba5bdc4e16d80a77b1517153234ceb413d31d635d7b91f1e3"},
{"name":"actioncable","version":"7.2.2.1","platform":"ruby","checksum":"5b3b885075a80767d63cbf2b586cbf82466a241675b7985233f957abb01bffb4"},
{"name":"actionmailbox","version":"7.2.2.1","platform":"ruby","checksum":"896a47c2520f4507c75dde67c6ea1f5eec3a041fe7bfbf3568c4e0149a080e25"},
{"name":"actionmailer","version":"7.2.2.1","platform":"ruby","checksum":"b02ae523c32c8ad762d4db941e76f3c108c106030132247ee7a7b8c86bc7b21f"},
{"name":"actionpack","version":"7.2.2.1","platform":"ruby","checksum":"17b2160a7bcbd5a569d06b1ae54a4bb5ccc7ba0815d73ff5768100a79dc1f734"},
{"name":"actiontext","version":"7.2.2.1","platform":"ruby","checksum":"f369cee41a6674b697bf9257d917a3dce575a2c89935af437b432d6737a3f0d6"},
{"name":"actionview","version":"7.2.2.1","platform":"ruby","checksum":"69fc880cf3d8b1baf21b048cf7bb68f1eef08760ff8104d7d60a6a1be8b359a5"},
{"name":"activejob","version":"7.2.2.1","platform":"ruby","checksum":"f2f95a8573b394aa4f7c24843f0c4a6065c073a5c64d6f15ecd98d98c2c23e5b"},
{"name":"activemodel","version":"7.2.2.1","platform":"ruby","checksum":"8398861f9ee2c4671a8357ab39e9b38a045fd656f6685a3dd5890c2419dbfdaf"},
{"name":"activerecord","version":"7.2.2.1","platform":"ruby","checksum":"79a31f71c32d5138717c2104e0ff105f5d82922247c85bdca144f2720e67fab9"},
{"name":"activerecord-explain-analyze","version":"0.1.0","platform":"ruby","checksum":"5debb11fe23f35b91953a80677d80ba9284ee737fd9d148c1d7603ce45217f7b"},
{"name":"activestorage","version":"7.1.5.1","platform":"ruby","checksum":"ae6b8b076858c666eaad6f896d786b67654235e861e24a83f61f1cc97b43ff63"},
{"name":"activesupport","version":"7.1.5.1","platform":"ruby","checksum":"9f0c482e473b9868cb3dfe3e9db549a3bd2302c02e4f595a5caac144a8c7cfb8"},
{"name":"activestorage","version":"7.2.2.1","platform":"ruby","checksum":"b4ec35ff94d4d6656ee6952ce439c3f80e249552d49fd2d3996ee53880c5525f"},
{"name":"activesupport","version":"7.2.2.1","platform":"ruby","checksum":"842bcbf8a92977f80fb4750661a237cf5dd4fdd442066b3c35e88afb488647f5"},
{"name":"addressable","version":"2.8.7","platform":"ruby","checksum":"462986537cf3735ab5f3c0f557f14155d778f4b43ea4f485a9deb9c8f7c58232"},
{"name":"aes_key_wrap","version":"1.1.0","platform":"ruby","checksum":"b935f4756b37375895db45669e79dfcdc0f7901e12d4e08974d5540c8e0776a5"},
{"name":"akismet","version":"3.0.0","platform":"ruby","checksum":"74991b8e3d3257eeea996b47069abb8da2006c84a144255123e8dffd1c86b230"},
@ -85,7 +85,7 @@
{"name":"coercible","version":"1.0.0","platform":"ruby","checksum":"5081ad24352cc8435ce5472bc2faa30260c7ea7f2102cc6a9f167c4d9bffaadc"},
{"name":"colored2","version":"3.1.2","platform":"ruby","checksum":"b13c2bd7eeae2cf7356a62501d398e72fde78780bd26aec6a979578293c28b4a"},
{"name":"commonmarker","version":"0.23.11","platform":"ruby","checksum":"9d1d35d358740151bce29235aebfecc63314fb57dd89a83e72d4061b4fe3d2bf"},
{"name":"concurrent-ruby","version":"1.2.3","platform":"ruby","checksum":"82fdd3f8a0816e28d513e637bb2b90a45d7b982bdf4f3a0511722d2e495801e2"},
{"name":"concurrent-ruby","version":"1.3.5","platform":"ruby","checksum":"813b3e37aca6df2a21a3b9f1d497f8cbab24a2b94cab325bffe65ee0f6cbebc6"},
{"name":"connection_pool","version":"2.5.3","platform":"ruby","checksum":"cfd74a82b9b094d1ce30c4f1a346da23ee19dc8a062a16a85f58eab1ced4305b"},
{"name":"console","version":"1.29.2","platform":"ruby","checksum":"afd9b75a1b047059dda22df0e3c0a386e96f50f6752c87c4b00b1a9fcbe77cd6"},
{"name":"cork","version":"0.3.0","platform":"ruby","checksum":"a0a0ac50e262f8514d1abe0a14e95e71c98b24e3378690e5d044daf0013ad4bc"},
@ -561,12 +561,12 @@
{"name":"rack-test","version":"2.1.0","platform":"ruby","checksum":"0c61fc61904049d691922ea4bb99e28004ed3f43aa5cfd495024cc345f125dfb"},
{"name":"rack-timeout","version":"0.7.0","platform":"ruby","checksum":"757337e9793cca999bb73a61fe2a7d4280aa9eefbaf787ce3b98d860749c87d9"},
{"name":"rackup","version":"1.0.1","platform":"ruby","checksum":"ba86604a28989fe1043bff20d819b360944ca08156406812dca6742b24b3c249"},
{"name":"rails","version":"7.1.5.1","platform":"ruby","checksum":"05aea2ed7b6392b41ce0fc11455de118455025a431b6ea334a7ac2b101608804"},
{"name":"rails","version":"7.2.2.1","platform":"ruby","checksum":"aedb1604b40f4e43b5e8066e5a1aa34dae02c33aa9669b21fd4497d0f8c9bb40"},
{"name":"rails-controller-testing","version":"1.0.5","platform":"ruby","checksum":"741448db59366073e86fc965ba403f881c636b79a2c39a48d0486f2607182e94"},
{"name":"rails-dom-testing","version":"2.2.0","platform":"ruby","checksum":"e515712e48df1f687a1d7c380fd7b07b8558faa26464474da64183a7426fa93b"},
{"name":"rails-html-sanitizer","version":"1.6.1","platform":"ruby","checksum":"e3d2fb10339f03b802e39c7f6cac28c54fd404d3f65ae39c31cca9d150c5cbf0"},
{"name":"rails-i18n","version":"7.0.10","platform":"ruby","checksum":"efae16e0ac28c0f42e98555c8db1327d69ab02058c8b535e0933cb106dd931ca"},
{"name":"railties","version":"7.1.5.1","platform":"ruby","checksum":"0be15562e2ded4efdc1b6c30f884b6d838c9ba49573dde042334b752b043e2fb"},
{"name":"railties","version":"7.2.2.1","platform":"ruby","checksum":"e3f11bf116dd6d0d874522843ccc70ec0f89fbfed3e9c2ee48a4778cd042fe1f"},
{"name":"rainbow","version":"3.1.1","platform":"ruby","checksum":"039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a"},
{"name":"rake","version":"13.0.6","platform":"ruby","checksum":"5ce4bf5037b4196c24ac62834d8db1ce175470391026bd9e557d669beeb19097"},
{"name":"rake-compiler-dock","version":"1.9.1","platform":"ruby","checksum":"e73720a29aba9c114728ce39cc0d8eef69ba61d88e7978c57bac171724cd4d53"},
@ -787,6 +787,7 @@
{"name":"unleash","version":"3.2.2","platform":"ruby","checksum":"0f6e56498de920de66a01bceffb93933693ade646bb853fc70eb16bd1026b93b"},
{"name":"unparser","version":"0.6.7","platform":"ruby","checksum":"ae42e73edfa273766e66c166368fb75ca5972cd8ec50c536253e0f6299a9dec8"},
{"name":"uri","version":"0.13.2","platform":"ruby","checksum":"a557196e652011bcff0b36d29f9e427fefcf60cc35c0ab8cce08768a6287e457"},
{"name":"useragent","version":"0.16.11","platform":"ruby","checksum":"700e6413ad4bb954bb63547fa098dddf7b0ebe75b40cc6f93b8d54255b173844"},
{"name":"valid_email","version":"0.1.3","platform":"ruby","checksum":"b81452b51b64c4beb67913f68db52c20ecb4d73d45512f5b282ab4a3f4416570"},
{"name":"validate_url","version":"1.0.15","platform":"ruby","checksum":"72fe164c0713d63a9970bd6700bea948babbfbdcec392f2342b6704042f57451"},
{"name":"validates_hostname","version":"1.0.13","platform":"ruby","checksum":"eac40178cc0b4f727df9cc6a5cb5bc2550718ad8d9bb3728df9aba6354bdda19"},

View File

@ -231,86 +231,80 @@ GEM
base64 (~> 0.2.0)
faraday (>= 1.0, < 3.0.0)
faraday-retry (>= 1.0, < 3.0.0)
actioncable (7.1.5.1)
actionpack (= 7.1.5.1)
activesupport (= 7.1.5.1)
actioncable (7.2.2.1)
actionpack (= 7.2.2.1)
activesupport (= 7.2.2.1)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
zeitwerk (~> 2.6)
actionmailbox (7.1.5.1)
actionpack (= 7.1.5.1)
activejob (= 7.1.5.1)
activerecord (= 7.1.5.1)
activestorage (= 7.1.5.1)
activesupport (= 7.1.5.1)
mail (>= 2.7.1)
net-imap
net-pop
net-smtp
actionmailer (7.1.5.1)
actionpack (= 7.1.5.1)
actionview (= 7.1.5.1)
activejob (= 7.1.5.1)
activesupport (= 7.1.5.1)
mail (~> 2.5, >= 2.5.4)
net-imap
net-pop
net-smtp
actionmailbox (7.2.2.1)
actionpack (= 7.2.2.1)
activejob (= 7.2.2.1)
activerecord (= 7.2.2.1)
activestorage (= 7.2.2.1)
activesupport (= 7.2.2.1)
mail (>= 2.8.0)
actionmailer (7.2.2.1)
actionpack (= 7.2.2.1)
actionview (= 7.2.2.1)
activejob (= 7.2.2.1)
activesupport (= 7.2.2.1)
mail (>= 2.8.0)
rails-dom-testing (~> 2.2)
actionpack (7.1.5.1)
actionview (= 7.1.5.1)
activesupport (= 7.1.5.1)
actionpack (7.2.2.1)
actionview (= 7.2.2.1)
activesupport (= 7.2.2.1)
nokogiri (>= 1.8.5)
racc
rack (>= 2.2.4)
rack (>= 2.2.4, < 3.2)
rack-session (>= 1.0.1)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
actiontext (7.1.5.1)
actionpack (= 7.1.5.1)
activerecord (= 7.1.5.1)
activestorage (= 7.1.5.1)
activesupport (= 7.1.5.1)
useragent (~> 0.16)
actiontext (7.2.2.1)
actionpack (= 7.2.2.1)
activerecord (= 7.2.2.1)
activestorage (= 7.2.2.1)
activesupport (= 7.2.2.1)
globalid (>= 0.6.0)
nokogiri (>= 1.8.5)
actionview (7.1.5.1)
activesupport (= 7.1.5.1)
actionview (7.2.2.1)
activesupport (= 7.2.2.1)
builder (~> 3.1)
erubi (~> 1.11)
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
activejob (7.1.5.1)
activesupport (= 7.1.5.1)
activejob (7.2.2.1)
activesupport (= 7.2.2.1)
globalid (>= 0.3.6)
activemodel (7.1.5.1)
activesupport (= 7.1.5.1)
activerecord (7.1.5.1)
activemodel (= 7.1.5.1)
activesupport (= 7.1.5.1)
activemodel (7.2.2.1)
activesupport (= 7.2.2.1)
activerecord (7.2.2.1)
activemodel (= 7.2.2.1)
activesupport (= 7.2.2.1)
timeout (>= 0.4.0)
activerecord-explain-analyze (0.1.0)
activerecord (>= 4)
pg
activestorage (7.1.5.1)
actionpack (= 7.1.5.1)
activejob (= 7.1.5.1)
activerecord (= 7.1.5.1)
activesupport (= 7.1.5.1)
activestorage (7.2.2.1)
actionpack (= 7.2.2.1)
activejob (= 7.2.2.1)
activerecord (= 7.2.2.1)
activesupport (= 7.2.2.1)
marcel (~> 1.0)
activesupport (7.1.5.1)
activesupport (7.2.2.1)
base64
benchmark (>= 0.3)
bigdecimal
concurrent-ruby (~> 1.0, >= 1.0.2)
concurrent-ruby (~> 1.0, >= 1.3.1)
connection_pool (>= 2.2.5)
drb
i18n (>= 1.6, < 2)
logger (>= 1.4.2)
minitest (>= 5.1)
mutex_m
securerandom (>= 0.3)
tzinfo (~> 2.0)
tzinfo (~> 2.0, >= 2.0.5)
addressable (2.8.7)
public_suffix (>= 2.0.2, < 7.0)
aes_key_wrap (1.1.0)
@ -456,7 +450,7 @@ GEM
descendants_tracker (~> 0.0.1)
colored2 (3.1.2)
commonmarker (0.23.11)
concurrent-ruby (1.2.3)
concurrent-ruby (1.3.5)
connection_pool (2.5.3)
console (1.29.2)
fiber-annotation
@ -1552,20 +1546,20 @@ GEM
rackup (1.0.1)
rack (< 3)
webrick
rails (7.1.5.1)
actioncable (= 7.1.5.1)
actionmailbox (= 7.1.5.1)
actionmailer (= 7.1.5.1)
actionpack (= 7.1.5.1)
actiontext (= 7.1.5.1)
actionview (= 7.1.5.1)
activejob (= 7.1.5.1)
activemodel (= 7.1.5.1)
activerecord (= 7.1.5.1)
activestorage (= 7.1.5.1)
activesupport (= 7.1.5.1)
rails (7.2.2.1)
actioncable (= 7.2.2.1)
actionmailbox (= 7.2.2.1)
actionmailer (= 7.2.2.1)
actionpack (= 7.2.2.1)
actiontext (= 7.2.2.1)
actionview (= 7.2.2.1)
activejob (= 7.2.2.1)
activemodel (= 7.2.2.1)
activerecord (= 7.2.2.1)
activestorage (= 7.2.2.1)
activesupport (= 7.2.2.1)
bundler (>= 1.15.0)
railties (= 7.1.5.1)
railties (= 7.2.2.1)
rails-controller-testing (1.0.5)
actionpack (>= 5.0.1.rc1)
actionview (>= 5.0.1.rc1)
@ -1580,10 +1574,10 @@ GEM
rails-i18n (7.0.10)
i18n (>= 0.7, < 2)
railties (>= 6.0.0, < 8)
railties (7.1.5.1)
actionpack (= 7.1.5.1)
activesupport (= 7.1.5.1)
irb
railties (7.2.2.1)
actionpack (= 7.2.2.1)
activesupport (= 7.2.2.1)
irb (~> 1.13)
rackup (>= 1.0.0)
rake (>= 12.2)
thor (~> 1.0, >= 1.2.2)
@ -1984,6 +1978,7 @@ GEM
diff-lcs (~> 1.3)
parser (>= 3.2.0)
uri (0.13.2)
useragent (0.16.11)
valid_email (0.1.3)
activemodel
mail (>= 2.6.1)
@ -2335,7 +2330,7 @@ DEPENDENCIES
rack-oauth2 (~> 2.2.1)
rack-proxy (~> 0.7.7)
rack-timeout (~> 0.7.0)
rails (~> 7.1.5.1)
rails (~> 7.2.2.1)
rails-controller-testing
rails-i18n (~> 7.0, >= 7.0.9)
rainbow (~> 3.0)

View File

@ -138,6 +138,9 @@ export const initSharedAccessTokenApp = () => {
const {
accessTokenMaxDate,
accessTokenMinDate,
accessTokenName,
accessTokenDescription,
accessTokenScopes,
accessTokenCreate,
accessTokenRevoke,
accessTokenRotate,
@ -160,6 +163,9 @@ export const initSharedAccessTokenApp = () => {
return createElement(AccessTokens, {
props: {
id: gon.current_user_id,
tokenName: accessTokenName,
tokenDescription: accessTokenDescription,
tokenScopes: accessTokenScopes && JSON.parse(accessTokenScopes),
},
});
},

View File

@ -1,6 +1,5 @@
<script>
import { GlPopover, GlLink, GlIcon } from '@gitlab/ui';
import { METRIC_POPOVER_LABEL } from '../constants';
export default {
name: 'MetricPopover',
@ -13,6 +12,12 @@ export default {
metric: {
type: Object,
required: true,
validator: (metric) => ['label', 'description'].every((key) => metric[key]),
},
metricUrl: {
type: String,
required: false,
default: '',
},
target: {
type: String,
@ -20,40 +25,36 @@ export default {
},
},
computed: {
metricLink() {
return this.metric.links?.find((link) => !link.docs_link);
},
docsLink() {
return this.metric.links?.find((link) => link.docs_link);
return this.metric.docsLink;
},
},
metricPopoverLabel: METRIC_POPOVER_LABEL,
};
</script>
<template>
<gl-popover :target="target" placement="top">
<template #title>
<div class="gl-flex gl-items-center gl-justify-between gl-py-1 gl-text-right">
<div class="gl-flex gl-w-full gl-items-center gl-justify-between gl-py-1">
<span data-testid="metric-label">{{ metric.label }}</span>
<gl-link
v-if="metricLink"
:href="metricLink.url"
v-if="metricUrl"
:href="metricUrl"
class="gl-text-sm gl-font-normal"
data-testid="metric-link"
>{{ $options.metricPopoverLabel }}
>{{ s__('ValueStreamAnalytics|View details') }}
<gl-icon name="chart" />
</gl-link>
</div>
</template>
<span v-if="metric.description" data-testid="metric-description">{{ metric.description }}</span>
<p data-testid="metric-description" class="gl-mb-0">{{ metric.description }}</p>
<gl-link
v-if="docsLink"
:href="docsLink.url"
class="gl-text-sm"
:href="docsLink"
class="gl-mt-2 gl-block gl-text-sm"
target="_blank"
data-testid="metric-docs-link"
>{{ docsLink.label }}
>{{ __('Go to docs') }}
<gl-icon name="external-link" class="gl-align-middle" />
</gl-link>
</gl-popover>

View File

@ -2,6 +2,8 @@
import { GlSingleStat } from '@gitlab/ui/dist/charts';
import { countFloatingPointDigits } from '~/lib/utils/number_utils';
import { visitUrl } from '~/lib/utils/url_utility';
import { generateMetricLink } from '~/analytics/shared/utils';
import { FLOW_METRICS } from '~/analytics/shared/constants';
import MetricPopover from './metric_popover.vue';
const MAX_DISPLAYED_DECIMAL_PRECISION = 2;
@ -17,6 +19,15 @@ export default {
type: Object,
required: true,
},
namespacePath: {
type: String,
required: true,
},
isProjectNamespace: {
type: Boolean,
required: false,
default: false,
},
},
computed: {
decimalPlaces() {
@ -28,14 +39,21 @@ export default {
}
return 0;
},
hasLinks() {
return this.metric.links?.length && this.metric.links[0].url;
metricUrl() {
const { metric, namespacePath, isProjectNamespace } = this;
const { LEAD_TIME, CYCLE_TIME } = FLOW_METRICS;
// Both of these metrics drill down to VSA, so we return an empty string here
// to avoid circular redirect
if ([LEAD_TIME, CYCLE_TIME].includes(metric.identifier)) return '';
return generateMetricLink({ metricId: metric.identifier, namespacePath, isProjectNamespace });
},
},
methods: {
clickHandler({ links }) {
if (this.hasLinks) {
visitUrl(links[0].url);
clickHandler() {
if (this.metricUrl) {
visitUrl(this.metricUrl);
}
},
},
@ -50,12 +68,12 @@ export default {
:unit="metric.unit || ''"
:should-animate="true"
:animation-decimal-places="decimalPlaces"
:class="{ 'hover:gl-cursor-pointer': hasLinks }"
:class="{ 'hover:gl-cursor-pointer': metricUrl }"
data-testid="metric-tile"
tabindex="0"
use-delimiters
@click="clickHandler(metric)"
@click="clickHandler"
/>
<metric-popover :metric="metric" :target="metric.identifier" />
<metric-popover :metric="metric" :metric-url="metricUrl" :target="metric.identifier" />
</div>
</template>

View File

@ -247,6 +247,8 @@ export default {
v-for="metric in group.data"
:key="metric.identifier"
:metric="metric"
:namespace-path="requestPath"
:is-project-namespace="isProjectNamespace"
class="gl-mt-5 gl-pr-10"
/>
<value-streams-dashboard-link
@ -262,6 +264,8 @@ export default {
v-for="metric in metrics"
:key="metric.identifier"
:metric="metric"
:namespace-path="requestPath"
:is-project-namespace="isProjectNamespace"
class="gl-mt-5 gl-pr-10"
/>
</div>

View File

@ -90,8 +90,6 @@ export const NUMBER_OF_DAYS_SELECTED = (numDays) => {
return n__('1 day selected', '%d days selected', numDays);
};
export const METRIC_POPOVER_LABEL = s__('ValueStreamAnalytics|View details');
export const ISSUES_COMPLETED_TYPE = 'issues_completed';
export const ALL_METRICS_QUERY_TYPE = 'ALL_METRICS_QUERY_TYPE';

View File

@ -9,6 +9,7 @@ import {
MAX_METRIC_PRECISION,
UNITS,
VALUE_STREAM_METRIC_DISPLAY_UNITS,
VALUE_STREAM_METRIC_METADATA,
VALUE_STREAM_METRIC_TILE_METADATA,
} from './constants';
@ -167,6 +168,32 @@ export const generateValueStreamsDashboardLink = (
return joinPaths(...segments);
};
/**
* Generates a URL link to the metric's report based on the namespace type.
* @param {String} metricId Metric's identifier
* @param {String} namespacePath - Path of the specified namespace
* @param {Boolean} isProjectNamespace
* @returns {String} URL link to the metric's report
*/
export const generateMetricLink = ({
metricId = null,
namespacePath = null,
isProjectNamespace = false,
} = {}) => {
const { groupLink, projectLink } = VALUE_STREAM_METRIC_METADATA[metricId] ?? {};
const hasLinks = groupLink || projectLink;
if (!hasLinks || !namespacePath) return '';
return joinPaths(
'/',
gon.relative_url_root,
!isProjectNamespace ? 'groups' : '',
namespacePath,
isProjectNamespace ? projectLink : groupLink,
);
};
/**
* Extracts the relevant feature and license flags needed for VSA
*

View File

@ -65,8 +65,7 @@ $(() => {
}
function crudToggleSection(section, toggleState) {
const collapseIcon = section.querySelector('.js-crud-collapsible-collapse');
const expandIcon = section.querySelector('.js-crud-collapsible-expand');
const chevronIcon = section.querySelector('.js-crud-collapsible-icon');
const crudBody = section.querySelector('.crud-body');
const crudHeader = section.querySelector('.crud-header');
const crudFooter = section.querySelector('[data-testid="crud-footer"]');
@ -76,20 +75,20 @@ $(() => {
if (isExpanded && !toggleState) {
toggleButton.ariaExpanded = 'false';
collapseIcon?.classList.add('gl-hidden');
expandIcon?.classList.remove('gl-hidden');
chevronIcon?.classList.remove('gl-animated-icon-on');
chevronIcon?.classList.add('gl-animated-icon-off');
crudBody?.classList.add('!gl-hidden');
crudFooter?.classList.add('!gl-hidden');
crudForm?.classList.add('!gl-hidden');
crudHeader?.classList.add('gl-rounded-base', 'gl-border-b-transparent');
crudHeader?.classList.add('gl-rounded-lg', 'gl-border-b-transparent');
} else {
toggleButton.ariaExpanded = 'true';
expandIcon?.classList.add('gl-hidden');
collapseIcon?.classList.remove('gl-hidden');
chevronIcon?.classList.add('gl-animated-icon-on');
chevronIcon?.classList.remove('gl-animated-icon-off');
crudBody?.classList.remove('!gl-hidden');
crudFooter?.classList.remove('!gl-hidden');
crudForm?.classList.remove('!gl-hidden');
crudHeader?.classList.remove('gl-rounded-base', 'gl-border-b-transparent');
crudHeader?.classList.remove('gl-rounded-lg', 'gl-border-b-transparent');
}
toggleButton.setAttribute(

View File

@ -1,3 +1,4 @@
import { assign } from 'lodash';
import { gql } from '@apollo/client/core';
import createDefaultClient from '~/lib/graphql';
import TaskQueue from '../utils/task_queue';
@ -6,6 +7,17 @@ import { joinPaths } from '../../lib/utils/url_utility';
const CONCURRENCY_LIMIT = 1;
export const resolveToScalar = (obj) => {
const key0 = Object.keys(obj).filter((key) => key !== '__typename')[0];
return typeof obj[key0] === 'object' ? resolveToScalar(obj[key0]) : obj[key0];
};
export const transformGIDToString = (data, type) => {
// legacy epics expect the id to be the last part of the GID
if (type === 'String') return data?.split('/').pop();
return data;
};
export default class Executor {
#client;
static taskQueue;
@ -22,19 +34,38 @@ export default class Executor {
return this;
}
async execute(query) {
const { data } = await Executor.taskQueue.enqueue(() =>
this.#client.query({
query: gql`
${query}
`,
}),
async execute(query, variables = []) {
return this.#enqueue(
query,
assign(
...(await Promise.all(
variables.map(async (variable) => ({
[variable.key]: transformGIDToString(
resolveToScalar(await this.#execute(variable.data)),
variable.data_type,
),
})),
)),
),
);
}
async #execute(query, variables = {}) {
const { data } = await this.#client.query({
query: gql`
${query}
`,
variables,
});
return data;
}
async #enqueue(query, variables = {}) {
return Executor.taskQueue.enqueue(() => this.#execute(query, variables));
}
}
export const execute = async (query) => {
return new Executor().init().execute(query);
export const execute = async (query, variables = []) => {
return new Executor().init().execute(query, variables);
};

View File

@ -4,8 +4,8 @@ import { present } from './presenter';
import { transform } from './transformer/data';
export const executeAndPresentQuery = async (glqlQuery, queryKey) => {
const { query, config } = await parse(glqlQuery);
const data = await execute(query);
const { query, config, variables } = await parse(glqlQuery);
const data = await execute(query, variables);
const transformed = transform(data, config);
return present(transformed, config, { queryKey });
};

View File

@ -25,6 +25,7 @@ export const parse = async (glqlQuery, target = 'graphql') => {
}
const limit = parseInt(config.limit, 10) || undefined;
const parsed = await parseQuery(query, { ...config, target, limit });
return { query: await parseQuery(query, { ...config, target, limit }), config };
return { query: parsed.query, variables: parsed.variables, config };
};

View File

@ -22,9 +22,9 @@ export const parseQuery = async (query, config) => {
parser.fields = uniq([...REQUIRED_QUERY_FIELDS, ...config.fields.map(({ name }) => name)]);
const target = glqlWorkItemsFeatureFlagEnabled() ? 'work_items_graphql' : 'graphql';
const { output } = parser.compile(target, query, config);
const { output, variables } = parser.compile(target, query, config);
if (output.toLowerCase().startsWith('error')) throw new Error(output.replace(/^error: /i, ''));
return output;
return { query: output, variables };
};

View File

@ -1,5 +1,5 @@
<script>
import { GlButton, GlTooltipDirective } from '@gitlab/ui';
import { GlButton, GlTooltipDirective, GlLoadingIcon } from '@gitlab/ui';
import { computed } from 'vue';
import { __ } from '~/locale';
import { logError } from '~/lib/logger';
@ -51,6 +51,7 @@ export default {
components: {
OpenMrBadge,
GlButton,
GlLoadingIcon,
BlobOverflowMenu,
ForkSuggestionModal,
WebIdeLink: () => import('ee_else_ce/vue_shared/components/web_ide_link.vue'),
@ -349,6 +350,15 @@ export default {
@hide="isForkSuggestionModalVisible = false"
/>
<gl-loading-icon
v-if="isLoadingRepositoryBlob"
:label="__('Loading file actions')"
class="gl-p-3"
size="sm"
color="dark"
variant="spinner"
:inline="false"
/>
<blob-overflow-menu
v-if="!isLoadingRepositoryBlob && glFeatures.blobOverflowMenu"
:project-path="projectPath"

View File

@ -34,6 +34,23 @@ export default {
import('ee_component/vue_shared/components/access_tokens/max_expiration_date_message.vue'),
},
inject: ['accessTokenMaxDate', 'accessTokenMinDate'],
props: {
name: {
type: String,
required: false,
default: '',
},
description: {
type: String,
required: false,
default: '',
},
scopes: {
type: Array,
required: false,
default: () => [],
},
},
data() {
const maxDate = this.accessTokenMaxDate ? new Date(this.accessTokenMaxDate) : null;
if (maxDate) {
@ -43,7 +60,11 @@ export default {
}
const minDate = new Date(this.accessTokenMinDate);
const expiresAt = defaultDate(maxDate);
return { maxDate, minDate, values: { expiresAt } };
return {
maxDate,
minDate,
values: { expiresAt, name: this.name, description: this.description, scopes: this.scopes },
};
},
computed: {
...mapState(useAccessTokens, ['busy']),

View File

@ -36,6 +36,21 @@ export default {
required: false,
default: false,
},
tokenName: {
type: String,
required: false,
default: '',
},
tokenDescription: {
type: String,
required: false,
default: '',
},
tokenScopes: {
type: Array,
required: false,
default: () => [],
},
},
computed: {
...mapState(useAccessTokens, [
@ -54,6 +69,7 @@ export default {
this.setup({
...initializeValuesFromQuery(),
id: this.id,
showCreateForm: Boolean(this.tokenName || this.tokenDescription || this.tokenScopes.length),
urlCreate: this.accessTokenCreate,
urlRevoke: this.accessTokenRevoke,
urlRotate: this.accessTokenRotate,
@ -117,7 +133,12 @@ export default {
</template>
</page-heading>
<access-token v-if="token" />
<access-token-form v-if="showCreateForm" />
<access-token-form
v-if="showCreateForm"
:name="tokenName"
:description="tokenDescription"
:scopes="tokenScopes"
/>
<access-token-statistics />
<div class="gl-my-5 gl-flex gl-flex-col gl-gap-3 md:gl-flex-row">
<gl-filtered-search

View File

@ -16,6 +16,7 @@ import { serializeParams, update2WeekFromNow, updateUrlWithQueryParams } from '.
/**
* @typedef {{type: string, value: {data: string, operator: string}}} Filter
* @typedef {Array<string|Filter>} Filters
* @typedef {{isAsc: boolean, value: string}} Sorting
*/
/**
@ -236,7 +237,7 @@ export const useAccessTokens = defineStore('accessTokens', {
this.token = token;
},
/**
* @param {{isAsc: boolean, value: string}} sorting
* @param {Sorting} sorting
*/
setSorting(sorting) {
this.sorting = sorting;
@ -245,15 +246,29 @@ export const useAccessTokens = defineStore('accessTokens', {
* @param {Object} options
* @param {Filters} options.filters
* @param {number} options.id
* @param {number} options.page
* @param {boolean} options.showCreateForm
* @param {Sorting} options.sorting
* @param {string} options.urlCreate
* @param {string} options.urlRevoke
* @param {string} options.urlRotate
* @param {string} options.urlShow
*/
setup({ filters, id, page, sorting, urlCreate, urlRevoke, urlRotate, urlShow }) {
setup({
filters,
id,
page,
showCreateForm,
sorting,
urlCreate,
urlRevoke,
urlRotate,
urlShow,
}) {
this.filters = filters;
this.id = id;
this.page = page;
this.showCreateForm = showCreateForm;
this.sorting = sorting;
this.urlCreate = urlCreate;
this.urlRevoke = urlRevoke;

View File

@ -6,6 +6,7 @@ import {
GlSkeletonLoader,
GlLink,
GlTooltipDirective,
GlAnimatedChevronLgDownUpIcon,
} from '@gitlab/ui';
import { __ } from '~/locale';
@ -16,6 +17,7 @@ export default {
GlBadge,
GlSkeletonLoader,
GlLink,
GlAnimatedChevronLgDownUpIcon,
},
directives: {
GlTooltip: GlTooltipDirective,
@ -117,9 +119,6 @@ export default {
this.$scopedSlots.default || this.$scopedSlots.empty || this.$scopedSlots.pagination;
return !(hasContent && this.isCollapsible && this.isCollapsed);
},
toggleIcon() {
return this.isCollapsed ? 'chevron-lg-down' : 'chevron-lg-up';
},
toggleLabel() {
return this.isCollapsed ? __('Expand') : __('Collapse');
},
@ -260,16 +259,17 @@ export default {
<gl-button
v-gl-tooltip
:title="toggleLabel"
:icon="toggleIcon"
category="tertiary"
size="small"
:aria-label="toggleLabel"
:aria-expanded="ariaExpandedAttr"
:aria-controls="anchorId"
class="-gl-mr-2 gl-self-start"
class="btn-icon -gl-mr-2 gl-self-start"
data-testid="crud-collapse-toggle"
@click="toggleCollapse"
/>
>
<gl-animated-chevron-lg-down-up-icon :is-on="!isCollapsed" variant="default" />
</gl-button>
</div>
</div>
</header>

View File

@ -6,6 +6,11 @@ export default {
required: false,
default: () => [],
},
urlFullPath: {
type: String,
required: false,
default: undefined,
},
withTabs: {
type: Boolean,
required: false,
@ -24,6 +29,7 @@ export default {
<router-view
:key="pageKey"
:new-comment-template-paths="newCommentTemplatePaths"
:url-full-path="urlFullPath"
:with-tabs="withTabs"
data-testid="work-item-router-view"
/>

View File

@ -33,7 +33,6 @@ export default {
GlButton,
GlAlert,
},
inject: ['fullPath'],
props: {
designNoteMutation: {
type: Object,

View File

@ -186,7 +186,8 @@ export default {
return this.workItemHierarchy?.hasParent;
},
workItemCrmContacts() {
return this.isWidgetPresent(WIDGET_TYPE_CRM_CONTACTS);
const crmContactsWidget = this.isWidgetPresent(WIDGET_TYPE_CRM_CONTACTS);
return crmContactsWidget && crmContactsWidget.contactsAvailable ? crmContactsWidget : null;
},
customFields() {
return this.isWidgetPresent(WIDGET_TYPE_CUSTOM_FIELDS)?.customFieldValues;
@ -249,6 +250,7 @@ export default {
v-if="showParent"
class="work-item-attributes-item"
:can-update="canUpdateMetadata"
:full-path="fullPath"
:work-item-id="workItem.id"
:work-item-type="workItemType"
:parent="workItemParent"

View File

@ -139,7 +139,7 @@ export default {
import('ee_component/work_items/components/work_item_vulnerabilities.vue'),
},
mixins: [glFeatureFlagMixin(), trackingMixin],
inject: ['fullPath', 'groupPath', 'hasSubepicsFeature', 'hasLinkedItemsEpicsFeature'],
inject: ['groupPath', 'hasSubepicsFeature', 'hasLinkedItemsEpicsFeature'],
props: {
isModal: {
type: Boolean,
@ -156,7 +156,7 @@ export default {
required: false,
default: null,
},
modalWorkItemFullPath: {
workItemFullPath: {
type: String,
required: false,
default: '',
@ -301,9 +301,6 @@ export default {
},
},
computed: {
workItemFullPath() {
return this.modalWorkItemFullPath || this.fullPath;
},
workItemProjectId() {
return this.workItem?.project?.id;
},

View File

@ -137,7 +137,7 @@ export default {
is-modal
:work-item-id="displayedWorkItemId"
:work-item-iid="displayedWorkItemIid"
:modal-work-item-full-path="workItemFullPath"
:work-item-full-path="workItemFullPath"
class="gl-isolate -gl-mt-3 gl-bg-inherit gl-p-5"
@close="hide"
@deleteWorkItem="deleteWorkItem"

View File

@ -313,7 +313,7 @@ export default {
<work-item-detail
:key="activeItem.iid"
:work-item-iid="activeItem.iid"
:modal-work-item-full-path="activeItemFullPath"
:work-item-full-path="activeItemFullPath"
:modal-is-group="modalIsGroup"
:new-comment-template-paths="newCommentTemplatePaths"
:is-board="isBoard"

View File

@ -39,12 +39,15 @@ export default {
IssuePopover: () => import('~/issuable/popover/components/issue_popover.vue'),
WorkItemSidebarDropdownWidget,
},
inject: ['fullPath'],
props: {
workItemId: {
type: String,
required: true,
},
fullPath: {
required: true,
type: String,
},
parent: {
type: Object,
required: false,

View File

@ -398,6 +398,7 @@ export const setNewWorkItemCache = async (
if (widgetName === WIDGET_TYPE_CRM_CONTACTS) {
widgets.push({
type: 'CRM_CONTACTS',
contactsAvailable: false,
contacts: {
nodes: [],
__typename: 'CustomerRelationsContactConnection',

View File

@ -102,6 +102,7 @@ fragment WorkItemWidgets on WorkItemWidget {
}
}
... on WorkItemWidgetCrmContacts {
contactsAvailable
contacts {
nodes {
id

View File

@ -149,6 +149,7 @@ export const initWorkItemsRoot = ({ workspaceType, withTabs } = {}) => {
return createElement(App, {
props: {
newCommentTemplatePaths: JSON.parse(newCommentTemplatePaths),
urlFullPath: fullPath,
withTabs,
},
});

View File

@ -27,6 +27,10 @@ export default {
required: false,
default: () => [],
},
urlFullPath: {
type: String,
required: true,
},
},
data() {
return {
@ -75,6 +79,7 @@ export default {
<gl-alert v-if="error" variant="danger" @dismiss="error = ''">{{ error }}</gl-alert>
<work-item-detail
:new-comment-template-paths="newCommentTemplatePaths"
:work-item-full-path="urlFullPath"
:work-item-iid="iid"
@deleteWorkItem="deleteWorkItem($event)"
/>

View File

@ -25,8 +25,10 @@
size: :small,
button_text_classes: '!gl-overflow-visible',
button_options: { class: '-gl-mr-2 js-crud-collapsible-button has-tooltip', title: _('Collapse'), 'aria-expanded': 'true', 'aria-controls': id, data: { collapse_title: _('Expand'), expand_title: _('Collapse') } }) do
= sprite_icon('chevron-lg-up', css_class: '!-gl-mx-2 js-crud-collapsible-collapse')
= sprite_icon('chevron-lg-down', css_class: '!-gl-mx-2 gl-hidden js-crud-collapsible-expand')
= render Pajamas::AnimatedIconComponent.new(icon: :chevron_lg_down_up,
variant: :current,
is_on: true,
icon_options: { class: 's16 !-gl-mx-2 js-crud-collapsible-icon' })
- if form?
.gl-p-5.gl-pt-4.gl-bg-subtle.gl-border-b.gl-border-section{ form_options_attrs }

View File

@ -10,10 +10,6 @@ module Projects
push_frontend_feature_flag(:show_container_registry_tag_signatures, project)
end
before_action only: [:index, :show] do
push_frontend_feature_flag(:container_registry_immutable_tags, project)
end
before_action :authorize_update_container_image!, only: [:destroy]
def index

View File

@ -9,8 +9,6 @@ module Projects
before_action :packages_and_registries_settings_enabled!
before_action :set_feature_flag_packages_protected_packages, only: :show
before_action :set_feature_flag_container_registry_protected_containers_delete, only: :show
before_action :set_feature_flag_container_registry_immutable_tags, only: :show
before_action :push_create_container_registry_protection_immutable_tag_rule_ability, only: :show
feature_category :package_registry
urgency :low
@ -44,15 +42,8 @@ module Projects
def set_feature_flag_container_registry_protected_containers_delete
push_frontend_feature_flag(:container_registry_protected_containers_delete, project)
end
def set_feature_flag_container_registry_immutable_tags
push_frontend_feature_flag(:container_registry_immutable_tags, project)
end
def push_create_container_registry_protection_immutable_tag_rule_ability
push_frontend_ability(ability: :create_container_registry_protection_immutable_tag_rule,
resource: project, user: current_user)
end
end
end
end
Projects::Settings::PackagesAndRegistriesController.prepend_mod

View File

@ -35,10 +35,13 @@ module AccessTokensHelper
}.to_json
end
def personal_access_token_data
def personal_access_token_data(token)
{
access_token: {
**expires_at_field_data,
name: token[:name],
description: token[:description],
scopes: token[:scopes].to_json,
create: user_settings_personal_access_tokens_path,
revoke: api_v4_personal_access_tokens_path,
rotate: api_v4_personal_access_tokens_path,

View File

@ -12,17 +12,9 @@ module Integrations
belongs_to :group, inverse_of: self.table_name.to_sym, foreign_key: :group_id, optional: true
belongs_to :organization, inverse_of: self.table_name.to_sym, foreign_key: :organization_id, optional: true
belongs_to :instance_integration,
inverse_of: self.table_name.to_sym,
foreign_key: :instance_integration_id,
class_name: 'Integrations::Instance::Integration',
optional: true
before_validation :set_sharding_key
validates :integration, absence: true, if: :instance_integration
validates :instance_integration, absence: true, if: :integration
validate :validate_mutual_exclusion
validates :integration, presence: true
validate :validate_sharding_key
end
@ -50,7 +42,6 @@ module Integrations
'integration_id',
'created_at',
'updated_at',
'instance_integration_id',
'group_id',
'project_id',
'organization_id'
@ -59,12 +50,6 @@ module Integrations
private
def validate_mutual_exclusion
return if integration.present? ^ instance_integration.present?
errors.add(:base, :blank, message: 'one of integration or instance_integration must be present')
end
def set_sharding_key
return if project_id || group_id || organization_id || integration.nil?

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class Asana < Integration
include Integrations::Base::Asana
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class Assembla < Integration
include Integrations::Base::Assembla
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class Bamboo < Integration
include Integrations::Base::Bamboo
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class BeyondIdentity < Integration
# To be updated as part of https://gitlab.com/gitlab-org/gitlab/-/issues/474809
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class Bugzilla < Integration
include Integrations::Base::Bugzilla
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class Buildkite < Integration
# To be updated as part of https://gitlab.com/gitlab-org/gitlab/-/issues/474809
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class Clickup < Integration
include Integrations::Base::Clickup
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class Confluence < Integration
include Integrations::Base::Confluence
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class CustomIssueTracker < Integration
include Integrations::Base::CustomIssueTracker
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class Datadog < Integration
# To be updated as part of https://gitlab.com/gitlab-org/gitlab/-/issues/474809
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class DiffblueCover < Integration
include Integrations::Base::DiffblueCover
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class Discord < Integration
include Integrations::Base::Discord
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class DroneCi < Integration
# To be updated as part of https://gitlab.com/gitlab-org/gitlab/-/issues/474809
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class EmailsOnPush < Integration
include Integrations::Base::EmailsOnPush
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class Ewm < Integration
include Integrations::Base::Ewm
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class ExternalWiki < Integration
include Integrations::Base::ExternalWiki
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class GitGuardian < Integration
# To be updated as part of https://gitlab.com/gitlab-org/gitlab/-/issues/474809
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class HangoutsChat < Integration
include Integrations::Base::HangoutsChat
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class Harbor < Integration
include Integrations::Base::Harbor
end
end
end

View File

@ -1,45 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class Integration < ApplicationRecord
include IgnorableColumns
include Integrations::Base::Integration
self.table_name = 'instance_integrations'
self.inheritance_column = :type_new # rubocop:disable Database/AvoidInheritanceColumn -- supporting instance integrations migration
ignore_column :type, remove_with: '17.7', remove_after: '2024-12-02'
has_one :issue_tracker_data,
autosave: true,
inverse_of: :instance_integration,
foreign_key: :instance_integration_id,
class_name: 'Integrations::IssueTrackerData'
has_one :jira_tracker_data,
autosave: true,
inverse_of: :instance_integration,
foreign_key: :instance_integration_id,
class_name: 'Integrations::JiraTrackerData'
has_one :zentao_tracker_data,
autosave: true,
inverse_of: :instance_integration,
foreign_key: :instance_integration_id,
class_name: 'Integrations::ZentaoTrackerData'
def instance_level?
true
end
def group_level?
false
end
def project_level?
false
end
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class Irker < Integration
include Integrations::Base::Irker
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class Jira < Integration
# To be updated as part of https://gitlab.com/gitlab-org/gitlab/-/issues/474809
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class Matrix < Integration
# To be updated as part of https://gitlab.com/gitlab-org/gitlab/-/issues/474809
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class Mattermost < Integration
# To be updated as part of https://gitlab.com/gitlab-org/gitlab/-/issues/474809
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class MattermostSlashCommands < Integration
include Integrations::Base::MattermostSlashCommands
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class MicrosoftTeams < Integration
include Integrations::Base::MicrosoftTeams
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class MockCi < Integration
include Integrations::Base::MockCi
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class MockMonitoring < Integration
include Integrations::Base::MockMonitoring
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class Packagist < Integration
# To be updated as part of https://gitlab.com/gitlab-org/gitlab/-/issues/474809
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class Phorge < Integration
include Integrations::Base::Phorge
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class PipelinesEmail < Integration
include Integrations::Base::PipelinesEmail
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class Pivotaltracker < Integration
include Integrations::Base::Pivotaltracker
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class Pumble < Integration
include Integrations::Base::Pumble
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class Pushover < Integration
include Integrations::Base::Pushover
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class Redmine < Integration
include Integrations::Base::Redmine
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class Slack < Integration
# To be updated as part of https://gitlab.com/gitlab-org/gitlab/-/issues/474809
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class SlackSlashCommands < Integration
# To be updated as part of https://gitlab.com/gitlab-org/gitlab/-/issues/474809
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class SquashTm < Integration
# To be updated as part of https://gitlab.com/gitlab-org/gitlab/-/issues/474809
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class Teamcity < Integration
include Integrations::Base::Teamcity
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class Telegram < Integration
include Integrations::Base::Telegram
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class UnifyCircuit < Integration
include Integrations::Base::UnifyCircuit
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class WebexTeams < Integration
include Integrations::Base::WebexTeams
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class Youtrack < Integration
include Integrations::Base::Youtrack
end
end
end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
module Integrations
module Instance
class Zentao < Integration
# To be updated as part of https://gitlab.com/gitlab-org/gitlab/-/issues/474809
end
end
end

View File

@ -2636,7 +2636,7 @@ class User < ApplicationRecord
# override, from Devise::Validatable
def password_required?
return false if internal? || project_bot? || security_policy_bot?
return false if internal? || project_bot? || security_policy_bot? || placeholder?
super
end

View File

@ -2,7 +2,7 @@
module Users
class BuildService < BaseService
ALLOWED_USER_TYPES = %i[project_bot security_policy_bot].freeze
ALLOWED_USER_TYPES = %i[project_bot security_policy_bot placeholder].freeze
delegate :user_default_internal_regex_enabled?,
:user_default_internal_regex_instance,

View File

@ -5,7 +5,7 @@
- @force_desktop_expanded_sidebar = true
- if Feature.enabled?(:migrate_user_access_tokens_ui, current_user)
#js-shared-access-token-app{ data: personal_access_token_data }
#js-shared-access-token-app{ data: personal_access_token_data(@personal_access_token) }
- else
= render ::Layouts::SettingsSectionComponent.new(page_title) do |c|
- c.with_description do

View File

@ -22,7 +22,7 @@
# We can probably drop this patch for Rails 7.1 and up, but we might
# want to wait for https://github.com/rails/rails/pull/51441 or some
# mechanism that can disable the `Link` header.
if Gem::Version.new(ActionView.version) >= Gem::Version.new('7.2')
if Gem::Version.new(ActionView.version) >= Gem::Version.new('7.3')
raise 'New version of ActionView detected. This patch can likely be removed.'
end

View File

@ -6,7 +6,7 @@
# We need to set the following up to override the ActiveJob adapater
# so as to ensure that mailer jobs are enqueued in a shard-aware manner.
if Gem::Version.new(Rails.gem_version) >= Gem::Version.new('7.2')
if Gem::Version.new(Rails.gem_version) >= Gem::Version.new('7.3')
raise 'New version of Rails detected, please remove or update this patch'
end

View File

@ -1,7 +1,5 @@
# frozen_string_literal: true
return if Gitlab::Utils.to_boolean(ENV['SKIP_CELL_CONFIG_VALIDATION'], default: false)
ValidationError = Class.new(StandardError)
print_error = ->(error_message) do

View File

@ -0,0 +1,100 @@
# frozen_string_literal: true
class RemoveOldCodeSuggestionsTables < ClickHouse::Migration
def up
execute "DROP TABLE IF EXISTS code_suggestion_usages" # new table code_suggestion_events
execute "DROP TABLE IF EXISTS code_suggestion_daily_events" # new table code_suggestion_events_daily
execute "DROP TABLE IF EXISTS code_suggestion_daily_events_new"
execute "DROP VIEW IF EXISTS code_suggestion_daily_events_mv" # new view code_suggestion_events_daily_mv
execute "DROP VIEW IF EXISTS code_suggestion_daily_events_mv_new"
end
def down
execute <<~SQL
CREATE TABLE code_suggestion_usages
(
`user_id` UInt64 DEFAULT 0,
`event` UInt8 DEFAULT 0,
`namespace_path` String DEFAULT '0/',
`timestamp` DateTime64(6, 'UTC') DEFAULT now64(),
`unique_tracking_id` String DEFAULT '',
`language` LowCardinality(String) DEFAULT '',
`suggestion_size` UInt64 DEFAULT 0,
`branch_name` String DEFAULT ''
)
ENGINE = ReplacingMergeTree
PARTITION BY toYear(timestamp)
ORDER BY (user_id, event, timestamp)
SETTINGS index_granularity = 8192
SQL
execute <<~SQL
CREATE TABLE code_suggestion_daily_events
(
`user_id` UInt64 DEFAULT 0,
`date` Date32 DEFAULT toDate(now64()),
`event` UInt8 DEFAULT 0,
`occurrences` UInt64 DEFAULT 0
)
ENGINE = SummingMergeTree
PARTITION BY toYear(date)
ORDER BY (user_id, date, event)
SETTINGS index_granularity = 64
SQL
execute <<~SQL
CREATE TABLE code_suggestion_daily_events_new
(
`namespace_path` String DEFAULT '0/',
`user_id` UInt64 DEFAULT 0,
`date` Date32 DEFAULT toDate(now64()),
`event` UInt8 DEFAULT 0,
`language` String DEFAULT '',
`suggestions_size_sum` UInt32 DEFAULT 0,
`occurrences` UInt64 DEFAULT 0
)
ENGINE = SummingMergeTree
PARTITION BY toYear(date)
ORDER BY (namespace_path, date, user_id, event, language)
SETTINGS index_granularity = 64
SQL
execute <<~SQL
CREATE MATERIALIZED VIEW code_suggestion_daily_events_mv TO code_suggestion_daily_events
(
`user_id` UInt64,
`date` Date,
`event` UInt8,
`occurrences` UInt8
)
AS SELECT
user_id,
toDate(timestamp) AS date,
event,
1 AS occurrences
FROM code_suggestion_usages
SQL
execute <<~SQL
CREATE MATERIALIZED VIEW code_suggestion_daily_events_mv_new TO code_suggestion_daily_events_new
(
`namespace_path` String,
`user_id` UInt64,
`date` Date,
`event` UInt8,
`language` LowCardinality(String),
`suggestions_size_sum` UInt64,
`occurrences` UInt8
)
AS SELECT
namespace_path,
user_id,
toDate(timestamp) AS date,
event,
language,
suggestion_size AS suggestions_size_sum,
1 AS occurrences
FROM code_suggestion_usages
SQL
end
end

View File

@ -7,6 +7,5 @@ feature_categories:
description: Contains records corresponding to collections in the connected vector store for use by the ActiveContext gem.
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/180558
milestone: '17.9'
gitlab_schema: gitlab_main_cell
exempt_from_sharding: true
gitlab_schema: gitlab_main_cell_local
table_size: small

View File

@ -8,6 +8,5 @@ description: Stores connection configurations for AI active context integrations
Each connection represents a unique integration point with specific adapter settings and options.
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/181400
milestone: '17.10'
gitlab_schema: gitlab_main_cell
exempt_from_sharding: true
table_size: small
gitlab_schema: gitlab_main_cell_local
table_size: small

View File

@ -8,6 +8,5 @@ description: Tracks the state and progress of AI active context migrations.
Each migration is identified by a unique version timestamp and is used for computing or updating collections in ai context abstraction layer.
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/181238
milestone: '17.10'
gitlab_schema: gitlab_main_cell
exempt_from_sharding: true
gitlab_schema: gitlab_main_cell_local
table_size: small

View File

@ -5,4 +5,4 @@ feature_category: team_planning
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/174410
milestone: '17.7'
queued_migration_version: 20241202143623
finalized_by: # version of the migration that finalized this BBM
finalized_by: '20250528232928'

View File

@ -1,9 +0,0 @@
---
migration_job_name: RestoreOptInToGitlabCom
description: We deleted the email_opted_in field from the user table on GitLab.com. This was done by mistake. We would like to restore the values from the temporary table with a backup from Snowflake. We need to restore it to the onboarding_status column in the user_details table.
feature_category: activation
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/165155
milestone: '17.6'
queued_migration_version: 20241004100956
finalize_after: '2024-11-16'
finalized_by: '20250110151716'

View File

@ -1,51 +1,6 @@
---
table_name: instance_integrations
classes:
- Integrations::Instance::Integration
- Integrations::Instance::AmazonQ
- Integrations::Instance::Asana
- Integrations::Instance::Assembla
- Integrations::Instance::Bamboo
- Integrations::Instance::BeyondIdentity
- Integrations::Instance::Bugzilla
- Integrations::Instance::Buildkite
- Integrations::Instance::Clickup
- Integrations::Instance::Confluence
- Integrations::Instance::CustomIssueTracker
- Integrations::Instance::Datadog
- Integrations::Instance::DiffblueCover
- Integrations::Instance::Discord
- Integrations::Instance::DroneCi
- Integrations::Instance::EmailsOnPush
- Integrations::Instance::Ewm
- Integrations::Instance::ExternalWiki
- Integrations::Instance::GitGuardian
- Integrations::Instance::HangoutsChat
- Integrations::Instance::Harbor
- Integrations::Instance::Irker
- Integrations::Instance::Teamcity
- Integrations::Instance::Youtrack
- Integrations::Instance::Jira
- Integrations::Instance::Matrix
- Integrations::Instance::Mattermost
- Integrations::Instance::MattermostSlashCommands
- Integrations::Instance::MicrosoftTeams
- Integrations::Instance::MockMonitoring
- Integrations::Instance::MockCi
- Integrations::Instance::Packagist
- Integrations::Instance::Phorge
- Integrations::Instance::PipelinesEmail
- Integrations::Instance::Pivotaltracker
- Integrations::Instance::Pumble
- Integrations::Instance::Pushover
- Integrations::Instance::Redmine
- Integrations::Instance::Slack
- Integrations::Instance::SlackSlashCommands
- Integrations::Instance::SquashTm
- Integrations::Instance::Telegram
- Integrations::Instance::UnifyCircuit
- Integrations::Instance::WebexTeams
- Integrations::Instance::Zentao
feature_categories:
- integrations
description: Support 3rd party instance-wide integrations

View File

@ -8,14 +8,6 @@ description: Records the change of weight on issues along with timestamps
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21515
milestone: '12.7'
gitlab_schema: gitlab_main_cell
desired_sharding_key:
namespace_id:
references: namespaces
backfill_via:
parent:
foreign_key: issue_id
table: issues
sharding_key: namespace_id
belongs_to: issue
sharding_key:
namespace_id: namespaces
table_size: small
desired_sharding_key_migration_job_name: BackfillResourceWeightEventsNamespaceId

View File

@ -1,45 +0,0 @@
# frozen_string_literal: true
class QueueRestoreOptInToGitlabCom < Gitlab::Database::Migration[2.2]
milestone '17.6'
restrict_gitlab_migration gitlab_schema: :gitlab_main
disable_ddl_transaction!
# https://gitlab.com/gitlab-com/gl-infra/production/-/issues/18367
TEMPORARY_TABLE_NAME = 'temp_user_details_issue18240'
MIGRATION = "RestoreOptInToGitlabCom"
DELAY_INTERVAL = 2.minutes
TABLE_NAME = :user_details
BATCH_COLUMN = :user_id
BATCH_SIZE = 3_000
SUB_BATCH_SIZE = 250
MAX_BATCH_SIZE = 10_000
def up
return unless should_run?
queue_batched_background_migration(
MIGRATION,
TABLE_NAME,
BATCH_COLUMN,
TEMPORARY_TABLE_NAME,
job_interval: DELAY_INTERVAL,
batch_size: BATCH_SIZE,
sub_batch_size: SUB_BATCH_SIZE,
max_batch_size: MAX_BATCH_SIZE
)
end
def down
return unless should_run?
delete_batched_background_migration(MIGRATION, TABLE_NAME, BATCH_COLUMN, [TEMPORARY_TABLE_NAME])
end
private
def should_run?
Gitlab.com_except_jh? && ApplicationRecord.connection.table_exists?(TEMPORARY_TABLE_NAME)
end
end

View File

@ -1,23 +0,0 @@
# frozen_string_literal: true
class FinalizeRestoreOptInToGitlabCom < Gitlab::Database::Migration[2.2]
milestone '17.9'
disable_ddl_transaction!
restrict_gitlab_migration gitlab_schema: :gitlab_main
def up
return unless Gitlab.com_except_jh?
ensure_batched_background_migration_is_finished(
job_class_name: 'RestoreOptInToGitlabCom',
table_name: :user_details,
column_name: :user_id,
job_arguments: ['temp_user_details_issue18240'],
finalize: true
)
end
def down; end
end

View File

@ -0,0 +1,14 @@
# frozen_string_literal: true
class AddResourceWeightEventsNamespaceIdNotNull < Gitlab::Database::Migration[2.3]
milestone '18.1'
disable_ddl_transaction!
def up
add_not_null_constraint :resource_weight_events, :namespace_id
end
def down
remove_not_null_constraint :resource_weight_events, :namespace_id
end
end

View File

@ -0,0 +1,21 @@
# frozen_string_literal: true
class FinalizeHkBackfillWorkItemProgressesNamespaceId < Gitlab::Database::Migration[2.3]
milestone '18.1'
disable_ddl_transaction!
restrict_gitlab_migration gitlab_schema: :gitlab_main_cell
def up
ensure_batched_background_migration_is_finished(
job_class_name: 'BackfillWorkItemProgressesNamespaceId',
table_name: :work_item_progresses,
column_name: :issue_id,
job_arguments: [:namespace_id, :issues, :namespace_id, :issue_id],
finalize: true
)
end
def down; end
end

View File

@ -1 +0,0 @@
08147a6cb23f2c47c51540f86da313b5e5e7d2102bdc53797b67f9d697773a81

View File

@ -1 +0,0 @@
5d04a86bf20d62365968cf29d915aaf09fcd52d83646e1246147ac1f7b45b0c1

Some files were not shown because too many files have changed in this diff Show More