diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-03-08 12:11:30 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-03-08 12:11:30 +0000 |
commit | 012f9a4b9ec4a78d9593d882b38f95e376c2cfe2 (patch) | |
tree | 07f1df76cb12d94744e8069eec540d36092bbaba /app | |
parent | 3c050fb24b757425987a7df4cb3497e1d792be8e (diff) | |
download | gitlab-ce-012f9a4b9ec4a78d9593d882b38f95e376c2cfe2.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
43 files changed, 383 insertions, 60 deletions
diff --git a/app/assets/javascripts/add_context_commits_modal/components/add_context_commits_modal_wrapper.vue b/app/assets/javascripts/add_context_commits_modal/components/add_context_commits_modal_wrapper.vue index a41ff42df20..c66b595ffdc 100644 --- a/app/assets/javascripts/add_context_commits_modal/components/add_context_commits_modal_wrapper.vue +++ b/app/assets/javascripts/add_context_commits_modal/components/add_context_commits_modal_wrapper.vue @@ -2,7 +2,7 @@ import { GlModal, GlTabs, GlTab, GlSearchBoxByType, GlSprintf, GlBadge } from '@gitlab/ui'; import { mapState, mapActions } from 'vuex'; import ReviewTabContainer from '~/add_context_commits_modal/components/review_tab_container.vue'; -import { createAlert } from '~/flash'; +import { createAlert } from '~/alert'; import { BV_SHOW_MODAL } from '~/lib/utils/constants'; import { s__ } from '~/locale'; import eventHub from '../event_hub'; diff --git a/app/assets/javascripts/add_context_commits_modal/store/actions.js b/app/assets/javascripts/add_context_commits_modal/store/actions.js index d4c9db2fa33..de9c7488ace 100644 --- a/app/assets/javascripts/add_context_commits_modal/store/actions.js +++ b/app/assets/javascripts/add_context_commits_modal/store/actions.js @@ -1,6 +1,6 @@ import _ from 'lodash'; import Api from '~/api'; -import { createAlert } from '~/flash'; +import { createAlert } from '~/alert'; import axios from '~/lib/utils/axios_utils'; import { s__ } from '~/locale'; import * as types from './mutation_types'; diff --git a/app/assets/javascripts/blob_edit/blob_bundle.js b/app/assets/javascripts/blob_edit/blob_bundle.js index 509d399273d..01d35a0980f 100644 --- a/app/assets/javascripts/blob_edit/blob_bundle.js +++ b/app/assets/javascripts/blob_edit/blob_bundle.js @@ -2,7 +2,7 @@ import $ from 'jquery'; import initPopover from '~/blob/suggest_gitlab_ci_yml'; -import { createAlert } from '~/flash'; +import { createAlert } from '~/alert'; import { setCookie } from '~/lib/utils/common_utils'; import Tracking from '~/tracking'; import NewCommitForm from '../new_commit_form'; diff --git a/app/assets/javascripts/blob_edit/edit_blob.js b/app/assets/javascripts/blob_edit/edit_blob.js index db47b11cca1..f021553ae98 100644 --- a/app/assets/javascripts/blob_edit/edit_blob.js +++ b/app/assets/javascripts/blob_edit/edit_blob.js @@ -4,7 +4,7 @@ import { SourceEditorExtension } from '~/editor/extensions/source_editor_extensi import { FileTemplateExtension } from '~/editor/extensions/source_editor_file_template_ext'; import { ToolbarExtension } from '~/editor/extensions/source_editor_toolbar_ext'; import SourceEditor from '~/editor/source_editor'; -import { createAlert } from '~/flash'; +import { createAlert } from '~/alert'; import axios from '~/lib/utils/axios_utils'; import { addEditorMarkdownListeners } from '~/lib/utils/text_markdown'; import { insertFinalNewline } from '~/lib/utils/text_utility'; diff --git a/app/assets/javascripts/ci/runner/admin_register_runner/admin_register_runner_app.vue b/app/assets/javascripts/ci/runner/admin_register_runner/admin_register_runner_app.vue index b291be41203..1ae119da959 100644 --- a/app/assets/javascripts/ci/runner/admin_register_runner/admin_register_runner_app.vue +++ b/app/assets/javascripts/ci/runner/admin_register_runner/admin_register_runner_app.vue @@ -2,12 +2,13 @@ import { GlButton } from '@gitlab/ui'; import { s__, sprintf } from '~/locale'; import { createAlert } from '~/flash'; -import { getParameterByName } from '~/lib/utils/url_utility'; +import { getParameterByName, updateHistory, mergeUrlParams } from '~/lib/utils/url_utility'; import { convertToGraphQLId } from '~/graphql_shared/utils'; import { TYPENAME_CI_RUNNER } from '~/graphql_shared/constants'; import runnerForRegistrationQuery from '../graphql/register/runner_for_registration.query.graphql'; import { I18N_FETCH_ERROR, PARAM_KEY_PLATFORM, DEFAULT_PLATFORM } from '../constants'; import RegistrationInstructions from '../components/registration/registration_instructions.vue'; +import PlatformsDrawer from '../components/registration/platforms_drawer.vue'; import { captureException } from '../sentry_utils'; export default { @@ -15,6 +16,7 @@ export default { components: { GlButton, RegistrationInstructions, + PlatformsDrawer, }, props: { runnerId: { @@ -30,6 +32,7 @@ export default { return { platform: getParameterByName(PARAM_KEY_PLATFORM) || DEFAULT_PLATFORM, runner: null, + isDrawerOpen: false, }; }, apollo: { @@ -62,6 +65,21 @@ export default { return this.runner?.ephemeralAuthenticationToken; }, }, + watch: { + platform(platform) { + updateHistory({ + url: mergeUrlParams({ [PARAM_KEY_PLATFORM]: platform }, window.location.href), + }); + }, + }, + methods: { + onSelectPlatform(platform) { + this.platform = platform; + }, + onToggleDrawer(val = !this.isDrawerOpen) { + this.isDrawerOpen = val; + }, + }, }; </script> <template> @@ -72,6 +90,14 @@ export default { :loading="$apollo.queries.runner.loading" :platform="platform" :token="ephemeralAuthenticationToken" + @toggleDrawer="onToggleDrawer" + /> + + <platforms-drawer + :platform="platform" + :open="isDrawerOpen" + @selectPlatform="onSelectPlatform" + @close="onToggleDrawer(false)" /> <gl-button :href="runnersPath" variant="confirm">{{ diff --git a/app/assets/javascripts/ci/runner/components/registration/platforms_drawer.vue b/app/assets/javascripts/ci/runner/components/registration/platforms_drawer.vue new file mode 100644 index 00000000000..a56302898ca --- /dev/null +++ b/app/assets/javascripts/ci/runner/components/registration/platforms_drawer.vue @@ -0,0 +1,131 @@ +<script> +import { GlDrawer, GlFormGroup, GlFormSelect, GlLink, GlSprintf } from '@gitlab/ui'; +import { getContentWrapperHeight } from '~/lib/utils/dom_utils'; +import { DRAWER_Z_INDEX } from '~/lib/utils/constants'; + +import { + DEFAULT_PLATFORM, + MACOS_PLATFORM, + LINUX_PLATFORM, + WINDOWS_PLATFORM, + INSTALL_HELP_URL, +} from '../../constants'; +import { installScript, platformArchitectures } from './utils'; + +import CliCommand from './cli_command.vue'; + +export default { + components: { + GlDrawer, + GlFormGroup, + GlFormSelect, + GlLink, + GlSprintf, + CliCommand, + }, + props: { + open: { + type: Boolean, + required: true, + }, + platform: { + type: String, + required: false, + default: DEFAULT_PLATFORM, + }, + }, + data() { + return { + selectedPlatform: this.platform, + selectedArchitecture: null, + }; + }, + computed: { + drawerHeightOffset() { + return getContentWrapperHeight('.content-wrapper'); + }, + architectureOptions() { + return platformArchitectures({ platform: this.selectedPlatform }); + }, + script() { + return installScript({ + platform: this.selectedPlatform, + architecture: this.selectedArchitecture, + }); + }, + }, + watch: { + selectedPlatform() { + this.selectedArchitecture = + this.architectureOptions.find((value) => value === this.selectedArchitecture) || + this.architectureOptions[0]; + + this.$emit('selectPlatform', this.selectedPlatform); + }, + }, + created() { + [this.selectedArchitecture] = this.architectureOptions; + }, + methods: { + onClose() { + this.$emit('close'); + }, + }, + platformOptions: [ + /* eslint-disable @gitlab/require-i18n-strings */ + { value: LINUX_PLATFORM, text: 'Linux' }, + { value: MACOS_PLATFORM, text: 'macOS' }, + { value: WINDOWS_PLATFORM, text: 'Windows' }, + /* eslint-enable @gitlab/require-i18n-strings */ + ], + INSTALL_HELP_URL, + DRAWER_Z_INDEX, +}; +</script> +<template> + <gl-drawer + :open="open" + :header-height="drawerHeightOffset" + :z-index="$options.DRAWER_Z_INDEX" + @close="onClose" + > + <template #title> + <h2 class="gl-my-0 gl-font-size-h2 gl-line-height-24"> + {{ s__('Runners|Install GitLab Runner') }} + </h2> + </template> + <div> + <p>{{ s__('Runners|Select platform specifications to install GitLab Runner.') }}</p> + + <gl-form-group :label="s__('Runners|Environment')" label-for="runner-environment-select"> + <gl-form-select + id="runner-environment-select" + v-model="selectedPlatform" + :options="$options.platformOptions" + /> + </gl-form-group> + + <gl-form-group :label="s__('Runners|Architecture')" label-for="runner-architecture-select"> + <gl-form-select + id="runner-architecture-select" + v-model="selectedArchitecture" + :options="architectureOptions" + /> + </gl-form-group> + + <cli-command :command="script" /> + + <p> + <gl-sprintf + :message=" + s__('Runners|See more %{linkStart}installation methods and architectures%{linkEnd}.') + " + > + <template #link="{ content }"> + <gl-link :href="$options.INSTALL_HELP_URL">{{ content }}</gl-link> + </template> + </gl-sprintf> + </p> + </div> + </gl-drawer> +</template> diff --git a/app/assets/javascripts/ci/runner/components/registration/registration_instructions.vue b/app/assets/javascripts/ci/runner/components/registration/registration_instructions.vue index e01d8b64839..e611cae1f35 100644 --- a/app/assets/javascripts/ci/runner/components/registration/registration_instructions.vue +++ b/app/assets/javascripts/ci/runner/components/registration/registration_instructions.vue @@ -2,7 +2,7 @@ import { GlIcon, GlLink, GlSprintf, GlSkeletonLoader } from '@gitlab/ui'; import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; -import { INSTALL_HELP_URL, EXECUTORS_HELP_URL, SERVICE_COMMANDS_HELP_URL } from '../../constants'; +import { EXECUTORS_HELP_URL, SERVICE_COMMANDS_HELP_URL } from '../../constants'; import CliCommand from './cli_command.vue'; import { commandPrompt, registerCommand, runCommand } from './utils'; @@ -42,7 +42,11 @@ export default { return runCommand({ platform: this.platform }); }, }, - INSTALL_HELP_URL, + methods: { + toggleDrawer(val) { + this.$emit('toggleDrawer', val); + }, + }, EXECUTORS_HELP_URL, SERVICE_COMMANDS_HELP_URL, }; @@ -58,7 +62,7 @@ export default { " > <template #link="{ content }"> - <gl-link :href="$options.INSTALL_HELP_URL">{{ content }}</gl-link> + <gl-link @click="toggleDrawer()">{{ content }}</gl-link> </template> </gl-sprintf> </p> diff --git a/app/assets/javascripts/ci/runner/components/registration/registration_token_reset_dropdown_item.vue b/app/assets/javascripts/ci/runner/components/registration/registration_token_reset_dropdown_item.vue index ac2793654c8..db8c953ce3c 100644 --- a/app/assets/javascripts/ci/runner/components/registration/registration_token_reset_dropdown_item.vue +++ b/app/assets/javascripts/ci/runner/components/registration/registration_token_reset_dropdown_item.vue @@ -1,6 +1,6 @@ <script> import { GlDropdownItem, GlLoadingIcon, GlModal, GlModalDirective } from '@gitlab/ui'; -import { createAlert } from '~/flash'; +import { createAlert } from '~/alert'; import { TYPENAME_GROUP, TYPENAME_PROJECT } from '~/graphql_shared/constants'; import { convertToGraphQLId } from '~/graphql_shared/utils'; import { __, s__ } from '~/locale'; diff --git a/app/assets/javascripts/ci/runner/components/registration/scripts/linux/install.sh b/app/assets/javascripts/ci/runner/components/registration/scripts/linux/install.sh new file mode 100644 index 00000000000..a8ba2592128 --- /dev/null +++ b/app/assets/javascripts/ci/runner/components/registration/scripts/linux/install.sh @@ -0,0 +1,12 @@ +# Download the binary for your system +sudo curl -L --output /usr/local/bin/gitlab-runner ${GITLAB_CI_RUNNER_DOWNLOAD_LOCATION} + +# Give it permission to execute +sudo chmod +x /usr/local/bin/gitlab-runner + +# Create a GitLab Runner user +sudo useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash + +# Install and run as a service +sudo gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner +sudo gitlab-runner start diff --git a/app/assets/javascripts/ci/runner/components/registration/scripts/osx/install.sh b/app/assets/javascripts/ci/runner/components/registration/scripts/osx/install.sh new file mode 100644 index 00000000000..76c893bacfc --- /dev/null +++ b/app/assets/javascripts/ci/runner/components/registration/scripts/osx/install.sh @@ -0,0 +1,11 @@ +# Download the binary for your system +sudo curl --output /usr/local/bin/gitlab-runner ${GITLAB_CI_RUNNER_DOWNLOAD_LOCATION} + +# Give it permission to execute +sudo chmod +x /usr/local/bin/gitlab-runner + +# The rest of the commands execute as the user who will run the runner +# Register the runner (steps below), then run +cd ~ +gitlab-runner install +gitlab-runner start diff --git a/app/assets/javascripts/ci/runner/components/registration/scripts/windows/install.ps1 b/app/assets/javascripts/ci/runner/components/registration/scripts/windows/install.ps1 new file mode 100644 index 00000000000..019363fc3f7 --- /dev/null +++ b/app/assets/javascripts/ci/runner/components/registration/scripts/windows/install.ps1 @@ -0,0 +1,13 @@ +# Run PowerShell: https://docs.microsoft.com/en-us/powershell/scripting/windows-powershell/starting-windows-powershell?view=powershell-7#with-administrative-privileges-run-as-administrator +# Create a folder somewhere on your system, for example: C:\GitLab-Runner +New-Item -Path 'C:\GitLab-Runner' -ItemType Directory + +# Change to the folder +cd 'C:\GitLab-Runner' + +# Download binary +Invoke-WebRequest -Uri "${GITLAB_CI_RUNNER_DOWNLOAD_LOCATION}" -OutFile "gitlab-runner.exe" + +# Register the runner (steps below), then run +.\gitlab-runner.exe install +.\gitlab-runner.exe start diff --git a/app/assets/javascripts/ci/runner/components/registration/utils.js b/app/assets/javascripts/ci/runner/components/registration/utils.js index 32fb8eac5e9..621963349ae 100644 --- a/app/assets/javascripts/ci/runner/components/registration/utils.js +++ b/app/assets/javascripts/ci/runner/components/registration/utils.js @@ -1,11 +1,15 @@ +/* eslint-disable @gitlab/require-i18n-strings */ import { DEFAULT_PLATFORM, LINUX_PLATFORM, MACOS_PLATFORM, WINDOWS_PLATFORM, + DOWNLOAD_LOCATIONS, } from '../../constants'; +import linuxInstall from './scripts/linux/install.sh?raw'; +import osxInstall from './scripts/osx/install.sh?raw'; +import windowsInstall from './scripts/windows/install.ps1?raw'; -/* eslint-disable @gitlab/require-i18n-strings */ const OS = { [LINUX_PLATFORM]: { commandPrompt: '$', @@ -33,11 +37,40 @@ export const registerCommand = ({ platform, url = gon.gitlab_url, registrationTo return [ `${executable({ platform })} register`, ` --url ${url}`, - ` --registration-token ${registrationToken}`, + ...(registrationToken ? [` --registration-token ${registrationToken}`] : []), ]; }; export const runCommand = ({ platform }) => { return `${executable({ platform })} run`; }; -/* eslint-enable @gitlab/require-i18n-strings */ + +const importInstallScript = ({ platform = DEFAULT_PLATFORM }) => { + switch (platform) { + case LINUX_PLATFORM: + return linuxInstall; + case MACOS_PLATFORM: + return osxInstall; + case WINDOWS_PLATFORM: + return windowsInstall; + default: + return ''; + } +}; + +export const platformArchitectures = ({ platform }) => { + return DOWNLOAD_LOCATIONS[platform].map(({ arch }) => arch); +}; + +export const installScript = ({ platform, architecture }) => { + const downloadLocation = DOWNLOAD_LOCATIONS[platform].find(({ arch }) => arch === architecture) + .url; + + return importInstallScript({ platform }) + .replace( + // eslint-disable-next-line no-template-curly-in-string + '${GITLAB_CI_RUNNER_DOWNLOAD_LOCATION}', + downloadLocation, + ) + .trim(); +}; diff --git a/app/assets/javascripts/ci/runner/components/runner_bulk_delete.vue b/app/assets/javascripts/ci/runner/components/runner_bulk_delete.vue index 8dde3ac4e19..e7b26ec6d4e 100644 --- a/app/assets/javascripts/ci/runner/components/runner_bulk_delete.vue +++ b/app/assets/javascripts/ci/runner/components/runner_bulk_delete.vue @@ -1,6 +1,6 @@ <script> import { GlButton, GlModalDirective, GlModal, GlSprintf } from '@gitlab/ui'; -import { createAlert } from '~/flash'; +import { createAlert } from '~/alert'; import { __, s__, n__, sprintf } from '~/locale'; import checkedRunnerIdsQuery from '../graphql/list/checked_runner_ids.query.graphql'; import BulkRunnerDelete from '../graphql/list/bulk_runner_delete.mutation.graphql'; diff --git a/app/assets/javascripts/ci/runner/components/runner_delete_button.vue b/app/assets/javascripts/ci/runner/components/runner_delete_button.vue index f02e6bce5c3..020487fc727 100644 --- a/app/assets/javascripts/ci/runner/components/runner_delete_button.vue +++ b/app/assets/javascripts/ci/runner/components/runner_delete_button.vue @@ -1,7 +1,7 @@ <script> import { GlButton, GlModalDirective, GlTooltipDirective } from '@gitlab/ui'; import runnerDeleteMutation from '~/ci/runner/graphql/shared/runner_delete.mutation.graphql'; -import { createAlert } from '~/flash'; +import { createAlert } from '~/alert'; import { sprintf, s__ } from '~/locale'; import { captureException } from '~/ci/runner/sentry_utils'; import { getIdFromGraphQLId } from '~/graphql_shared/utils'; diff --git a/app/assets/javascripts/ci/runner/components/runner_jobs.vue b/app/assets/javascripts/ci/runner/components/runner_jobs.vue index 9003eba3636..f5287f597ab 100644 --- a/app/assets/javascripts/ci/runner/components/runner_jobs.vue +++ b/app/assets/javascripts/ci/runner/components/runner_jobs.vue @@ -1,6 +1,6 @@ <script> import { GlSkeletonLoader } from '@gitlab/ui'; -import { createAlert } from '~/flash'; +import { createAlert } from '~/alert'; import runnerJobsQuery from '../graphql/show/runner_jobs.query.graphql'; import { I18N_FETCH_ERROR, I18N_NO_JOBS_FOUND, RUNNER_DETAILS_JOBS_PAGE_SIZE } from '../constants'; import { captureException } from '../sentry_utils'; diff --git a/app/assets/javascripts/ci/runner/components/runner_pause_button.vue b/app/assets/javascripts/ci/runner/components/runner_pause_button.vue index 2c80518e772..a27af232e97 100644 --- a/app/assets/javascripts/ci/runner/components/runner_pause_button.vue +++ b/app/assets/javascripts/ci/runner/components/runner_pause_button.vue @@ -1,7 +1,7 @@ <script> import { GlButton, GlTooltipDirective } from '@gitlab/ui'; import runnerToggleActiveMutation from '~/ci/runner/graphql/shared/runner_toggle_active.mutation.graphql'; -import { createAlert } from '~/flash'; +import { createAlert } from '~/alert'; import { captureException } from '~/ci/runner/sentry_utils'; import { I18N_PAUSE, I18N_PAUSE_TOOLTIP, I18N_RESUME, I18N_RESUME_TOOLTIP } from '../constants'; diff --git a/app/assets/javascripts/ci/runner/components/runner_projects.vue b/app/assets/javascripts/ci/runner/components/runner_projects.vue index 4a6e90b44a9..4cfc57340f5 100644 --- a/app/assets/javascripts/ci/runner/components/runner_projects.vue +++ b/app/assets/javascripts/ci/runner/components/runner_projects.vue @@ -1,7 +1,7 @@ <script> import { GlSearchBoxByType, GlSkeletonLoader } from '@gitlab/ui'; import { sprintf, formatNumber } from '~/locale'; -import { createAlert } from '~/flash'; +import { createAlert } from '~/alert'; import runnerProjectsQuery from '../graphql/show/runner_projects.query.graphql'; import { I18N_ASSIGNED_PROJECTS, diff --git a/app/assets/javascripts/ci/runner/components/runner_update_form.vue b/app/assets/javascripts/ci/runner/components/runner_update_form.vue index a9790d06ca7..dd8e965cecd 100644 --- a/app/assets/javascripts/ci/runner/components/runner_update_form.vue +++ b/app/assets/javascripts/ci/runner/components/runner_update_form.vue @@ -13,7 +13,7 @@ import { modelToUpdateMutationVariables, runnerToModel, } from 'ee_else_ce/ci/runner/runner_update_form_utils'; -import { createAlert, VARIANT_SUCCESS } from '~/flash'; +import { createAlert, VARIANT_SUCCESS } from '~/alert'; import { redirectTo } from '~/lib/utils/url_utility'; import { __ } from '~/locale'; import { captureException } from '~/ci/runner/sentry_utils'; diff --git a/app/assets/javascripts/ci/runner/components/search_tokens/tag_token.vue b/app/assets/javascripts/ci/runner/components/search_tokens/tag_token.vue index 6e7c41885f8..1de7775090a 100644 --- a/app/assets/javascripts/ci/runner/components/search_tokens/tag_token.vue +++ b/app/assets/javascripts/ci/runner/components/search_tokens/tag_token.vue @@ -1,6 +1,6 @@ <script> import { GlFilteredSearchSuggestion, GlToken } from '@gitlab/ui'; -import { createAlert } from '~/flash'; +import { createAlert } from '~/alert'; import axios from '~/lib/utils/axios_utils'; import { s__ } from '~/locale'; diff --git a/app/assets/javascripts/ci/runner/constants.js b/app/assets/javascripts/ci/runner/constants.js index 054e6b954d0..8e31b7f2d44 100644 --- a/app/assets/javascripts/ci/runner/constants.js +++ b/app/assets/javascripts/ci/runner/constants.js @@ -183,6 +183,55 @@ export const MACOS_PLATFORM = 'osx'; export const WINDOWS_PLATFORM = 'windows'; export const AWS_PLATFORM = 'aws'; +export const DOWNLOAD_LOCATIONS = { + [LINUX_PLATFORM]: [ + { + arch: 'amd64', + url: + 'https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64', + }, + { + arch: '386', + url: + 'https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-386', + }, + { + arch: 'arm', + url: + 'https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-arm', + }, + { + arch: 'arm64', + url: + 'https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-arm64', + }, + ], + [MACOS_PLATFORM]: [ + { + arch: 'amd64', + url: + 'https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-darwin-amd64', + }, + { + arch: 'arm64', + url: + 'https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-darwin-arm64', + }, + ], + [WINDOWS_PLATFORM]: [ + { + arch: 'amd64', + url: + 'https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-windows-amd64.exe', + }, + { + arch: '386', + url: + 'https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-windows-386.exe', + }, + ], +}; + export const DEFAULT_PLATFORM = LINUX_PLATFORM; // Runner docs are in a separate repository and are not shipped with GitLab diff --git a/app/assets/javascripts/ci/runner/local_storage_alert/show_alert_from_local_storage.js b/app/assets/javascripts/ci/runner/local_storage_alert/show_alert_from_local_storage.js index d768a06494a..bad3ca6024e 100644 --- a/app/assets/javascripts/ci/runner/local_storage_alert/show_alert_from_local_storage.js +++ b/app/assets/javascripts/ci/runner/local_storage_alert/show_alert_from_local_storage.js @@ -7,7 +7,7 @@ export const showAlertFromLocalStorage = async () => { if (alertOptions) { try { - const { createAlert } = await import('~/flash'); + const { createAlert } = await import('~/alert'); createAlert(JSON.parse(alertOptions)); } catch { // ignore when the alert data cannot be parsed diff --git a/app/assets/javascripts/content_editor/components/content_editor.vue b/app/assets/javascripts/content_editor/components/content_editor.vue index 237808983ee..bb777cb09eb 100644 --- a/app/assets/javascripts/content_editor/components/content_editor.vue +++ b/app/assets/javascripts/content_editor/components/content_editor.vue @@ -1,7 +1,7 @@ <script> import { EditorContent as TiptapEditorContent } from '@tiptap/vue-2'; import { __ } from '~/locale'; -import { VARIANT_DANGER } from '~/flash'; +import { VARIANT_DANGER } from '~/alert'; import { createContentEditor } from '../services/create_content_editor'; import { ALERT_EVENT, TIPTAP_AUTOFOCUS_OPTIONS } from '../constants'; import ContentEditorAlert from './content_editor_alert.vue'; diff --git a/app/assets/javascripts/content_editor/extensions/paste_markdown.js b/app/assets/javascripts/content_editor/extensions/paste_markdown.js index fa465160598..0a9a0d8d4c1 100644 --- a/app/assets/javascripts/content_editor/extensions/paste_markdown.js +++ b/app/assets/javascripts/content_editor/extensions/paste_markdown.js @@ -1,7 +1,7 @@ import { Extension } from '@tiptap/core'; import { Plugin, PluginKey } from '@tiptap/pm/state'; import { __ } from '~/locale'; -import { VARIANT_DANGER } from '~/flash'; +import { VARIANT_DANGER } from '~/alert'; import createMarkdownDeserializer from '../services/gl_api_markdown_deserializer'; import { ALERT_EVENT, EXTENSION_PRIORITY_HIGHEST } from '../constants'; import CodeBlockHighlight from './code_block_highlight'; diff --git a/app/assets/javascripts/content_editor/extensions/table.js b/app/assets/javascripts/content_editor/extensions/table.js index d7456ab4094..de8170eff93 100644 --- a/app/assets/javascripts/content_editor/extensions/table.js +++ b/app/assets/javascripts/content_editor/extensions/table.js @@ -1,6 +1,6 @@ import { Table } from '@tiptap/extension-table'; import { debounce } from 'lodash'; -import { VARIANT_WARNING } from '~/flash'; +import { VARIANT_WARNING } from '~/alert'; import { __ } from '~/locale'; import { getMarkdownSource } from '../services/markdown_sourcemap'; import { shouldRenderHTMLTable } from '../services/serialization_helpers'; diff --git a/app/assets/javascripts/content_editor/services/upload_helpers.js b/app/assets/javascripts/content_editor/services/upload_helpers.js index abfb73183dd..de1a187b246 100644 --- a/app/assets/javascripts/content_editor/services/upload_helpers.js +++ b/app/assets/javascripts/content_editor/services/upload_helpers.js @@ -1,4 +1,4 @@ -import { VARIANT_DANGER } from '~/flash'; +import { VARIANT_DANGER } from '~/alert'; import axios from '~/lib/utils/axios_utils'; import { __ } from '~/locale'; import { extractFilename, readFileAsDataURL } from './utils'; diff --git a/app/assets/javascripts/graphql_shared/possible_types.json b/app/assets/javascripts/graphql_shared/possible_types.json index 4a5536986bd..22629dfb7d8 100644 --- a/app/assets/javascripts/graphql_shared/possible_types.json +++ b/app/assets/javascripts/graphql_shared/possible_types.json @@ -152,6 +152,7 @@ "WorkItemWidgetLabels", "WorkItemWidgetMilestone", "WorkItemWidgetNotes", + "WorkItemWidgetNotifications", "WorkItemWidgetProgress", "WorkItemWidgetRequirementLegacy", "WorkItemWidgetStartAndDueDate", @@ -159,4 +160,4 @@ "WorkItemWidgetTestReports", "WorkItemWidgetWeight" ] -}
\ No newline at end of file +} diff --git a/app/assets/javascripts/invite_members/utils/trigger_successful_invite_alert.js b/app/assets/javascripts/invite_members/utils/trigger_successful_invite_alert.js index 4d3a7951265..e556582742b 100644 --- a/app/assets/javascripts/invite_members/utils/trigger_successful_invite_alert.js +++ b/app/assets/javascripts/invite_members/utils/trigger_successful_invite_alert.js @@ -1,4 +1,4 @@ -import { createAlert } from '~/flash'; +import { createAlert } from '~/alert'; import AccessorUtilities from '~/lib/utils/accessor'; import { TOAST_MESSAGE_LOCALSTORAGE_KEY, TOAST_MESSAGE_SUCCESSFUL } from '../constants'; diff --git a/app/assets/javascripts/merge_request.js b/app/assets/javascripts/merge_request.js index 61abdca0a5b..b045da93fd8 100644 --- a/app/assets/javascripts/merge_request.js +++ b/app/assets/javascripts/merge_request.js @@ -1,7 +1,7 @@ /* eslint-disable func-names, no-underscore-dangle, consistent-return */ import $ from 'jquery'; -import { createAlert } from '~/flash'; +import { createAlert } from '~/alert'; import toast from '~/vue_shared/plugins/global_toast'; import { __ } from '~/locale'; import eventHub from '~/vue_merge_request_widget/event_hub'; diff --git a/app/assets/javascripts/merge_request_tabs.js b/app/assets/javascripts/merge_request_tabs.js index 46ee8fecfc5..d55e942dafa 100644 --- a/app/assets/javascripts/merge_request_tabs.js +++ b/app/assets/javascripts/merge_request_tabs.js @@ -1,7 +1,7 @@ /* eslint-disable class-methods-use-this */ import $ from 'jquery'; import Vue from 'vue'; -import { createAlert } from '~/flash'; +import { createAlert } from '~/alert'; import { getCookie, isMetaClick, parseBoolean, scrollToElement } from '~/lib/utils/common_utils'; import { parseUrlPathname } from '~/lib/utils/url_utility'; import createEventHub from '~/helpers/event_hub_factory'; diff --git a/app/assets/javascripts/vue_merge_request_widget/components/approvals/approvals.vue b/app/assets/javascripts/vue_merge_request_widget/components/approvals/approvals.vue index 213c9ca7f54..74922dd922c 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/approvals/approvals.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/approvals/approvals.vue @@ -1,5 +1,5 @@ <script> -import { GlButton, GlSprintf, GlLink } from '@gitlab/ui'; +import { GlButton, GlSprintf } from '@gitlab/ui'; import { createAlert } from '~/alert'; import { BV_SHOW_MODAL } from '~/lib/utils/constants'; import { HTTP_STATUS_UNAUTHORIZED } from '~/lib/utils/http_status'; @@ -14,7 +14,6 @@ import { INVALID_RULES_DOCS_PATH } from '../../constants'; import ApprovalsSummary from './approvals_summary.vue'; import ApprovalsSummaryOptional from './approvals_summary_optional.vue'; import { FETCH_LOADING, APPROVE_ERROR, UNAPPROVE_ERROR } from './messages'; -import { humanizeInvalidApproversRules } from './humanized_text'; export default { name: 'MRWidgetApprovals', @@ -25,7 +24,6 @@ export default { ApprovalsSummaryOptional, GlButton, GlSprintf, - GlLink, }, mixins: [approvalsMixin, glFeatureFlagsMixin()], props: { @@ -84,7 +82,7 @@ export default { return this.mr.mergeRequestApproversAvailable && this.invalidRules.length; }, invalidRulesText() { - return humanizeInvalidApproversRules(this.invalidRules); + return this.invalidRules.length; }, approvedBy() { return this.approvals.approvedBy?.nodes || []; @@ -200,10 +198,10 @@ export default { linkToInvalidRules: INVALID_RULES_DOCS_PATH, i18n: { invalidRuleSingular: s__( - 'mrWidget|Approval rule %{rules} is invalid. GitLab has approved this rule automatically to unblock the merge request. %{link}', + 'mrWidget|%{rules} invalid rule has been approved automatically, as no one can approve it.', ), invalidRulesPlural: s__( - 'mrWidget|Approval rules %{rules} are invalid. GitLab has approved these rules automatically to unblock the merge request. %{link}', + 'mrWidget|%{rules} invalid rules have been approved automatically, as no one can approve them.', ), learnMore: __('Learn more.'), }, @@ -241,14 +239,7 @@ export default { </div> <div v-if="hasInvalidRules" class="gl-text-gray-400 gl-mt-2" data-testid="invalid-rules"> <gl-sprintf :message="pluralizedRuleText"> - <template #rules> - {{ invalidRulesText }} - </template> - <template #link> - <gl-link :href="$options.linkToInvalidRules" target="_blank"> - {{ $options.i18n.learnMore }} - </gl-link> - </template> + <template #rules>{{ invalidRulesText }}</template> </gl-sprintf> </div> </div> diff --git a/app/graphql/mutations/metrics/dashboard/annotations/create.rb b/app/graphql/mutations/metrics/dashboard/annotations/create.rb index 2e7c0c5a2f9..d458bdcf82b 100644 --- a/app/graphql/mutations/metrics/dashboard/annotations/create.rb +++ b/app/graphql/mutations/metrics/dashboard/annotations/create.rb @@ -10,7 +10,7 @@ module Mutations ANNOTATION_SOURCE_ARGUMENT_ERROR = 'Either a cluster or environment global id is required' INVALID_ANNOTATION_SOURCE_ERROR = 'Invalid cluster or environment id' - authorize :create_metrics_dashboard_annotation + authorize :admin_metrics_dashboard_annotation field :annotation, Types::Metrics::Dashboards::AnnotationType, diff --git a/app/graphql/mutations/metrics/dashboard/annotations/delete.rb b/app/graphql/mutations/metrics/dashboard/annotations/delete.rb index e0fadff13d4..0ee2791f78b 100644 --- a/app/graphql/mutations/metrics/dashboard/annotations/delete.rb +++ b/app/graphql/mutations/metrics/dashboard/annotations/delete.rb @@ -7,7 +7,7 @@ module Mutations class Delete < Base graphql_name 'DeleteAnnotation' - authorize :delete_metrics_dashboard_annotation + authorize :admin_metrics_dashboard_annotation argument :id, ::Types::GlobalIDType[::Metrics::Dashboard::Annotation], required: true, diff --git a/app/graphql/resolvers/work_items_resolver.rb b/app/graphql/resolvers/work_items_resolver.rb index 0c9aac80274..fc086f35ba6 100644 --- a/app/graphql/resolvers/work_items_resolver.rb +++ b/app/graphql/resolvers/work_items_resolver.rb @@ -66,7 +66,8 @@ module Resolvers parent: :work_item_parent, children: { work_item_children_by_relative_position: [:author, { project: :project_feature }] }, labels: :labels, - milestone: { milestone: [:project, :group] } + milestone: { milestone: [:project, :group] }, + subscribed: [:assignees, :award_emoji, { notes: [:author, :award_emoji] }] } end diff --git a/app/graphql/types/work_items/widget_interface.rb b/app/graphql/types/work_items/widget_interface.rb index 672a78f12e1..50f8e4f7d8a 100644 --- a/app/graphql/types/work_items/widget_interface.rb +++ b/app/graphql/types/work_items/widget_interface.rb @@ -18,7 +18,8 @@ module Types ::Types::WorkItems::Widgets::AssigneesType, ::Types::WorkItems::Widgets::StartAndDueDateType, ::Types::WorkItems::Widgets::MilestoneType, - ::Types::WorkItems::Widgets::NotesType + ::Types::WorkItems::Widgets::NotesType, + ::Types::WorkItems::Widgets::NotificationsType ].freeze def self.ce_orphan_types @@ -44,6 +45,8 @@ module Types ::Types::WorkItems::Widgets::MilestoneType when ::WorkItems::Widgets::Notes ::Types::WorkItems::Widgets::NotesType + when ::WorkItems::Widgets::Notifications + ::Types::WorkItems::Widgets::NotificationsType else raise "Unknown GraphQL type for widget #{object}" end diff --git a/app/graphql/types/work_items/widgets/notifications_type.rb b/app/graphql/types/work_items/widgets/notifications_type.rb new file mode 100644 index 00000000000..85928817d07 --- /dev/null +++ b/app/graphql/types/work_items/widgets/notifications_type.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +module Types + module WorkItems + module Widgets + # Disabling widget level authorization as it might be too granular + # and we already authorize the parent work item + # rubocop:disable Graphql/AuthorizeTypes + class NotificationsType < BaseObject + graphql_name 'WorkItemWidgetNotifications' + description 'Represents the notifications widget' + + implements Types::WorkItems::WidgetInterface + + field :subscribed, GraphQL::Types::Boolean, + null: false, + description: 'Whether the current user is subscribed to notifications on the work item.' + + def subscribed + object.work_item.subscribed?(current_user, object.work_item.project) + end + end + # rubocop:enable Graphql/AuthorizeTypes + end + end +end diff --git a/app/models/concerns/subscribable.rb b/app/models/concerns/subscribable.rb index 5a10ea7a248..fe47393c554 100644 --- a/app/models/concerns/subscribable.rb +++ b/app/models/concerns/subscribable.rb @@ -27,8 +27,6 @@ module Subscribable def lazy_subscription(user, project = nil) return unless user - # handle project and group labels as well as issuable subscriptions - subscribable_type = self.class.ancestors.include?(Label) ? 'Label' : self.class.name BatchLoader.for(id: id, subscribable_type: subscribable_type, project_id: project&.id).batch do |items, loader| values = items.each_with_object({ ids: Set.new, subscribable_types: Set.new, project_ids: Set.new }) do |item, result| result[:ids] << item[:id] @@ -121,4 +119,15 @@ module Subscribable subscriptions .where(t[:project_id].eq(nil).or(t[:project_id].eq(project.try(:id)))) end + + def subscribable_type + # handle project and group labels as well as issuable subscriptions + if self.class.ancestors.include?(Label) + 'Label' + elsif self.class.ancestors.include?(Issue) + 'Issue' + else + self.class.name + end + end end diff --git a/app/models/work_items/widget_definition.rb b/app/models/work_items/widget_definition.rb index 5d4414e95d8..9e8c421d740 100644 --- a/app/models/work_items/widget_definition.rb +++ b/app/models/work_items/widget_definition.rb @@ -28,7 +28,8 @@ module WorkItems progress: 10, # EE-only status: 11, # EE-only requirement_legacy: 12, # EE-only - test_reports: 13 # EE-only + test_reports: 13, # EE-only + notifications: 14 } def self.available_widgets diff --git a/app/models/work_items/widgets/notifications.rb b/app/models/work_items/widgets/notifications.rb new file mode 100644 index 00000000000..9a13e5ebbea --- /dev/null +++ b/app/models/work_items/widgets/notifications.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +module WorkItems + module Widgets + class Notifications < Base + delegate :subscribed?, to: :work_item + end + end +end diff --git a/app/policies/group_policy.rb b/app/policies/group_policy.rb index ba6e760fd2b..c08bc8744ba 100644 --- a/app/policies/group_policy.rb +++ b/app/policies/group_policy.rb @@ -159,9 +159,7 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy rule { has_access }.enable :read_namespace rule { developer }.policy do - enable :create_metrics_dashboard_annotation - enable :delete_metrics_dashboard_annotation - enable :update_metrics_dashboard_annotation + enable :admin_metrics_dashboard_annotation enable :create_custom_emoji enable :create_package enable :developer_access diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb index 2bdd8b23c62..fcb93e44191 100644 --- a/app/policies/project_policy.rb +++ b/app/policies/project_policy.rb @@ -234,6 +234,10 @@ class ProjectPolicy < BasePolicy Gitlab.config.packages.enabled end + condition :terraform_state_disabled do + !Gitlab.config.terraform_state.enabled + end + condition(:create_runner_workflow_enabled) do Feature.enabled?(:create_runner_workflow_for_namespace, project.namespace) end @@ -404,13 +408,16 @@ class ProjectPolicy < BasePolicy end rule { infrastructure_disabled }.policy do - prevent(*create_read_update_admin_destroy(:terraform_state)) prevent(*create_read_update_admin_destroy(:cluster)) prevent(:read_pod_logs) prevent(:read_prometheus) prevent(:admin_project_google_cloud) end + rule { infrastructure_disabled | terraform_state_disabled }.policy do + prevent(*create_read_update_admin_destroy(:terraform_state)) + end + rule { can?(:metrics_dashboard) }.policy do enable :read_prometheus enable :read_deployment @@ -458,9 +465,7 @@ class ProjectPolicy < BasePolicy enable :create_release enable :update_release enable :destroy_release - enable :create_metrics_dashboard_annotation - enable :delete_metrics_dashboard_annotation - enable :update_metrics_dashboard_annotation + enable :admin_metrics_dashboard_annotation enable :read_alert_management_alert enable :update_alert_management_alert enable :create_design diff --git a/app/services/metrics/dashboard/annotations/create_service.rb b/app/services/metrics/dashboard/annotations/create_service.rb index b86fa82a5e8..47e9afa36b9 100644 --- a/app/services/metrics/dashboard/annotations/create_service.rb +++ b/app/services/metrics/dashboard/annotations/create_service.rb @@ -26,7 +26,7 @@ module Metrics attr_reader :user, :params def authorize_environment_access(options) - if environment.nil? || Ability.allowed?(user, :create_metrics_dashboard_annotation, project) + if environment.nil? || Ability.allowed?(user, :admin_metrics_dashboard_annotation, project) options[:environment] = environment success(options) else @@ -35,7 +35,7 @@ module Metrics end def authorize_cluster_access(options) - if cluster.nil? || Ability.allowed?(user, :create_metrics_dashboard_annotation, cluster) + if cluster.nil? || Ability.allowed?(user, :admin_metrics_dashboard_annotation, cluster) options[:cluster] = cluster success(options) else diff --git a/app/services/metrics/dashboard/annotations/delete_service.rb b/app/services/metrics/dashboard/annotations/delete_service.rb index 3cb22f8d3da..34918c89304 100644 --- a/app/services/metrics/dashboard/annotations/delete_service.rb +++ b/app/services/metrics/dashboard/annotations/delete_service.rb @@ -24,7 +24,7 @@ module Metrics attr_reader :user, :annotation def authorize_action(_options) - if Ability.allowed?(user, :delete_metrics_dashboard_annotation, annotation) + if Ability.allowed?(user, :admin_metrics_dashboard_annotation, annotation) success else error(s_('MetricsDashboardAnnotation|You are not authorized to delete this annotation')) diff --git a/app/views/clusters/clusters/_integrations.html.haml b/app/views/clusters/clusters/_integrations.html.haml index 4a3062def8c..0f62b640b97 100644 --- a/app/views/clusters/clusters/_integrations.html.haml +++ b/app/views/clusters/clusters/_integrations.html.haml @@ -6,7 +6,7 @@ - if can?(current_user, :admin_cluster, @cluster) .sub-section.form-group = gitlab_ui_form_for @prometheus_integration, as: :integration, namespace: :prometheus, url: @cluster.integrations_path, method: :post, html: { class: 'js-cluster-integrations-form' } do |prometheus_form| - = prometheus_form.hidden_field :application_type + = prometheus_form.hidden_field :application_type, value: @prometheus_integration.application_type .form-group.gl-form-group - help_text = s_('ClusterIntegration|Allows GitLab to query a specifically configured in-cluster Prometheus for metrics.') - help_link = link_to(_('More information.'), help_page_path("user/clusters/integrations", anchor: "prometheus-cluster-integration"), target: '_blank', rel: 'noopener noreferrer') |