From 3b69a04945341516a2ed6a291769c50fe04336df Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Mon, 12 Sep 2022 21:10:38 +0000 Subject: [PATCH] Add latest changes from gitlab-org/gitlab@master --- .gitlab/ci/static-analysis.gitlab-ci.yml | 11 +- .../expiration_interval_description.vue | 52 ++++ .../components/expiration_intervals.vue | 123 +++++++++ .../runner_token_expiration/index.js | 32 +++ .../admin/application_settings/ci_cd/index.js | 3 + .../pages/profiles/show/emoji_menu.js | 19 -- .../javascripts/pages/profiles/show/index.js | 98 +------ .../components/graph/graph_component.vue | 2 +- .../components/graph/job_group_dropdown.vue | 4 +- .../graph/stage_column_component.vue | 3 +- app/assets/javascripts/profile/profile.js | 24 ++ .../runner/components/runner_detail.vue | 9 +- .../runner/components/runner_details.vue | 46 +++- .../runner_details_shared.fragment.graphql | 1 + app/assets/javascripts/runner/utils.js | 11 + .../javascripts/set_status_modal/constants.js | 14 + .../set_status_modal/set_status_form.vue | 70 +++-- .../set_status_modal_wrapper.vue | 22 +- .../user_profile_set_status_wrapper.vue | 100 ++++++++ .../javascripts/set_status_modal/utils.js | 5 +- .../components/work_item_description.vue | 10 +- .../update_work_item_widgets.mutation.graphql | 10 - app/controllers/admin/runners_controller.rb | 10 +- app/controllers/groups/runners_controller.rb | 6 +- app/controllers/profiles_controller.rb | 2 +- .../projects/runners_controller.rb | 6 +- app/graphql/mutations/ci/runner/update.rb | 5 +- app/helpers/application_settings_helper.rb | 8 + app/models/user_status.rb | 4 + .../ci/runners/update_runner_service.rb | 9 +- .../system_notes/issuables_service.rb | 11 +- .../application_settings/_ci_cd.html.haml | 2 + app/views/profiles/show.html.haml | 41 +-- .../deprecations/15-4-cs-docker-variables.yml | 11 + doc/ci/runners/configure_runners.md | 40 +++ doc/ci/yaml/artifacts_reports.md | 3 +- doc/development/backend/ruby_style_guide.md | 103 ++++++++ doc/development/newlines_styleguide.md | 111 +------- doc/development/rake_tasks.md | 14 + doc/install/cloud_native/index.md | 27 +- doc/update/deprecations.md | 14 + doc/user/profile/index.md | 2 +- lib/api/ci/runners.rb | 2 +- .../templates/Jobs/SAST.latest.gitlab-ci.yml | 2 +- .../importer/events/changed_reviewer.rb | 54 ++++ .../importer/issue_event_importer.rb | 2 + .../representation/issue_event.rb | 7 +- lib/gitlab/github_import/user_finder.rb | 4 + lib/tasks/rubocop.rake | 13 + locale/gitlab.pot | 60 +++-- qa/lib/gitlab/page/admin/subscription.rb | 9 +- rubocop/check_graceful_task.rb | 83 ++++++ rubocop/cop_todo.rb | 6 +- rubocop/formatter/graceful_formatter.rb | 109 ++++++++ rubocop/formatter/todo_formatter.rb | 24 +- .../admin/runners_controller_spec.rb | 4 +- spec/controllers/profiles_controller_spec.rb | 8 +- .../profiles/user_edit_profile_spec.rb | 20 +- .../frontend/__helpers__/dl_locator_helper.js | 13 +- .../emoji/components/category_spec.js | 8 +- .../components/app_spec.js | 4 +- .../components/project_dropdown_spec.js | 10 +- .../recent_searches_dropdown_content_spec.js | 6 +- .../frequent_items_list_item_spec.js | 4 +- .../frequent_items_search_input_spec.js | 2 +- .../components/group_dropdown_spec.js | 2 +- .../components/import_table_spec.js | 18 +- .../components/import_target_cell_spec.js | 4 +- .../components/bitbucket_status_table_spec.js | 10 +- .../components/import_projects_table_spec.js | 14 +- .../provider_repo_table_row_spec.js | 16 +- .../components/incidents_list_spec.js | 10 +- .../incidents_settings_tabs_spec.js | 4 +- .../edit/components/trigger_fields_spec.js | 2 +- .../import_project_members_modal_spec.js | 2 +- .../components/issue_milestone_spec.js | 2 +- .../components/issue_token_spec.js | 6 +- .../components/related_issues_block_spec.js | 4 +- .../components/related_issues_list_spec.js | 4 +- .../components/issue_card_time_info_spec.js | 10 +- .../jira_issues_import_status_app_spec.js | 10 +- .../components/title_suggestions_item_spec.js | 4 +- .../issues/show/components/app_spec.js | 2 +- .../components/fields/description_spec.js | 2 +- .../show/components/fields/title_spec.js | 2 +- .../show/components/header_actions_spec.js | 4 +- .../incidents/highlight_bar_spec.js | 2 +- .../incidents/incident_tabs_spec.js | 6 +- .../sentry_error_stack_trace_spec.js | 8 +- .../components/jira_import_app_spec.js | 10 +- .../components/jira_import_form_spec.js | 2 +- .../components/jira_import_progress_spec.js | 2 +- .../components/jira_import_setup_spec.js | 2 +- .../components/delete_label_modal_spec.js | 2 +- .../components/avatars/user_avatar_spec.js | 2 +- .../merge_conflict_resolver_app_spec.js | 4 +- .../components/milestone_combobox_spec.js | 4 +- .../components/top_nav_dropdown_menu_spec.js | 2 +- .../nav/components/top_nav_menu_item_spec.js | 2 +- .../notebook/cells/output/latex_spec.js | 2 +- .../notes/components/note_header_spec.js | 2 +- .../custom_notifications_modal_spec.js | 10 +- .../components/notifications_dropdown_spec.js | 6 +- .../components/metrics_settings_spec.js | 14 +- .../explorer/components/delete_button_spec.js | 4 +- .../details_page/delete_alert_spec.js | 4 +- .../partial_cleanup_alert_spec.js | 2 +- .../details_page/status_alert_spec.js | 4 +- .../details_page/tags_list_row_spec.js | 2 +- .../list_page/cleanup_status_spec.js | 2 +- .../list_page/image_list_row_spec.js | 2 +- .../components/list_page/image_list_spec.js | 2 +- .../list_page/registry_header_spec.js | 2 +- .../explorer/pages/details_spec.js | 20 +- .../explorer/pages/index_spec.js | 2 +- .../components/details/artifacts_list_spec.js | 6 +- .../list/harbor_list_header_spec.js | 4 +- .../components/list/harbor_list_row_spec.js | 4 +- .../harbor_registry/pages/details_spec.js | 8 +- .../harbor_registry/pages/index_spec.js | 2 +- .../components/details/components/app_spec.js | 4 +- .../details/components/package_files_spec.js | 4 +- .../components/package_history_spec.js | 4 +- .../components/infrastructure_title_spec.js | 4 +- .../list/components/packages_list_app_spec.js | 8 +- .../list/components/packages_list_spec.js | 10 +- .../infrastructure_icon_and_name_spec.js | 2 +- .../components/list/package_list_row_spec.js | 6 +- .../components/list/packages_title_spec.js | 4 +- .../list/tokens/package_type_token_spec.js | 2 +- .../components/cleanup_image_tags_spec.js | 4 +- .../container_expiration_policy_form_spec.js | 2 +- .../container_expiration_policy_spec.js | 6 +- .../components/expiration_dropdown_spec.js | 4 +- .../components/expiration_input_spec.js | 6 +- .../components/expiration_run_text_spec.js | 4 +- .../components/expiration_toggle_spec.js | 2 +- .../packages_cleanup_policy_form_spec.js | 2 +- .../components/registry_settings_app_spec.js | 4 +- .../shared/components/cli_commands_spec.js | 2 +- .../components/package_icon_and_name_spec.js | 2 +- .../bitbucket_server_status_table_spec.js | 2 +- .../bulk_imports_history_app_spec.js | 8 +- .../components/import_error_details_spec.js | 6 +- .../pages/profiles/show/emoji_menu_spec.js | 115 --------- .../charts/components/pipeline_charts_spec.js | 2 +- .../runner/components/runner_details_spec.js | 30 ++- spec/frontend/runner/utils_spec.js | 13 +- .../set_status_modal_wrapper_spec.js | 37 +-- .../user_profile_set_status_wrapper_spec.js | 156 ++++++++++++ spec/frontend/set_status_modal/utils_spec.js | 3 +- .../assignees/user_name_with_status_spec.js | 2 +- .../user_popover/user_popover_spec.js | 2 +- .../components/work_item_description_spec.js | 10 +- spec/frontend/work_items/mock_data.js | 11 - .../importer/events/changed_reviewer_spec.rb | 101 ++++++++ .../importer/issue_event_importer_spec.rb | 14 + .../importer/issue_events_importer_spec.rb | 4 +- .../representation/issue_event_spec.rb | 44 +++- .../gitlab/github_import/user_finder_spec.rb | 12 + spec/models/ci/runner_spec.rb | 2 +- spec/models/user_status_spec.rb | 8 + spec/rubocop/check_graceful_task_spec.rb | 125 +++++++++ spec/rubocop/cop_todo_spec.rb | 20 +- .../formatter/graceful_formatter_spec.rb | 239 ++++++++++++++++++ spec/rubocop/formatter/todo_formatter_spec.rb | 92 +++++++ .../ci/runners/update_runner_service_spec.rb | 88 +++---- spec/support/matchers/abort_matcher.rb | 17 +- spec/support/rspec.rb | 1 + spec/tasks/rubocop_rake_spec.rb | 38 +++ 170 files changed, 2269 insertions(+), 855 deletions(-) create mode 100644 app/assets/javascripts/admin/application_settings/runner_token_expiration/components/expiration_interval_description.vue create mode 100644 app/assets/javascripts/admin/application_settings/runner_token_expiration/components/expiration_intervals.vue create mode 100644 app/assets/javascripts/admin/application_settings/runner_token_expiration/index.js create mode 100644 app/assets/javascripts/pages/admin/application_settings/ci_cd/index.js delete mode 100644 app/assets/javascripts/pages/profiles/show/emoji_menu.js create mode 100644 app/assets/javascripts/set_status_modal/constants.js create mode 100644 app/assets/javascripts/set_status_modal/user_profile_set_status_wrapper.vue delete mode 100644 app/assets/javascripts/work_items/graphql/update_work_item_widgets.mutation.graphql create mode 100644 data/deprecations/15-4-cs-docker-variables.yml create mode 100644 lib/gitlab/github_import/importer/events/changed_reviewer.rb create mode 100644 rubocop/check_graceful_task.rb create mode 100644 rubocop/formatter/graceful_formatter.rb delete mode 100644 spec/frontend/pages/profiles/show/emoji_menu_spec.js create mode 100644 spec/frontend/set_status_modal/user_profile_set_status_wrapper_spec.js create mode 100644 spec/lib/gitlab/github_import/importer/events/changed_reviewer_spec.rb create mode 100644 spec/rubocop/check_graceful_task_spec.rb create mode 100644 spec/rubocop/formatter/graceful_formatter_spec.rb diff --git a/.gitlab/ci/static-analysis.gitlab-ci.yml b/.gitlab/ci/static-analysis.gitlab-ci.yml index b2cbfedbfbd..cf25a33ed62 100644 --- a/.gitlab/ci/static-analysis.gitlab-ci.yml +++ b/.gitlab/ci/static-analysis.gitlab-ci.yml @@ -19,7 +19,10 @@ update-static-analysis-cache: - .shared:rules:update-cache stage: prepare script: - - run_timed_command "bundle exec rubocop --parallel" # For the moment we only cache `tmp/rubocop_cache` so we don't need to run all the tasks. + # Silence cop offenses for rules with "grace period". + # This will notify Slack if offenses were silenced. + # For the moment we only cache `tmp/rubocop_cache` so we don't need to run all the tasks. + - run_timed_command "bundle exec rake rubocop:check:graceful" static-analysis: extends: @@ -121,7 +124,11 @@ rubocop: - | # For non-merge request, or when RUN_ALL_RUBOCOP is 'true', run all RuboCop rules if [ -z "${CI_MERGE_REQUEST_IID}" ] || [ "${RUN_ALL_RUBOCOP}" == "true" ]; then - run_timed_command "bundle exec rubocop --parallel" + # Silence cop offenses for rules with "grace period". + # We won't notify Slack if offenses were silenced to avoid frequent messages. + # Job `update-static-analysis-cache` takes care of Slack notifications every 2 hours. + unset CI_SLACK_WEBHOOK_URL + run_timed_command "bundle exec rake rubocop:check:graceful" else run_timed_command "bundle exec rubocop --parallel --force-exclusion $(cat ${RSPEC_CHANGED_FILES_PATH})" fi diff --git a/app/assets/javascripts/admin/application_settings/runner_token_expiration/components/expiration_interval_description.vue b/app/assets/javascripts/admin/application_settings/runner_token_expiration/components/expiration_interval_description.vue new file mode 100644 index 00000000000..2f74b44625f --- /dev/null +++ b/app/assets/javascripts/admin/application_settings/runner_token_expiration/components/expiration_interval_description.vue @@ -0,0 +1,52 @@ + + diff --git a/app/assets/javascripts/admin/application_settings/runner_token_expiration/components/expiration_intervals.vue b/app/assets/javascripts/admin/application_settings/runner_token_expiration/components/expiration_intervals.vue new file mode 100644 index 00000000000..371a26d2664 --- /dev/null +++ b/app/assets/javascripts/admin/application_settings/runner_token_expiration/components/expiration_intervals.vue @@ -0,0 +1,123 @@ + + diff --git a/app/assets/javascripts/admin/application_settings/runner_token_expiration/index.js b/app/assets/javascripts/admin/application_settings/runner_token_expiration/index.js new file mode 100644 index 00000000000..79d7ff0451a --- /dev/null +++ b/app/assets/javascripts/admin/application_settings/runner_token_expiration/index.js @@ -0,0 +1,32 @@ +import Vue from 'vue'; +import { parseInterval } from '~/runner/utils'; +import ExpirationIntervals from './components/expiration_intervals.vue'; + +const initRunnerTokenExpirationIntervals = (selector = '#js-runner-token-expiration-intervals') => { + const el = document.querySelector(selector); + + if (!el) { + return null; + } + + const { + instanceRunnerTokenExpirationInterval, + groupRunnerTokenExpirationInterval, + projectRunnerTokenExpirationInterval, + } = el.dataset; + + return new Vue({ + el, + render(h) { + return h(ExpirationIntervals, { + props: { + instanceRunnerExpirationInterval: parseInterval(instanceRunnerTokenExpirationInterval), + groupRunnerExpirationInterval: parseInterval(groupRunnerTokenExpirationInterval), + projectRunnerExpirationInterval: parseInterval(projectRunnerTokenExpirationInterval), + }, + }); + }, + }); +}; + +export default initRunnerTokenExpirationIntervals; diff --git a/app/assets/javascripts/pages/admin/application_settings/ci_cd/index.js b/app/assets/javascripts/pages/admin/application_settings/ci_cd/index.js new file mode 100644 index 00000000000..9b6fba9876e --- /dev/null +++ b/app/assets/javascripts/pages/admin/application_settings/ci_cd/index.js @@ -0,0 +1,3 @@ +import initRunnerTokenExpirationIntervals from '~/admin/application_settings/runner_token_expiration/index'; + +initRunnerTokenExpirationIntervals(); diff --git a/app/assets/javascripts/pages/profiles/show/emoji_menu.js b/app/assets/javascripts/pages/profiles/show/emoji_menu.js deleted file mode 100644 index 286c1f1e929..00000000000 --- a/app/assets/javascripts/pages/profiles/show/emoji_menu.js +++ /dev/null @@ -1,19 +0,0 @@ -import '~/commons/bootstrap'; -import { AwardsHandler } from '~/awards_handler'; - -class EmojiMenu extends AwardsHandler { - constructor(emoji, toggleButtonSelector, menuClass, selectEmojiCallback) { - super(emoji); - - this.selectEmojiCallback = selectEmojiCallback; - this.toggleButtonSelector = toggleButtonSelector; - this.menuClass = menuClass; - } - - postEmoji($emojiButton, awardUrl, selectedEmoji, callback) { - this.selectEmojiCallback(selectedEmoji, this.emoji.glEmojiTag(selectedEmoji)); - callback(); - } -} - -export default EmojiMenu; diff --git a/app/assets/javascripts/pages/profiles/show/index.js b/app/assets/javascripts/pages/profiles/show/index.js index ccdb9e991ca..96ea7329e6e 100644 --- a/app/assets/javascripts/pages/profiles/show/index.js +++ b/app/assets/javascripts/pages/profiles/show/index.js @@ -1,90 +1,18 @@ import emojiRegex from 'emoji-regex'; -import $ from 'jquery'; -import GfmAutoComplete from 'ee_else_ce/gfm_auto_complete'; -import * as Emoji from '~/emoji'; -import createFlash from '~/flash'; import { __ } from '~/locale'; -import EmojiMenu from './emoji_menu'; +import { initSetStatusForm } from '~/profile/profile'; -const defaultStatusEmoji = 'speech_balloon'; -const toggleEmojiMenuButtonSelector = '.js-toggle-emoji-menu'; -const toggleEmojiMenuButton = document.querySelector(toggleEmojiMenuButtonSelector); -const statusEmojiField = document.getElementById('js-status-emoji-field'); -const statusMessageField = document.getElementById('js-status-message-field'); - -const toggleNoEmojiPlaceholder = (isVisible) => { - const placeholderElement = document.getElementById('js-no-emoji-placeholder'); - placeholderElement.classList.toggle('hidden', !isVisible); -}; - -const findStatusEmoji = () => toggleEmojiMenuButton.querySelector('gl-emoji'); -const removeStatusEmoji = () => { - const statusEmoji = findStatusEmoji(); - if (statusEmoji) { - statusEmoji.remove(); - } -}; - -const selectEmojiCallback = (emoji, emojiTag) => { - statusEmojiField.value = emoji; - toggleNoEmojiPlaceholder(false); - removeStatusEmoji(); - // eslint-disable-next-line no-unsanitized/property - toggleEmojiMenuButton.innerHTML += emojiTag; -}; - -const clearEmojiButton = document.getElementById('js-clear-user-status-button'); -clearEmojiButton.addEventListener('click', () => { - statusEmojiField.value = ''; - statusMessageField.value = ''; - removeStatusEmoji(); - toggleNoEmojiPlaceholder(true); -}); - -const emojiAutocomplete = new GfmAutoComplete(); -emojiAutocomplete.setup($(statusMessageField), { emojis: true }); +initSetStatusForm(); const userNameInput = document.getElementById('user_name'); -userNameInput.addEventListener('input', () => { - const EMOJI_REGEX = emojiRegex(); - if (EMOJI_REGEX.test(userNameInput.value)) { - // set field to invalid so it gets detected by GlFieldErrors - userNameInput.setCustomValidity(__('Invalid field')); - } else { - userNameInput.setCustomValidity(''); - } -}); - -Emoji.initEmojiMap() - .then(() => { - const emojiMenu = new EmojiMenu( - Emoji, - toggleEmojiMenuButtonSelector, - 'js-status-emoji-menu', - selectEmojiCallback, - ); - emojiMenu.bindEvents(); - - const defaultEmojiTag = Emoji.glEmojiTag(defaultStatusEmoji); - statusMessageField.addEventListener('input', () => { - const hasStatusMessage = statusMessageField.value.trim() !== ''; - const statusEmoji = findStatusEmoji(); - if (hasStatusMessage && statusEmoji) { - return; - } - - if (hasStatusMessage) { - toggleNoEmojiPlaceholder(false); - // eslint-disable-next-line no-unsanitized/property - toggleEmojiMenuButton.innerHTML += defaultEmojiTag; - } else if (statusEmoji.dataset.name === defaultStatusEmoji) { - toggleNoEmojiPlaceholder(true); - removeStatusEmoji(); - } - }); - }) - .catch(() => - createFlash({ - message: __('Failed to load emoji list.'), - }), - ); +if (userNameInput) { + userNameInput.addEventListener('input', () => { + const EMOJI_REGEX = emojiRegex(); + if (EMOJI_REGEX.test(userNameInput.value)) { + // set field to invalid so it gets detected by GlFieldErrors + userNameInput.setCustomValidity(__('Invalid field')); + } else { + userNameInput.setCustomValidity(''); + } + }); +} diff --git a/app/assets/javascripts/pipelines/components/graph/graph_component.vue b/app/assets/javascripts/pipelines/components/graph/graph_component.vue index 31a34ab4fb5..1a05710a13e 100644 --- a/app/assets/javascripts/pipelines/components/graph/graph_component.vue +++ b/app/assets/javascripts/pipelines/components/graph/graph_component.vue @@ -170,7 +170,7 @@ export default { ref="mainPipelineContainer" class="gl-display-flex gl-position-relative gl-bg-gray-10 gl-white-space-nowrap" :class="{ - 'gl-pipeline-min-h gl-py-5 gl-overflow-auto gl-border-t-solid gl-border-t-1 gl-border-gray-100': !isLinkedPipeline, + 'gl-pipeline-min-h gl-py-5 gl-overflow-auto': !isLinkedPipeline, }" > diff --git a/app/assets/javascripts/pipelines/components/graph/job_group_dropdown.vue b/app/assets/javascripts/pipelines/components/graph/job_group_dropdown.vue index 8d764fad0c5..02d0c07ea54 100644 --- a/app/assets/javascripts/pipelines/components/graph/job_group_dropdown.vue +++ b/app/assets/javascripts/pipelines/components/graph/job_group_dropdown.vue @@ -82,7 +82,9 @@ export default { :stage-name="stageName" /> -
{{ group.size }}
+
+ {{ group.size }} +
diff --git a/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue b/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue index 42988e96692..4aec28295bd 100644 --- a/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue +++ b/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue @@ -64,8 +64,7 @@ export default { }, }, jobClasses: [ - 'gl-py-3', - 'gl-px-4', + 'gl-p-3', 'gl-border-gray-100', 'gl-border-solid', 'gl-border-1', diff --git a/app/assets/javascripts/profile/profile.js b/app/assets/javascripts/profile/profile.js index 064bcf8e4c4..af5beeb686c 100644 --- a/app/assets/javascripts/profile/profile.js +++ b/app/assets/javascripts/profile/profile.js @@ -1,11 +1,14 @@ import $ from 'jquery'; +import Vue from 'vue'; import { VARIANT_DANGER, VARIANT_INFO, createAlert } from '~/flash'; import axios from '~/lib/utils/axios_utils'; import { parseBoolean } from '~/lib/utils/common_utils'; +import { parseRailsFormFields } from '~/lib/utils/forms'; import { Rails } from '~/lib/utils/rails_ujs'; import TimezoneDropdown, { formatTimezone, } from '~/pages/projects/pipeline_schedules/shared/components/timezone_dropdown'; +import UserProfileSetStatusWrapper from '~/set_status_modal/user_profile_set_status_wrapper.vue'; export default class Profile { constructor({ form } = {}) { @@ -116,3 +119,24 @@ export default class Profile { } } } + +export const initSetStatusForm = () => { + const el = document.getElementById('js-user-profile-set-status-form'); + + if (!el) { + return null; + } + + const fields = parseRailsFormFields(el); + + return new Vue({ + el, + name: 'UserProfileStatusForm', + provide: { + fields, + }, + render(h) { + return h(UserProfileSetStatusWrapper); + }, + }); +}; diff --git a/app/assets/javascripts/runner/components/runner_detail.vue b/app/assets/javascripts/runner/components/runner_detail.vue index 584f77b7648..c260670b517 100644 --- a/app/assets/javascripts/runner/components/runner_detail.vue +++ b/app/assets/javascripts/runner/components/runner_detail.vue @@ -21,7 +21,8 @@ export default { props: { label: { type: String, - required: true, + default: null, + required: false, }, value: { type: String, @@ -39,7 +40,11 @@ export default {