diff --git a/.gitlab/ci/rails.gitlab-ci.yml b/.gitlab/ci/rails.gitlab-ci.yml index 96793b1f5d4..098c5a8a5e1 100644 --- a/.gitlab/ci/rails.gitlab-ci.yml +++ b/.gitlab/ci/rails.gitlab-ci.yml @@ -765,41 +765,46 @@ rspec system pg14-as-if-foss clusterwide-db: - .clusterwide-db - .rails:rules:clusterwide-db -rspec-ee unit gitlab-duo-chat pg14: - variables: - REAL_AI_REQUEST: "true" - RSPEC_RETRY_RETRY_COUNT: 0 +.rspec-ee-base-gitlab-duo: extends: - .rspec-ee-base-pg14 - - .rails:rules:ee-gitlab-duo-chat-base - parallel: - matrix: - - DUO_RSPEC: ["lib/gitlab/llm/chain/agents/zero_shot/executor_real_requests_spec.rb", "support_specs/helpers/chat_qa_evaluation_helpers_spec.rb"] + variables: + REAL_AI_REQUEST: "true" + +rspec-ee unit gitlab-duo-chat-zeroshot pg14: + extends: + - .rspec-ee-base-gitlab-duo + - .rails:rules:ee-gitlab-duo-chat-optional script: - !reference [.base-script, script] - - bundle exec rspec -Ispec -rspec_helper --failure-exit-code 0 --tag real_ai_request --color -- ee/spec/${DUO_RSPEC} + - rspec_paralellized_job "--tag zeroshot_executor" + +rspec-ee unit gitlab-duo-chat-qa-fast pg14: + extends: + - .rspec-ee-base-gitlab-duo + - .rails:rules:ee-gitlab-duo-chat-qa-fast + script: + - !reference [.base-script, script] + - rspec_paralellized_job "--tag fast_chat_qa_evaluation" rspec-ee unit gitlab-duo-chat-qa pg14: variables: - REAL_AI_REQUEST: "true" + QA_EVAL_REPORT_FILENAME: "qa_evaluation_report.md" RSPEC_RETRY_RETRY_COUNT: 0 extends: - - .rspec-ee-base-pg14 - - .rails:rules:ee-gitlab-duo-chat-base - parallel: - matrix: - - DUO_RSPEC: ["qa_epic_spec.rb", "qa_issue_spec.rb"] + - .rspec-ee-base-gitlab-duo + - .rails:rules:ee-gitlab-duo-chat-qa-full script: - !reference [.base-script, script] - source ./scripts/utils.sh - install_gitlab_gem - - bundle exec rspec -Ispec -rspec_helper --failure-exit-code 0 --tag real_ai_request --color -- ee/spec/lib/gitlab/llm/chain/agents/zero_shot/${DUO_RSPEC} + - bundle exec rspec -Ispec -rspec_helper --failure-exit-code 0 --color --tag chat_qa_evaluation -- ee/spec/lib/gitlab/llm/chain/agents/zero_shot/qa_evaluation_spec.rb - ./scripts/duo_chat/reporter.rb artifacts: expire_in: 5d paths: - tmp/duo_chat/qa*.json - - "${DUO_RSPEC}.md" + - "${QA_EVAL_REPORT_FILENAME}" rspec-ee migration pg14: extends: diff --git a/.gitlab/ci/rules.gitlab-ci.yml b/.gitlab/ci/rules.gitlab-ci.yml index f9690b0247c..6a5bade71f4 100644 --- a/.gitlab/ci/rules.gitlab-ci.yml +++ b/.gitlab/ci/rules.gitlab-ci.yml @@ -2125,8 +2125,28 @@ when: never - if: '$VERTEX_AI_CREDENTIALS == null' when: never + - <<: *if-fork-merge-request + when: never + +.rails:rules:ee-gitlab-duo-chat-optional: + rules: + - !reference [".rails:rules:ee-gitlab-duo-chat-base", rules] + - <<: *if-merge-request + changes: *backend-patterns + when: manual + allow_failure: true + +.rails:rules:ee-gitlab-duo-chat-qa-fast: + rules: + - !reference [".rails:rules:ee-gitlab-duo-chat-base", rules] - <<: *if-merge-request changes: *ai-patterns + +.rails:rules:ee-gitlab-duo-chat-qa-full: + rules: + - !reference [".rails:rules:ee-gitlab-duo-chat-optional", rules] + - <<: *if-default-branch-refs + changes: *setup-test-env-patterns when: manual allow_failure: true diff --git a/.rubocop_todo/rspec/verified_doubles.yml b/.rubocop_todo/rspec/verified_doubles.yml index d26067d2783..d907b372477 100644 --- a/.rubocop_todo/rspec/verified_doubles.yml +++ b/.rubocop_todo/rspec/verified_doubles.yml @@ -325,6 +325,7 @@ RSpec/VerifiedDoubles: - 'spec/lib/banzai/render_context_spec.rb' - 'spec/lib/banzai/renderer_spec.rb' - 'spec/lib/bitbucket/connection_spec.rb' + - 'spec/lib/bitbucket/exponential_backoff_spec.rb' - 'spec/lib/bitbucket/paginator_spec.rb' - 'spec/lib/bitbucket_server/paginator_spec.rb' - 'spec/lib/bulk_imports/clients/http_spec.rb' diff --git a/app/assets/javascripts/graphql_shared/issuable_client.js b/app/assets/javascripts/graphql_shared/issuable_client.js index 9537c9ef8a6..d0ba34b6127 100644 --- a/app/assets/javascripts/graphql_shared/issuable_client.js +++ b/app/assets/javascripts/graphql_shared/issuable_client.js @@ -146,7 +146,7 @@ export const config = { }, IssueConnection: { merge(existing = { nodes: [] }, incoming, { args }) { - if (!args.after) { + if (!args?.after) { return incoming; } return { diff --git a/app/assets/javascripts/graphql_shared/possible_types.json b/app/assets/javascripts/graphql_shared/possible_types.json index ee5f8c2ac2f..4ef0d067030 100644 --- a/app/assets/javascripts/graphql_shared/possible_types.json +++ b/app/assets/javascripts/graphql_shared/possible_types.json @@ -150,6 +150,7 @@ "User": [ "AddOnUser", "AutocompletedUser", + "CurrentUser", "MergeRequestAssignee", "MergeRequestAuthor", "MergeRequestParticipant", diff --git a/app/assets/javascripts/lib/utils/datetime/locale_dateformat.js b/app/assets/javascripts/lib/utils/datetime/locale_dateformat.js index 81922c4da1d..f1446fa5ac4 100644 --- a/app/assets/javascripts/lib/utils/datetime/locale_dateformat.js +++ b/app/assets/javascripts/lib/utils/datetime/locale_dateformat.js @@ -3,25 +3,36 @@ import { createDateTimeFormat } from '~/locale'; /** * Format a Date with the help of {@link DateTimeFormat.asDateTime} * - * Note: In case you can use localDateFormat.asDateTime directly, please do that. + * Note: In case you can use localeDateFormat.asDateTime directly, please do that. * * @example - * localDateFormat[DATE_WITH_TIME_FORMAT].format(date) // returns 'Jul 6, 2020, 2:43 PM' - * localDateFormat[DATE_WITH_TIME_FORMAT].formatRange(date, date) // returns 'Jul 6, 2020, 2:45PM – 8:43 PM' + * localeDateFormat[DATE_WITH_TIME_FORMAT].format(date) // returns 'Jul 6, 2020, 2:43 PM' + * localeDateFormat[DATE_WITH_TIME_FORMAT].formatRange(date, date) // returns 'Jul 6, 2020, 2:45PM – 8:43 PM' */ export const DATE_WITH_TIME_FORMAT = 'asDateTime'; + +/** + * Format a Date with the help of {@link DateTimeFormat.asDateTimeFull} + * + * Note: In case you can use localeDateFormat.asDateTimeFull directly, please do that. + * + * @example + * localeDateFormat[DATE_TIME_FULL_FORMAT].format(date) // returns 'July 6, 2020 at 2:43:12 PM GMT' + */ +export const DATE_TIME_FULL_FORMAT = 'asDateTimeFull'; + /** * Format a Date with the help of {@link DateTimeFormat.asDate} * - * Note: In case you can use localDateFormat.asDate directly, please do that. + * Note: In case you can use localeDateFormat.asDate directly, please do that. * * @example - * localDateFormat[DATE_ONLY_FORMAT].format(date) // returns 'Jul 05, 2023' - * localDateFormat[DATE_ONLY_FORMAT].formatRange(date, date) // returns 'Jul 05 - Jul 07, 2023' + * localeDateFormat[DATE_ONLY_FORMAT].format(date) // returns 'Jul 05, 2023' + * localeDateFormat[DATE_ONLY_FORMAT].formatRange(date, date) // returns 'Jul 05 - Jul 07, 2023' */ export const DATE_ONLY_FORMAT = 'asDate'; export const DEFAULT_DATE_TIME_FORMAT = DATE_WITH_TIME_FORMAT; -export const DATE_TIME_FORMATS = [DATE_WITH_TIME_FORMAT, DATE_ONLY_FORMAT]; +export const DATE_TIME_FORMATS = [DATE_WITH_TIME_FORMAT, DATE_TIME_FULL_FORMAT, DATE_ONLY_FORMAT]; /** * The DateTimeFormat utilities support formatting a number of types, @@ -54,7 +65,7 @@ class DateTimeFormat { * @example * // en-US: returns something like Jul 6, 2020, 2:43 PM * // en-GB: returns something like 6 Jul 2020, 14:43 - * localDateFormat.asDateTime.format(date) + * localeDateFormat.asDateTime.format(date) * * @returns {DateTimeFormatter} */ @@ -68,6 +79,32 @@ class DateTimeFormat { }) ); } + /** + * Locale aware formatter to a complete date time. + * + * This is needed if you need to convey a full timestamp including timezone and seconds. + * + * This is mainly used in tooltips. Use {@link DateTimeFormat.asDateTime} + * if you don't need to show all the information. + * + * + * @example + * // en-US: returns something like July 6, 2020 at 2:43:12 PM GMT + * // en-GB: returns something like 6 July 2020 at 14:43:12 GMT + * localeDateFormat.asDateTimeFull.format(date) + * + * @returns {DateTimeFormatter} + */ + get asDateTimeFull() { + return ( + this.#formatters[DATE_TIME_FULL_FORMAT] || + this.#createFormatter(DATE_TIME_FULL_FORMAT, { + dateStyle: 'long', + timeStyle: 'long', + hourCycle: DateTimeFormat.#hourCycle, + }) + ); + } /** * Locale aware formatter to display a only the date. @@ -77,12 +114,12 @@ class DateTimeFormat { * @example * // en-US: returns something like Jul 6, 2020 * // en-GB: returns something like 6 Jul 2020 - * localDateFormat.asDate.format(date) + * localeDateFormat.asDate.format(date) * * @example * // en-US: returns something like Jul 6 – 7, 2020 * // en-GB: returns something like 6-7 Jul 2020 - * localDateFormat.asDate.formatRange(date, date2) + * localeDateFormat.asDate.formatRange(date, date2) * * @returns {DateTimeFormatter} */ @@ -177,6 +214,7 @@ class DateTimeFormat { * * DateTime (showing both date and times): * - {@link DateTimeFormat.asDateTime localeDateFormat.asDateTime} - the default format for date times + * - {@link DateTimeFormat.asDateTimeFull localeDateFormat.asDateTimeFull} - full format, including timezone and seconds * * Date (showing date only): * - {@link DateTimeFormat.asDate localeDateFormat.asDate} - the default format for a date diff --git a/app/assets/javascripts/lib/utils/datetime/timeago_utility.js b/app/assets/javascripts/lib/utils/datetime/timeago_utility.js index a25acd5c711..3a94b26ee35 100644 --- a/app/assets/javascripts/lib/utils/datetime/timeago_utility.js +++ b/app/assets/javascripts/lib/utils/datetime/timeago_utility.js @@ -1,7 +1,6 @@ import * as timeago from 'timeago.js'; import { languageCode, s__ } from '~/locale'; import { DEFAULT_DATE_TIME_FORMAT, localeDateFormat } from '~/lib/utils/datetime/locale_dateformat'; -import { formatDate } from './date_format_utility'; /** * Timeago uses underscores instead of dashes to separate language from country code. @@ -130,7 +129,7 @@ export const localTimeAgo = (elements, updateTooltip = true) => { function addTimeAgoTooltip() { elements.forEach((el) => { // Recreate with custom template - el.setAttribute('title', formatDate(el.dateTime)); + el.setAttribute('title', localeDateFormat.asDateTimeFull.format(el.dateTime)); }); } diff --git a/app/assets/javascripts/search/sidebar/components/archived_filter/index.vue b/app/assets/javascripts/search/sidebar/components/archived_filter/index.vue index 914ff99075b..0308db17dc4 100644 --- a/app/assets/javascripts/search/sidebar/components/archived_filter/index.vue +++ b/app/assets/javascripts/search/sidebar/components/archived_filter/index.vue @@ -48,9 +48,9 @@ export default {