diff options
43 files changed, 774 insertions, 380 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ab38c87039e..f89a52e7a3e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1018,10 +1018,8 @@ schedule:review-build-cng: .review-deploy-base: &review-deploy-base <<: *review-base - retry: 2 allow_failure: true variables: - GIT_DEPTH: "1" HOST_SUFFIX: "${CI_ENVIRONMENT_SLUG}" DOMAIN: "-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN}" GITLAB_HELM_CHART_REF: "master" diff --git a/Dangerfile b/Dangerfile index 32f4b4d23c3..95dd48aae9e 100644 --- a/Dangerfile +++ b/Dangerfile @@ -13,3 +13,4 @@ danger.import_dangerfile(path: 'danger/prettier') danger.import_dangerfile(path: 'danger/eslint') danger.import_dangerfile(path: 'danger/roulette') danger.import_dangerfile(path: 'danger/single_codebase') +danger.import_dangerfile(path: 'danger/gitlab_ui_wg') diff --git a/app/assets/javascripts/boards/components/board.js b/app/assets/javascripts/boards/components/board.js index fb6e5291a61..45b9e57f9ab 100644 --- a/app/assets/javascripts/boards/components/board.js +++ b/app/assets/javascripts/boards/components/board.js @@ -54,7 +54,10 @@ export default Vue.extend({ return `${n__('%d issue', '%d issues', issuesSize)}`; }, isNewIssueShown() { - return this.list.type === 'backlog' || (!this.disabled && this.list.type !== 'closed'); + return ( + this.list.type === 'backlog' || + (!this.disabled && this.list.type !== 'closed' && this.list.type !== 'blank') + ); }, }, watch: { diff --git a/app/assets/javascripts/diffs/components/diff_file.vue b/app/assets/javascripts/diffs/components/diff_file.vue index 58a9605c181..f5876a73eff 100644 --- a/app/assets/javascripts/diffs/components/diff_file.vue +++ b/app/assets/javascripts/diffs/components/diff_file.vue @@ -188,10 +188,6 @@ export default { /> </div> </template> - <div v-if="isFileTooLarge" class="nothing-here-block diff-collapsed js-too-large-diff"> - {{ __('This source diff could not be displayed because it is too large.') }} - <span v-html="viewBlobLink"></span> - </div> </div> </template> diff --git a/app/assets/javascripts/notes/components/noteable_note.vue b/app/assets/javascripts/notes/components/noteable_note.vue index 5fa0ab3de98..d2cfeff53e8 100644 --- a/app/assets/javascripts/notes/components/noteable_note.vue +++ b/app/assets/javascripts/notes/components/noteable_note.vue @@ -96,7 +96,7 @@ export default { return ''; } - // We need to do this to ensure we have the currect sentence order + // We need to do this to ensure we have the correct sentence order // when translating this as the sentence order may change from one // language to the next. See: // https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/24427#note_133713771 diff --git a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/timezone_dropdown.js b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/timezone_dropdown.js index 95b57d5e048..c1f6edf2f27 100644 --- a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/timezone_dropdown.js +++ b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/timezone_dropdown.js @@ -1,17 +1,33 @@ -/* eslint-disable class-methods-use-this */ +const defaultTimezone = 'UTC'; + +export const formatUtcOffset = offset => { + const parsed = parseInt(offset, 10); + if (Number.isNaN(parsed) || parsed === 0) { + return `0`; + } + const prefix = offset > 0 ? '+' : '-'; + return `${prefix} ${Math.abs(offset / 3600)}`; +}; -import $ from 'jquery'; +export const formatTimezone = item => `[UTC ${formatUtcOffset(item.offset)}] ${item.name}`; -const defaultTimezone = 'UTC'; +const defaults = { + $inputEl: null, + $dropdownEl: null, + onSelectTimezone: null, +}; export default class TimezoneDropdown { - constructor() { - this.$dropdown = $('.js-timezone-dropdown'); + constructor({ $dropdownEl, $inputEl, onSelectTimezone } = defaults) { + this.$dropdown = $dropdownEl; this.$dropdownToggle = this.$dropdown.find('.dropdown-toggle-text'); - this.$input = $('#schedule_cron_timezone'); + this.$input = $inputEl; this.timezoneData = this.$dropdown.data('data'); + this.initDefaultTimezone(); this.initDropdown(); + + this.onSelectTimezone = onSelectTimezone; } initDropdown() { @@ -24,28 +40,12 @@ export default class TimezoneDropdown { fields: ['name'], }, clicked: cfg => this.updateInputValue(cfg), - text: item => this.formatTimezone(item), + text: item => formatTimezone(item), }); this.setDropdownToggle(); } - formatUtcOffset(offset) { - let prefix = ''; - - if (offset > 0) { - prefix = '+'; - } else if (offset < 0) { - prefix = '-'; - } - - return `${prefix} ${Math.abs(offset / 3600)}`; - } - - formatTimezone(item) { - return `[UTC ${this.formatUtcOffset(item.offset)}] ${item.name}`; - } - initDefaultTimezone() { const initialValue = this.$input.val(); @@ -56,13 +56,14 @@ export default class TimezoneDropdown { setDropdownToggle() { const initialValue = this.$input.val(); - this.$dropdownToggle.text(initialValue); } updateInputValue({ selectedObj, e }) { e.preventDefault(); this.$input.val(selectedObj.identifier); - gl.pipelineScheduleFieldErrors.updateFormValidityState(); + if (this.onSelectTimezone) { + this.onSelectTimezone({ selectedObj, e }); + } } } diff --git a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/init_form.js b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/init_form.js index 4d494efef6c..dc6df27f1c7 100644 --- a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/init_form.js +++ b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/init_form.js @@ -41,7 +41,13 @@ export default () => { const formElement = document.getElementById('new-pipeline-schedule-form'); - gl.timezoneDropdown = new TimezoneDropdown(); + gl.timezoneDropdown = new TimezoneDropdown({ + $dropdownEl: $('.js-timezone-dropdown'), + $inputEl: $('#schedule_cron_timezone'), + onSelectTimezone: () => { + gl.pipelineScheduleFieldErrors.updateFormValidityState(); + }, + }); gl.targetBranchDropdown = new TargetBranchDropdown(); gl.pipelineScheduleFieldErrors = new GlFieldErrors(formElement); diff --git a/app/assets/stylesheets/framework/system_messages.scss b/app/assets/stylesheets/framework/system_messages.scss index e5edddec71e..6205ccaa52f 100644 --- a/app/assets/stylesheets/framework/system_messages.scss +++ b/app/assets/stylesheets/framework/system_messages.scss @@ -14,6 +14,7 @@ @include str-truncated(100%); margin-top: -1px; margin-bottom: 0; + font-size: $gl-font-size-small; } } diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss index 5d4c84c494d..7d9781ffb87 100644 --- a/app/assets/stylesheets/framework/variables.scss +++ b/app/assets/stylesheets/framework/variables.scss @@ -289,7 +289,6 @@ $gl-line-height: 16px; $gl-line-height-24: 24px; $gl-line-height-14: 14px; -$system-header-height: 35px; $issue-box-upcoming-bg: #8f8f8f; $pages-group-name-color: #4c4e54; diff --git a/app/assets/stylesheets/page_bundles/ide.scss b/app/assets/stylesheets/page_bundles/ide.scss index a80158943c6..0c1067bfacc 100644 --- a/app/assets/stylesheets/page_bundles/ide.scss +++ b/app/assets/stylesheets/page_bundles/ide.scss @@ -179,6 +179,14 @@ $ide-commit-header-height: 48px; display: none; } + .monaco-editor .selected-text { + z-index: 1; + } + + .monaco-editor .view-lines { + z-index: 2; + } + .is-readonly, .editor.original { .view-lines { diff --git a/app/assets/stylesheets/pages/boards.scss b/app/assets/stylesheets/pages/boards.scss index ed0e9db035b..fc1c1bd9962 100644 --- a/app/assets/stylesheets/pages/boards.scss +++ b/app/assets/stylesheets/pages/boards.scss @@ -234,7 +234,7 @@ } .board-title-text { - margin-right: auto; + margin: $gl-vert-padding auto $gl-vert-padding 0; } .board-delete { diff --git a/app/graphql/gitlab_schema.rb b/app/graphql/gitlab_schema.rb index ecc34eacc7d..06d26309b5b 100644 --- a/app/graphql/gitlab_schema.rb +++ b/app/graphql/gitlab_schema.rb @@ -5,7 +5,6 @@ class GitlabSchema < GraphQL::Schema use Gitlab::Graphql::Authorize use Gitlab::Graphql::Present use Gitlab::Graphql::Connections - use Gitlab::Graphql::Tracing query(Types::QueryType) diff --git a/app/services/quick_actions/interpret_service.rb b/app/services/quick_actions/interpret_service.rb index f463e08ee7e..8ff73522e5f 100644 --- a/app/services/quick_actions/interpret_service.rb +++ b/app/services/quick_actions/interpret_service.rb @@ -96,14 +96,27 @@ module QuickActions end def find_labels(labels_params = nil) + extract_references(labels_params, :label) | find_labels_by_name_no_tilde(labels_params) + end + + def find_labels_by_name_no_tilde(labels_params) + return Label.none if label_with_tilde?(labels_params) + finder_params = { include_ancestor_groups: true } finder_params[:project_id] = project.id if project finder_params[:group_id] = group.id if group - finder_params[:name] = labels_params.split if labels_params + finder_params[:name] = extract_label_names(labels_params) if labels_params - result = LabelsFinder.new(current_user, finder_params).execute + LabelsFinder.new(current_user, finder_params).execute + end + + def label_with_tilde?(labels_params) + labels_params&.include?('~') + end - extract_references(labels_params, :label) | result + def extract_label_names(labels_params) + # '"A" "A B C" A B' => ["A", "A B C", "A", "B"] + labels_params.scan(/"([^"]+)"|([^ ]+)/).flatten.compact end def find_label_references(labels_param) diff --git a/changelogs/unreleased/47771-highlighting-in-diff.yml b/changelogs/unreleased/47771-highlighting-in-diff.yml new file mode 100644 index 00000000000..a8e8cbf0174 --- /dev/null +++ b/changelogs/unreleased/47771-highlighting-in-diff.yml @@ -0,0 +1,5 @@ +--- +title: Enabled text selection highlighting in diffs in Web IDE +merge_request: 26721 +author: Isaac Smith +type: fixed diff --git a/changelogs/unreleased/53459-quick-action-adds-multiple-labels-to-issue-if-middle-words-overlap-with-existing-label.yml b/changelogs/unreleased/53459-quick-action-adds-multiple-labels-to-issue-if-middle-words-overlap-with-existing-label.yml new file mode 100644 index 00000000000..30d8c0e95d7 --- /dev/null +++ b/changelogs/unreleased/53459-quick-action-adds-multiple-labels-to-issue-if-middle-words-overlap-with-existing-label.yml @@ -0,0 +1,5 @@ +--- +title: Fix quick actions add label name middle word overlaps +merge_request: 26602 +author: Jacopo Beschi @jacopo-beschi +type: fixed diff --git a/changelogs/unreleased/55980-remove-add-issue-on-blank-list.yml b/changelogs/unreleased/55980-remove-add-issue-on-blank-list.yml new file mode 100644 index 00000000000..4c16b635297 --- /dev/null +++ b/changelogs/unreleased/55980-remove-add-issue-on-blank-list.yml @@ -0,0 +1,5 @@ +--- +title: Remove non-functional add issue button on welcome list +merge_request: !26742 +author: +type: fixed diff --git a/changelogs/unreleased/59131-set-the-size-of-instance-system-message-text-12px.yml b/changelogs/unreleased/59131-set-the-size-of-instance-system-message-text-12px.yml new file mode 100644 index 00000000000..688190f4458 --- /dev/null +++ b/changelogs/unreleased/59131-set-the-size-of-instance-system-message-text-12px.yml @@ -0,0 +1,5 @@ +--- +title: Update system message banner font size to 12px +merge_request: 26293 +author: +type: changed diff --git a/changelogs/unreleased/ekigbo-extend-timezone-dropdown.yml b/changelogs/unreleased/ekigbo-extend-timezone-dropdown.yml new file mode 100644 index 00000000000..42bc320a542 --- /dev/null +++ b/changelogs/unreleased/ekigbo-extend-timezone-dropdown.yml @@ -0,0 +1,5 @@ +--- +title: Extend timezone dropdown +merge_request: 26311 +author: +type: changed diff --git a/changelogs/unreleased/fixed-duplicated-large-text-on-diffs.yml b/changelogs/unreleased/fixed-duplicated-large-text-on-diffs.yml new file mode 100644 index 00000000000..770186a64b0 --- /dev/null +++ b/changelogs/unreleased/fixed-duplicated-large-text-on-diffs.yml @@ -0,0 +1,5 @@ +--- +title: Fixed duplicated diff too large error message +merge_request: +author: +type: fixed diff --git a/changelogs/unreleased/graphql-prometheus.yml b/changelogs/unreleased/graphql-prometheus.yml deleted file mode 100644 index 180577f3aec..00000000000 --- a/changelogs/unreleased/graphql-prometheus.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Added prometheus monitoring to GraphQL -merge_request: -author: -type: added diff --git a/danger/gitlab_ui_wg/Dangerfile b/danger/gitlab_ui_wg/Dangerfile new file mode 100644 index 00000000000..02d94fa5ab7 --- /dev/null +++ b/danger/gitlab_ui_wg/Dangerfile @@ -0,0 +1,55 @@ +def mention_single_codebase_approvers + frontend_maintainers = %w(@filipa @iamphill @psimyn @sarahghp @mishunov) + ux_maintainers = %w(@tauriedavis @rverissimo) + + rows = [] + users = [] + + if gitlab.mr_labels.include?('frontend') + frontend_maintainer = frontend_maintainers.sample + + rows << "| ~frontend | `#{frontend_maintainer}`" + users << frontend_maintainer + end + + if gitlab.mr_labels.include?('UX') + ux_maintainers = ux_maintainers.sample + + rows << "| ~UX | `#{ux_maintainers}`" + users << ux_maintainers + end + + if rows.empty? + backup_maintainer = frontend_maintainers.sample + + rows << "| ~frontend / ~UX | `#{backup_maintainer}`" + users << backup_maintainer + end + + markdown(<<~MARKDOWN.strip) + ## GitLab UI Working Group changes + + This merge request contains changes related to the work of [cleaning up CSS and creating + reusable components](https://gitlab.com/groups/gitlab-org/-/epics/950). + These changes will need to be reviewed and approved by the following engineers: + + | Category | Reviewer + |----------|--------- + #{rows.join("\n")} + + To make sure this happens, please follow these steps: + + 1. Add all of the mentioned users to the list of merge request approvals. + 2. Assign the merge request to the first person in the above list. + + If you are a reviewer, please follow these steps: + + 1. Review the merge request. If it is good to go, approve it. + 2. Once approved, assign to the next person in the above list. If you are + the last person in the list, merge the merge request. + MARKDOWN +end + +if gitlab.mr_labels.include?('CSS cleanup') + mention_single_codebase_approvers +end diff --git a/danger/roulette/Dangerfile b/danger/roulette/Dangerfile index 808bc96a0a0..3a4625c4eb6 100644 --- a/danger/roulette/Dangerfile +++ b/danger/roulette/Dangerfile @@ -60,7 +60,9 @@ categories = changes.keys - [:unknown] # Single codebase MRs are reviewed using a slightly different process, so we # disable the review roulette for such MRs. -if changes.any? && !gitlab.mr_labels.include?('single codebase') +# CSS Clean up MRs are reviewed using a slightly different process, so we +# disable the review roulette for such MRs. +if changes.any? && !gitlab.mr_labels.include?('single codebase') && !gitlab.mr_labels.include?('CSS cleanup') team = begin helper.project_team diff --git a/doc/ci/variables/README.md b/doc/ci/variables/README.md index e4d826e5919..592fdfd2873 100644 --- a/doc/ci/variables/README.md +++ b/doc/ci/variables/README.md @@ -2,49 +2,244 @@ table_display_block: true --- -# GitLab CI/CD Variables +# GitLab CI/CD environment variables +{: #variables} -When receiving a job from GitLab CI, the [Runner](https://docs.gitlab.com/runner/) prepares the build environment. -It starts by setting a list of: +After a brief overview over the use of environment +variables, this document teaches you how to use GitLab CI/CD's +variables, presents the full reference for predefined variables, +and dives into more advanced applications. -- [Predefined environment variables](#predefined-environment-variables). -- Other variables. +## Overview -## Priority of variables +An environment variable is a dynamic-named value that can +affect the way running processes will behave on an operating +system. -Variables of different types can take precedence over other variables, depending on where they are defined. +They are part of the environment in which a process runs. +For example, a running process can query the value of the +`TEMP` environment variable to discover a suitable location +to store temporary files, or to define a `URL` for a database +that can be reused in different scripts. -The order of precedence for variables is (from highest to lowest): +Variables are useful for customizing your jobs in GitLab +CI/CD's pipelines. Using variables means no hardcoded values. -1. [Trigger variables](../triggers/README.md#making-use-of-trigger-variables) or [scheduled pipeline variables](../../user/project/pipelines/schedules.md#making-use-of-scheduled-pipeline-variables). -1. Project-level [variables](#variables) or [protected variables](#protected-variables). -1. Group-level [variables](#variables) or [protected variables](#protected-variables). -1. YAML-defined [job-level variables](../yaml/README.md#variables). -1. YAML-defined [global variables](../yaml/README.md#variables). -1. [Deployment variables](#deployment-variables). -1. [Predefined environment variables](#predefined-environment-variables). +### Predefined environment variables -For example, you define: +GitLab CI/CD has a default set of +[predefined variables](predefined_variables.md) +which can be used without any specification needed. +You can call issues numbers, user names, branch names, +pipeline and commit IDs, and much more. -- `API_TOKEN=secure` as a project variable. -- `API_TOKEN=yaml` in your `.gitlab-ci.yml`. +Predefined environment variables are the ones that GitLab +provides out of the box for the local environment of the Runner. -`API_TOKEN` will take the value `secure` as the project variables take precedence over those defined -in `.gitlab-ci.yml`. +GitLab reads the .gitlab-ci.yml file, sends the information +to the Runner (which runs the script commands), under which +the variables are exposed. -## Unsupported variables +For example, two jobs under the same pipeline can share the same +`CI_PIPELINE_ID` variable, but each one has its own `CI_JOB_ID` +variable. -There are cases where some variables cannot be used in the context of a -`.gitlab-ci.yml` definition (for example under `script`). Read more -about which variables are [not supported](where_variables_can_be_used.md). +### Custom environment variables + +When your use case requires a specific variable, you can +[set them up easily from the UI](#creating-a-custom-environment-variable) +or directly in the `.gitlab-ci.yml` file and reuse them as you wish. + +That can be very powerful as it can be used for scripting without +the need to specify the value itself. + +## Getting started + +To get started with environment variables in the scope of GitLab +CI/CD, let's go over a few examples. + +### Using predefined environment variables + +To get started, choose one of the existing +[predefined variables](predefined_variables.md) +to be output by the Runner. For example, let's say that you want +a given job you're running through your script to output the +stage that job is running for. In your `.gitlab-ci.yml` file, +call the variable from your script according to the [syntaxes](#syntax-of-variables-in-job-scripts) available. To +output the job stage, use the predefined variable `CI_JOB_STAGE`: + +```yaml +test_variable: + stage: test + script: + - echo $CI_JOB_STAGE +``` + +For this case, the Runner will output the `stage` for the +job `test_variable`, which is `test`: + + + +As another example, let's say you're using your own GitLab +instance you want to know what domain your GitLab Pages are +served under. You can easily call it with the predefined +variable `$CI_PAGES_DOMAIN` in your script: + +```yaml +pages: + script: + - ... + - echo $CI_PAGES_DOMAIN +``` + +For GitLab.com users, the output will be `gitlab.io`. For your +private instance, the output will be whatever your sysadmin has +defined. + +### Creating a custom environment variable + +Assume you have something you want to repeat through your scripts +in GitLab CI/CD's configuration file. To keep this example simple, +let's say you want to output `HELLO WORLD` for a `TEST` variable. + +You can either set the variable directly in the `.gitlab-ci.yml` +file or through the UI. + +#### Via [`.gitlab-ci.yml`](../yaml/README.md#variables) + +```yaml +variables: + TEST: "HELLO WORLD" +``` + +For a deeper look into them, see [`.gitlab-ci.yml` defined variables](#gitlab-ciyml-defined-variables). + +#### Via the UI + +From the UI, navigate to your project's **Settings > CI/CD** and +expand **Environment variables**. Create a new variable by naming +it in the field **Input variable key**, and define its value in the +**Input variable value** field: + + + +Once you've set the variables, call them from the `.gitlab-ci.yml` file: + +```yaml +test_variable: + stage: test + script: + - echo $CI_JOB_STAGE # calls a predefined variable + - echo $TEST # calls a custom variable +``` + +The output will be: + + + +CAUTION: **Important:** +Be aware that variables are not masked, and their values can be shown +in the job logs if explicitly asked to do so. If your project is public or +internal, you can set the pipelines private from your [project's Pipelines +settings](../../user/project/pipelines/settings.md#visibility-of-pipelines). +Follow the discussion in issue [#13784][ce-13784] for masking the variables. + +### Syntax of environment variables in job scripts +{: #syntax-of-variables-in-job-scripts} -## Predefined environment variables +All variables are set as environment variables in the build environment, and +they are accessible with normal methods that are used to access such variables. +In most cases `bash` or `sh` is used to execute the job script. + +To access environment variables, use the syntax for your Runner's [shell][shellexecutors]. + +| Shell | Usage | +|----------------------|-----------------| +| bash/sh | `$variable` | +| windows batch | `%variable%` | +| PowerShell | `$env:variable` | + +To access environment variables in bash, prefix the variable name with (`$`): + +```yaml +job_name: + script: + - echo $CI_JOB_ID +``` + +To access environment variables in **Windows Batch**, surround the variable +with (`%`): + +```yaml +job_name: + script: + - echo %CI_JOB_ID% +``` -See [full reference of predefined environment variables](predefined_variables.md). +To access environment variables in a **Windows PowerShell** environment, prefix +the variable name with (`$env:`): + +```yaml +job_name: + script: + - echo $env:CI_JOB_ID +``` + +You can also list all environment variables with the `export` command, +but be aware that this will also expose the values of all the variables +you set, in the job log: + +```yaml +job_name: + script: + - export +``` + +Example values: + +```bash +export CI_JOB_ID="50" +export CI_COMMIT_SHA="1ecfd275763eff1d6b4844ea3168962458c9f27a" +export CI_COMMIT_SHORT_SHA="1ecfd275" +export CI_COMMIT_REF_NAME="master" +export CI_REPOSITORY_URL="https://gitlab-ci-token:abcde-1234ABCD5678ef@example.com/gitlab-org/gitlab-ce.git" +export CI_COMMIT_TAG="1.0.0" +export CI_JOB_NAME="spec:other" +export CI_JOB_STAGE="test" +export CI_JOB_MANUAL="true" +export CI_JOB_TRIGGERED="true" +export CI_JOB_TOKEN="abcde-1234ABCD5678ef" +export CI_PIPELINE_ID="1000" +export CI_PIPELINE_IID="10" +export CI_PAGES_DOMAIN="gitlab.io" +export CI_PAGES_URL="https://gitlab-org.gitlab.io/gitlab-ce" +export CI_PROJECT_ID="34" +export CI_PROJECT_DIR="/builds/gitlab-org/gitlab-ce" +export CI_PROJECT_NAME="gitlab-ce" +export CI_PROJECT_NAMESPACE="gitlab-org" +export CI_PROJECT_PATH="gitlab-org/gitlab-ce" +export CI_PROJECT_URL="https://example.com/gitlab-org/gitlab-ce" +export CI_REGISTRY="registry.example.com" +export CI_REGISTRY_IMAGE="registry.example.com/gitlab-org/gitlab-ce" +export CI_RUNNER_ID="10" +export CI_RUNNER_DESCRIPTION="my runner" +export CI_RUNNER_TAGS="docker, linux" +export CI_SERVER="yes" +export CI_SERVER_NAME="GitLab" +export CI_SERVER_REVISION="70606bf" +export CI_SERVER_VERSION="8.9.0" +export CI_SERVER_VERSION_MAJOR="8" +export CI_SERVER_VERSION_MINOR="9" +export CI_SERVER_VERSION_PATCH="0" +export GITLAB_USER_ID="42" +export GITLAB_USER_EMAIL="user@example.com" +export CI_REGISTRY_USER="gitlab-ci-token" +export CI_REGISTRY_PASSWORD="longalfanumstring" +``` -## `.gitlab-ci.yml` defined variables +### `.gitlab-ci.yml` defined variables -NOTE **Note:** +NOTE: **Note:** This feature requires GitLab Runner 0.5.0 or higher and GitLab 7.14 or higher. GitLab CI allows you to add to `.gitlab-ci.yml` variables that are set in the @@ -82,42 +277,63 @@ script: - 'eval $LS_CMD' # will execute 'ls -al $TMP_DIR' ``` -## Variables +### Group-level environment variables +{: #group-level-variables} -> Group-level variables were introduced in GitLab 9.4. - -CAUTION: **Important:** -Be aware that variables are not masked, and their values can be shown -in the job logs if explicitly asked to do so. If your project is public or -internal, you can set the pipelines private from your [project's Pipelines -settings](../../user/project/pipelines/settings.md#visibility-of-pipelines). -Follow the discussion in issue [#13784][ce-13784] for masking the variables. +> Introduced in GitLab 9.4. -GitLab CI allows you to define per-project or per-group variables -that are set in the pipeline environment. The variables are stored out of +GitLab CI/CD allows you to define per-project or per-group variables +that are set in the pipeline environment. Group-level variables are stored out of the repository (not in `.gitlab-ci.yml`) and are securely passed to GitLab Runner -making them available during a pipeline run. It's the recommended method to +making them available during a pipeline run. It's the **recommended method** to use for storing things like passwords, SSH keys, and credentials. -Project-level variables can be added by: +Group-level variables can be added by: -1. Navigating to your project's **Settings > CI/CD** page. +1. Navigating to your group's **Settings > CI/CD** page. 1. Inputing variable keys and values in the **Environment variables** section. +Any variables of [subgroups](../../user/group/subgroups/index.md) will be inherited recursively. -Group-level variables can be added by: +Once you set them, they will be available for all subsequent pipelines. -1. Navigating to your group's **Settings > CI/CD** page. -1. Inputing variable keys and values in the **Environment variables** section. Any variables of - [subgroups](../../user/group/subgroups/index.md) will be inherited recursively. +## Priority of environment variables +{: #priority-of-variables} + +Variables of different types can take precedence over other +variables, depending on where they are defined. + +The order of precedence for variables is (from highest to lowest): + +1. [Trigger variables](../triggers/README.md#making-use-of-trigger-variables) or [scheduled pipeline variables](../../user/project/pipelines/schedules.md#making-use-of-scheduled-pipeline-variables). +1. Project-level [variables](#creating-a-custom-environment-variable) or [protected variables](#protected-variables). +1. Group-level [variables](#group-level-variables) or [protected variables](#protected-variables). +1. YAML-defined [job-level variables](../yaml/README.md#variables). +1. YAML-defined [global variables](../yaml/README.md#variables). +1. [Deployment variables](#deployment-variables). +1. [Predefined environment variables](predefined_variables.md). + +For example, if you define: + +- `API_TOKEN=secure` as a project variable. +- `API_TOKEN=yaml` in your `.gitlab-ci.yml`. -Once you set them, they will be available for all subsequent pipelines. You can also -[protect your variables](#protected-variables). +`API_TOKEN` will take the value `secure` as the project +variables take precedence over those defined in `.gitlab-ci.yml`. -### Protected variables +## Unsupported variables + +There are cases where some variables cannot be used in the context of a +`.gitlab-ci.yml` definition (for example under `script`). Read more +about which variables are [not supported](where_variables_can_be_used.md). + +## Advanced use + +### Protected environment variables +{: #protected-variables} > Introduced in GitLab 9.3. -Variables could be protected. Whenever a variable is +Variables can be protected. Whenever a variable is protected, it would only be securely passed to pipelines running on the [protected branches] or [protected tags]. The other pipelines would not get any protected variables. @@ -128,13 +344,8 @@ Protected variables can be added by going to your project's Once you set them, they will be available for all subsequent pipelines. -### Manually-specified variables - -> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/44059) in GitLab 10.8. - -Variables can be specified for a single pipeline run when a [manual pipeline](../pipelines.md#manually-executing-pipelines) is created. - -## Deployment variables +### Deployment environment variables +{: #deployment-variables} > Introduced in GitLab 8.15. @@ -147,7 +358,7 @@ the project services that you are using to learn which variables they define. An example project service that defines deployment variables is the [Kubernetes integration](../../user/project/clusters/index.md#deployment-variables). -## Auto DevOps application variables +### Auto DevOps environment variables > [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/49056) in GitLab 11.7. @@ -164,6 +375,113 @@ CAUTION: **Caution:** Variables with multiline values are not currently supported due to limitations with the current Auto DevOps scripting environment. +### Environment variables triggered manually + +> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/44059) in GitLab 10.8. + +[Manually triggered pipelines](../pipelines.md#manually-executing-pipelines) allow you to override the value of a current variable. + +For instance, suppose you added a +[custom variable `$TEST`](#creating-a-custom-variable) +as exemplified above and you want to override it in a manual pipeline. +Navigate to your project's **CI/CD > Pipelines** and click **Run pipeline**. +Choose the branch you want to run the pipeline for, then add a new variable +pair through the UI: + + + +The Runner will override the value previously set and use the custom +value you set for this specific pipeline: + + + +## Environment variables expressions +{: #variables-expressions} + +> Introduced in GitLab 10.7. + +It is possible to use variables expressions with only / except policies in +`.gitlab-ci.yml`. By using this approach you can limit what jobs are going to +be created within a pipeline after pushing a code to GitLab. + +This is particularly useful in combination with variables and triggered +pipeline variables. + +```yaml +deploy: + script: cap staging deploy + environment: staging + only: + variables: + - $RELEASE == "staging" + - $STAGING +``` + +Each expression provided is going to be evaluated before creating a pipeline. + +If any of the conditions in `variables` evaluates to truth when using `only`, +a new job is going to be created. If any of the expressions evaluates to truth +when `except` is being used, a job is not going to be created. + +This follows usual rules for [`only` / `except` policies](../yaml/README.md#onlyexcept-advanced). + +### Supported syntax + +Below you can find supported syntax reference: + +1. Equality matching using a string + + > Example: `$VARIABLE == "some value"` + + You can use equality operator `==` to compare a variable content to a + string. We support both, double quotes and single quotes to define a string + value, so both `$VARIABLE == "some value"` and `$VARIABLE == 'some value'` + are supported. `"some value" == $VARIABLE` is correct too. + +1. Checking for an undefined value + + > Example: `$VARIABLE == null` + + It sometimes happens that you want to check whether a variable is defined + or not. To do that, you can compare a variable to `null` keyword, like + `$VARIABLE == null`. This expression is going to evaluate to truth if + variable is not defined. + +1. Checking for an empty variable + + > Example: `$VARIABLE == ""` + + If you want to check whether a variable is defined, but is empty, you can + simply compare it against an empty string, like `$VAR == ''`. + +1. Comparing two variables + + > Example: `$VARIABLE_1 == $VARIABLE_2` + + It is possible to compare two variables. This is going to compare values + of these variables. + +1. Variable presence check + + > Example: `$STAGING` + + If you only want to create a job when there is some variable present, + which means that it is defined and non-empty, you can simply use + variable name as an expression, like `$STAGING`. If `$STAGING` variable + is defined, and is non empty, expression will evaluate to truth. + `$STAGING` value needs to a string, with length higher than zero. + Variable that contains only whitespace characters is not an empty variable. + +1. Pattern matching _(added in 11.0)_ + + > Example: `$VARIABLE =~ /^content.*/` + + It is possible perform pattern matching against a variable and regular + expression. Expression like this evaluates to truth if matches are found. + + Pattern matching is case-sensitive by default. Use `i` flag modifier, like + `/pattern/i` to make a pattern case-insensitive. + ## Debug tracing > Introduced in GitLab Runner 1.7. @@ -333,184 +651,6 @@ MIIFQzCCBCugAwIBAgIRAL/ElDjuf15xwja1ZnCocWAwDQYJKoZIhvcNAQELBQAw' ... ``` -## Using the CI variables in your job scripts - -All variables are set as environment variables in the build environment, and -they are accessible with normal methods that are used to access such variables. -In most cases `bash` or `sh` is used to execute the job script. - -To access environment variables, use the syntax for your Runner's [shell][shellexecutors]. - -| Shell | Usage | -|----------------------|-----------------| -| bash/sh | `$variable` | -| windows batch | `%variable%` | -| PowerShell | `$env:variable` | - -To access environment variables in bash, prefix the variable name with (`$`): - -```yaml -job_name: - script: - - echo $CI_JOB_ID -``` - -To access environment variables in **Windows Batch**, surround the variable -with (`%`): - -```yaml -job_name: - script: - - echo %CI_JOB_ID% -``` - -To access environment variables in a **Windows PowerShell** environment, prefix -the variable name with (`$env:`): - -```yaml -job_name: - script: - - echo $env:CI_JOB_ID -``` - -You can also list all environment variables with the `export` command, -but be aware that this will also expose the values of all the variables -you set, in the job log: - -```yaml -job_name: - script: - - export -``` - -Example values: - -```bash -export CI_JOB_ID="50" -export CI_COMMIT_SHA="1ecfd275763eff1d6b4844ea3168962458c9f27a" -export CI_COMMIT_SHORT_SHA="1ecfd275" -export CI_COMMIT_REF_NAME="master" -export CI_REPOSITORY_URL="https://gitlab-ci-token:abcde-1234ABCD5678ef@example.com/gitlab-org/gitlab-ce.git" -export CI_COMMIT_TAG="1.0.0" -export CI_JOB_NAME="spec:other" -export CI_JOB_STAGE="test" -export CI_JOB_MANUAL="true" -export CI_JOB_TRIGGERED="true" -export CI_JOB_TOKEN="abcde-1234ABCD5678ef" -export CI_PIPELINE_ID="1000" -export CI_PIPELINE_IID="10" -export CI_PAGES_DOMAIN="gitlab.io" -export CI_PAGES_URL="https://gitlab-org.gitlab.io/gitlab-ce" -export CI_PROJECT_ID="34" -export CI_PROJECT_DIR="/builds/gitlab-org/gitlab-ce" -export CI_PROJECT_NAME="gitlab-ce" -export CI_PROJECT_NAMESPACE="gitlab-org" -export CI_PROJECT_PATH="gitlab-org/gitlab-ce" -export CI_PROJECT_URL="https://example.com/gitlab-org/gitlab-ce" -export CI_REGISTRY="registry.example.com" -export CI_REGISTRY_IMAGE="registry.example.com/gitlab-org/gitlab-ce" -export CI_RUNNER_ID="10" -export CI_RUNNER_DESCRIPTION="my runner" -export CI_RUNNER_TAGS="docker, linux" -export CI_SERVER="yes" -export CI_SERVER_NAME="GitLab" -export CI_SERVER_REVISION="70606bf" -export CI_SERVER_VERSION="8.9.0" -export CI_SERVER_VERSION_MAJOR="8" -export CI_SERVER_VERSION_MINOR="9" -export CI_SERVER_VERSION_PATCH="0" -export GITLAB_USER_ID="42" -export GITLAB_USER_EMAIL="user@example.com" -export CI_REGISTRY_USER="gitlab-ci-token" -export CI_REGISTRY_PASSWORD="longalfanumstring" -``` - -## Variables expressions - -> Introduced in GitLab 10.7. - -It is possible to use variables expressions with only / except policies in -`.gitlab-ci.yml`. By using this approach you can limit what jobs are going to -be created within a pipeline after pushing a code to GitLab. - -This is particularly useful in combination with variables and triggered -pipeline variables. - -```yaml -deploy: - script: cap staging deploy - environment: staging - only: - variables: - - $RELEASE == "staging" - - $STAGING -``` - -Each expression provided is going to be evaluated before creating a pipeline. - -If any of the conditions in `variables` evaluates to truth when using `only`, -a new job is going to be created. If any of the expressions evaluates to truth -when `except` is being used, a job is not going to be created. - -This follows usual rules for [`only` / `except` policies](../yaml/README.md#onlyexcept-advanced). - -### Supported syntax - -Below you can find supported syntax reference: - -1. Equality matching using a string - - > Example: `$VARIABLE == "some value"` - - You can use equality operator `==` to compare a variable content to a - string. We support both, double quotes and single quotes to define a string - value, so both `$VARIABLE == "some value"` and `$VARIABLE == 'some value'` - are supported. `"some value" == $VARIABLE` is correct too. - -1. Checking for an undefined value - - > Example: `$VARIABLE == null` - - It sometimes happens that you want to check whether a variable is defined - or not. To do that, you can compare a variable to `null` keyword, like - `$VARIABLE == null`. This expression is going to evaluate to truth if - variable is not defined. - -1. Checking for an empty variable - - > Example: `$VARIABLE == ""` - - If you want to check whether a variable is defined, but is empty, you can - simply compare it against an empty string, like `$VAR == ''`. - -1. Comparing two variables - - > Example: `$VARIABLE_1 == $VARIABLE_2` - - It is possible to compare two variables. This is going to compare values - of these variables. - -1. Variable presence check - - > Example: `$STAGING` - - If you only want to create a job when there is some variable present, - which means that it is defined and non-empty, you can simply use - variable name as an expression, like `$STAGING`. If `$STAGING` variable - is defined, and is non empty, expression will evaluate to truth. - `$STAGING` value needs to a string, with length higher than zero. - Variable that contains only whitespace characters is not an empty variable. - -1. Pattern matching _(added in 11.0)_ - - > Example: `$VARIABLE =~ /^content.*/` - - It is possible perform pattern matching against a variable and regular - expression. Expression like this evaluates to truth if matches are found. - - Pattern matching is case-sensitive by default. Use `i` flag modifier, like - `/pattern/i` to make a pattern case-insensitive. - [ce-13784]: https://gitlab.com/gitlab-org/gitlab-ce/issues/13784 "Simple protection of CI variables" [eep]: https://about.gitlab.com/pricing/ "Available only in GitLab Premium" [envs]: ../environments.md diff --git a/doc/ci/variables/img/ci_job_stage_output_example.png b/doc/ci/variables/img/ci_job_stage_output_example.png Binary files differnew file mode 100755 index 00000000000..056238d5693 --- /dev/null +++ b/doc/ci/variables/img/ci_job_stage_output_example.png diff --git a/doc/ci/variables/img/custom_variable_output.png b/doc/ci/variables/img/custom_variable_output.png Binary files differnew file mode 100755 index 00000000000..50f3bceff9a --- /dev/null +++ b/doc/ci/variables/img/custom_variable_output.png diff --git a/doc/ci/variables/img/new_custom_variable_example.png b/doc/ci/variables/img/new_custom_variable_example.png Binary files differnew file mode 100755 index 00000000000..d169c5f1806 --- /dev/null +++ b/doc/ci/variables/img/new_custom_variable_example.png diff --git a/doc/ci/variables/img/override_value_via_manual_pipeline_output.png b/doc/ci/variables/img/override_value_via_manual_pipeline_output.png Binary files differnew file mode 100755 index 00000000000..02369d57fb8 --- /dev/null +++ b/doc/ci/variables/img/override_value_via_manual_pipeline_output.png diff --git a/doc/ci/variables/img/override_variable_manual_pipeline.png b/doc/ci/variables/img/override_variable_manual_pipeline.png Binary files differnew file mode 100755 index 00000000000..3bcd354e096 --- /dev/null +++ b/doc/ci/variables/img/override_variable_manual_pipeline.png diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md index 5690729c370..83a226d3577 100644 --- a/doc/ci/yaml/README.md +++ b/doc/ci/yaml/README.md @@ -391,6 +391,11 @@ job: The above example will run `job` for all branches on `gitlab-org/gitlab-ce`, except `master` and those with names prefixed with `release/`. +NOTE: **Note:** +Because `@` is used to denote the beginning of a ref's repository path, +matching a ref name containing the `@` character in a regular expression +requires the use of the hex character code match `\x40`. + If a job does not have an `only` rule, `only: ['branches', 'tags']` is set by default. If it doesn't have an `except` rule, it is empty. diff --git a/doc/user/profile/account/two_factor_authentication.md b/doc/user/profile/account/two_factor_authentication.md index 8b3ae19b544..69dfad829b4 100644 --- a/doc/user/profile/account/two_factor_authentication.md +++ b/doc/user/profile/account/two_factor_authentication.md @@ -161,6 +161,7 @@ a new set of recovery codes with SSH. 1. Run `ssh git@gitlab.example.com 2fa_recovery_codes`. 1. You are prompted to confirm that you want to generate new codes. Continuing this process invalidates previously saved codes. + ``` bash $ ssh git@gitlab.example.com 2fa_recovery_codes diff --git a/doc/user/project/clusters/serverless/index.md b/doc/user/project/clusters/serverless/index.md index e6804666e22..96bf455116c 100644 --- a/doc/user/project/clusters/serverless/index.md +++ b/doc/user/project/clusters/serverless/index.md @@ -214,7 +214,7 @@ The sample function can now be triggered from any HTTP client using a simple `PO --header "Content-Type: application/json" \ --request POST \ --data '{"GitLab":"FaaS"}' \ - <http://functions-echo.functions-1.functions.example.com/> + http://functions-echo.functions-1.functions.example.com ``` 2. Using a web-based tool (ie. postman, restlet, etc) diff --git a/doc/user/project/quick_actions.md b/doc/user/project/quick_actions.md index 392e72dcc5c..88f4de891a1 100644 --- a/doc/user/project/quick_actions.md +++ b/doc/user/project/quick_actions.md @@ -31,7 +31,7 @@ discussions, and descriptions: | `/reassign @user1 @user2` | Change assignee | ✓ | ✓ | | `/milestone %milestone` | Set milestone | ✓ | ✓ | | `/remove_milestone` | Remove milestone | ✓ | ✓ | -| `/label ~label1 ~label2` | Add label(s) | ✓ | ✓ | +| `/label ~label1 ~label2` | Add label(s). Label names can also start without ~ but mixed syntax is not supported. | ✓ | ✓ | | `/unlabel ~label1 ~label2` | Remove all or specific label(s)| ✓ | ✓ | | `/relabel ~label1 ~label2` | Replace label | ✓ | ✓ | | <code>/copy_metadata #issue | !merge_request</code> | Copy labels and milestone from other issue or merge request | ✓ | ✓ | diff --git a/lib/gitlab/graphql/tracing.rb b/lib/gitlab/graphql/tracing.rb deleted file mode 100644 index 6b505e4262b..00000000000 --- a/lib/gitlab/graphql/tracing.rb +++ /dev/null @@ -1,43 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module Graphql - class Tracing < GraphQL::Tracing::PlatformTracing - self.platform_keys = { - 'lex' => 'graphql.lex', - 'parse' => 'graphql.parse', - 'validate' => 'graphql.validate', - 'analyze_query' => 'graphql.analyze', - 'analyze_multiplex' => 'graphql.analyze', - 'execute_multiplex' => 'graphql.execute', - 'execute_query' => 'graphql.execute', - 'execute_query_lazy' => 'graphql.execute', - 'execute_field' => 'graphql.execute', - 'execute_field_lazy' => 'graphql.execute' - } - - def platform_field_key(type, field) - "#{type.name}.#{field.name}" - end - - def platform_trace(platform_key, key, data, &block) - start = Gitlab::Metrics::System.monotonic_time - - yield - ensure - duration = Gitlab::Metrics::System.monotonic_time - start - - graphql_duration_seconds.observe({ platform_key: platform_key, key: key }, duration) - end - - private - - def graphql_duration_seconds - @graphql_duration_seconds ||= Gitlab::Metrics.histogram( - :graphql_duration_seconds, - 'GraphQL execution time' - ) - end - end - end -end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index fcbd34a05d5..bb145a0984f 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -8278,9 +8278,6 @@ msgstr "" msgid "This setting will update the hostname that is used to generate private commit emails. %{learn_more}" msgstr "" -msgid "This source diff could not be displayed because it is too large." -msgstr "" - msgid "This timeout will take precedence when lower than project-defined timeout and accepts a human readable time input language like \"1 hour\". Values without specification represent seconds." msgstr "" diff --git a/package.json b/package.json index a2d96cc551a..934a30df261 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "@babel/plugin-syntax-import-meta": "^7.2.0", "@babel/preset-env": "^7.3.1", "@gitlab/csslab": "^1.9.0", - "@gitlab/svgs": "^1.57.0", + "@gitlab/svgs": "^1.58.0", "@gitlab/ui": "^3.0.0", "apollo-cache-inmemory": "^1.5.1", "apollo-client": "^2.5.1", @@ -56,11 +56,13 @@ "d3-array": "^1.2.1", "d3-axis": "^1.0.8", "d3-brush": "^1.0.4", + "d3-ease": "^1.0.3", "d3-scale": "^1.0.7", "d3-selection": "^1.2.0", "d3-shape": "^1.2.0", "d3-time": "^1.0.8", "d3-time-format": "^2.1.1", + "d3-transition": "^1.1.1", "dateformat": "^3.0.3", "deckar01-task_list": "^2.2.0", "diff": "^3.4.0", diff --git a/qa/STYLE_GUIDE.md b/qa/STYLE_GUIDE.md index f85e7492409..900f7456e1a 100644 --- a/qa/STYLE_GUIDE.md +++ b/qa/STYLE_GUIDE.md @@ -43,4 +43,4 @@ end Notice that in the above example, before clicking the `:operations_environments_link`, another element is hovered over. -> We can create these methods as helpers to abstrac multi-step navigation.
\ No newline at end of file +> We can create these methods as helpers to abstract multi-step navigation.
\ No newline at end of file diff --git a/spec/javascripts/boards/components/board_spec.js b/spec/javascripts/boards/components/board_spec.js index 6e6b3e6950b..d08ee41802b 100644 --- a/spec/javascripts/boards/components/board_spec.js +++ b/spec/javascripts/boards/components/board_spec.js @@ -103,4 +103,18 @@ describe('Board component', () => { }) .catch(done.fail); }); + + it('does render add issue button', () => { + expect(vm.$el.querySelector('.issue-count-badge-add-button')).not.toBeNull(); + }); + + it('does not render add issue button when list type is blank', done => { + vm.list.type = 'blank'; + + Vue.nextTick(() => { + expect(vm.$el.querySelector('.issue-count-badge-add-button')).toBeNull(); + + done(); + }); + }); }); diff --git a/spec/javascripts/diffs/components/diff_file_spec.js b/spec/javascripts/diffs/components/diff_file_spec.js index d9b298e84da..ef4589ada48 100644 --- a/spec/javascripts/diffs/components/diff_file_spec.js +++ b/spec/javascripts/diffs/components/diff_file_spec.js @@ -141,18 +141,16 @@ describe('DiffFile', () => { it('should have too large warning and blob link', done => { const BLOB_LINK = '/file/view/path'; vm.file.viewer.error = diffViewerErrors.too_large; + vm.file.viewer.error_message = + 'This source diff could not be displayed because it is too large'; vm.file.view_path = BLOB_LINK; + vm.file.renderIt = true; vm.$nextTick(() => { expect(vm.$el.innerText).toContain( 'This source diff could not be displayed because it is too large', ); - expect(vm.$el.querySelector('.js-too-large-diff')).toBeDefined(); - expect( - vm.$el.querySelector('.js-too-large-diff a').href.indexOf(BLOB_LINK), - ).toBeGreaterThan(-1); - done(); }); }); diff --git a/spec/javascripts/pages/projects/pipeline_schedules/shared/components/timezone_dropdown_spec.js b/spec/javascripts/pages/projects/pipeline_schedules/shared/components/timezone_dropdown_spec.js new file mode 100644 index 00000000000..a89952ee435 --- /dev/null +++ b/spec/javascripts/pages/projects/pipeline_schedules/shared/components/timezone_dropdown_spec.js @@ -0,0 +1,167 @@ +import $ from 'jquery'; +import GLDropdown from '~/gl_dropdown'; // eslint-disable-line no-unused-vars +import TimezoneDropdown, { + formatUtcOffset, + formatTimezone, +} from '~/pages/projects/pipeline_schedules/shared/components/timezone_dropdown'; + +describe('Timezone Dropdown', function() { + preloadFixtures('pipeline_schedules/edit.html'); + + let $inputEl = null; + let $dropdownEl = null; + let $wrapper = null; + const tzListSel = '.dropdown-content ul li a.is-active'; + + describe('Initialize', () => { + describe('with dropdown already loaded', () => { + beforeEach(() => { + loadFixtures('pipeline_schedules/edit.html'); + $wrapper = $('.dropdown'); + $inputEl = $('#schedule_cron_timezone'); + $dropdownEl = $('.js-timezone-dropdown'); + + // eslint-disable-next-line no-new + new TimezoneDropdown({ + $inputEl, + $dropdownEl, + }); + }); + + it('can take an $inputEl in the constructor', () => { + const tzStr = '[UTC + 5.5] Sri Jayawardenepura'; + const tzValue = 'Asia/Colombo'; + + expect($inputEl.val()).toBe('UTC'); + + $(`${tzListSel}:contains('${tzStr}')`, $wrapper).trigger('click'); + + const val = $inputEl.val(); + + expect(val).toBe(tzValue); + expect(val).not.toBe('UTC'); + }); + + it('will format data array of timezones into a list of offsets', () => { + const data = $dropdownEl.data('data'); + const formatted = $wrapper.find(tzListSel).text(); + + data.forEach(item => { + expect(formatted).toContain(formatTimezone(item)); + }); + }); + + it('will default the timezone to UTC', () => { + const tz = $inputEl.val(); + + expect(tz).toBe('UTC'); + }); + }); + + describe('without dropdown loaded', () => { + beforeEach(() => { + loadFixtures('pipeline_schedules/edit.html'); + $wrapper = $('.dropdown'); + $inputEl = $('#schedule_cron_timezone'); + $dropdownEl = $('.js-timezone-dropdown'); + }); + + it('will populate the list of UTC offsets after the dropdown is loaded', () => { + expect($wrapper.find(tzListSel).length).toEqual(0); + + // eslint-disable-next-line no-new + new TimezoneDropdown({ + $inputEl, + $dropdownEl, + }); + + expect($wrapper.find(tzListSel).length).toEqual($($dropdownEl).data('data').length); + }); + + it('will call a provided handler when a new timezone is selected', () => { + const onSelectTimezone = jasmine.createSpy('onSelectTimezoneMock'); + // eslint-disable-next-line no-new + new TimezoneDropdown({ + $inputEl, + $dropdownEl, + onSelectTimezone, + }); + + $wrapper + .find(tzListSel) + .first() + .trigger('click'); + + expect(onSelectTimezone).toHaveBeenCalled(); + }); + }); + }); + + describe('formatUtcOffset', () => { + it('will convert negative utc offsets in seconds to hours and minutes', () => { + expect(formatUtcOffset(-21600)).toEqual('- 6'); + }); + + it('will convert positive utc offsets in seconds to hours and minutes', () => { + expect(formatUtcOffset(25200)).toEqual('+ 7'); + expect(formatUtcOffset(49500)).toEqual('+ 13.75'); + }); + + it('will return 0 when given a string', () => { + expect(formatUtcOffset('BLAH')).toEqual('0'); + expect(formatUtcOffset('$%$%')).toEqual('0'); + }); + + it('will return 0 when given an array', () => { + expect(formatUtcOffset(['an', 'array'])).toEqual('0'); + }); + + it('will return 0 when given an object', () => { + expect(formatUtcOffset({ some: '', object: '' })).toEqual('0'); + }); + + it('will return 0 when given null', () => { + expect(formatUtcOffset(null)).toEqual('0'); + }); + + it('will return 0 when given undefined', () => { + expect(formatUtcOffset(undefined)).toEqual('0'); + }); + + it('will return 0 when given empty input', () => { + expect(formatUtcOffset('')).toEqual('0'); + }); + }); + + describe('formatTimezone', () => { + it('given name: "Chatham Is.", offset: "49500", will format for display as "[UTC + 13.75] Chatham Is."', () => { + expect( + formatTimezone({ + name: 'Chatham Is.', + offset: 49500, + identifier: 'Pacific/Chatham', + }), + ).toEqual('[UTC + 13.75] Chatham Is.'); + }); + + it('given name: "Saskatchewan", offset: "-21600", will format for display as "[UTC - 6] Saskatchewan"', () => { + expect( + formatTimezone({ + name: 'Saskatchewan', + offset: -21600, + identifier: 'America/Regina', + }), + ).toEqual('[UTC - 6] Saskatchewan'); + }); + + it('given name: "Accra", offset: "0", will format for display as "[UTC 0] Accra"', () => { + expect( + formatTimezone({ + name: 'Accra', + offset: 0, + identifier: 'Africa/Accra', + }), + ).toEqual('[UTC 0] Accra'); + }); + }); +}); diff --git a/spec/lib/gitlab/graphql/tracing_spec.rb b/spec/lib/gitlab/graphql/tracing_spec.rb deleted file mode 100644 index 6bae737d0f6..00000000000 --- a/spec/lib/gitlab/graphql/tracing_spec.rb +++ /dev/null @@ -1,35 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -describe Gitlab::Graphql::Tracing do - let!(:graphql_duration_seconds) { double('Gitlab::Metrics::NullMetric') } - - before do - allow(Gitlab::Metrics) - .to receive(:histogram) - .with(:graphql_duration_seconds, 'GraphQL execution time') - .and_return(graphql_duration_seconds) - end - - it 'updates graphql histogram with expected labels' do - query = 'query { users { id } }' - - expect_metric('graphql.lex', 'lex') - expect_metric('graphql.parse', 'parse') - expect_metric('graphql.validate', 'validate') - expect_metric('graphql.analyze', 'analyze_multiplex') - expect_metric('graphql.execute', 'execute_query_lazy') - expect_metric('graphql.execute', 'execute_multiplex') - - GitlabSchema.execute(query) - end - - private - - def expect_metric(platform_key, key) - expect(graphql_duration_seconds) - .to receive(:observe) - .with({ platform_key: platform_key, key: key }, be > 0.0) - end -end diff --git a/spec/services/quick_actions/interpret_service_spec.rb b/spec/services/quick_actions/interpret_service_spec.rb index 8b0f9c8ade2..c7e5cca324f 100644 --- a/spec/services/quick_actions/interpret_service_spec.rb +++ b/spec/services/quick_actions/interpret_service_spec.rb @@ -10,6 +10,7 @@ describe QuickActions::InterpretService do let(:milestone) { create(:milestone, project: project, title: '9.10') } let(:commit) { create(:commit, project: project) } let(:inprogress) { create(:label, project: project, title: 'In Progress') } + let(:helmchart) { create(:label, project: project, title: 'Helm Chart Registry') } let(:bug) { create(:label, project: project, title: 'Bug') } let(:note) { build(:note, commit_id: merge_request.diff_head_sha) } let(:service) { described_class.new(project, developer) } @@ -94,6 +95,26 @@ describe QuickActions::InterpretService do end end + shared_examples 'multiword label name starting without ~' do + it 'fetches label ids and populates add_label_ids if content contains /label' do + helmchart # populate the label + _, updates = service.execute(content, issuable) + + expect(updates).to eq(add_label_ids: [helmchart.id]) + end + end + + shared_examples 'label name is included in the middle of another label name' do + it 'ignores the sublabel when the content contains the includer label name' do + helmchart # populate the label + create(:label, project: project, title: 'Chart') + + _, updates = service.execute(content, issuable) + + expect(updates).to eq(add_label_ids: [helmchart.id]) + end + end + shared_examples 'unlabel command' do it 'fetches label ids and populates remove_label_ids if content contains /unlabel' do issuable.update!(label_ids: [inprogress.id]) # populate the label @@ -624,6 +645,26 @@ describe QuickActions::InterpretService do let(:issuable) { issue } end + it_behaves_like 'multiword label name starting without ~' do + let(:content) { %(/label "#{helmchart.title}") } + let(:issuable) { issue } + end + + it_behaves_like 'multiword label name starting without ~' do + let(:content) { %(/label "#{helmchart.title}") } + let(:issuable) { merge_request } + end + + it_behaves_like 'label name is included in the middle of another label name' do + let(:content) { %(/label ~"#{helmchart.title}") } + let(:issuable) { issue } + end + + it_behaves_like 'label name is included in the middle of another label name' do + let(:content) { %(/label ~"#{helmchart.title}") } + let(:issuable) { merge_request } + end + it_behaves_like 'unlabel command' do let(:content) { %(/unlabel ~"#{inprogress.title}") } let(:issuable) { issue } diff --git a/spec/support/shared_context/policies/project_policy_shared_context.rb b/spec/support/shared_context/policies/project_policy_shared_context.rb index 8bcd26ec0cd..3ad6e067674 100644 --- a/spec/support/shared_context/policies/project_policy_shared_context.rb +++ b/spec/support/shared_context/policies/project_policy_shared_context.rb @@ -15,7 +15,7 @@ RSpec.shared_context 'ProjectPolicy context' do read_project_for_iids read_issue_iid read_label read_milestone read_project_snippet read_project_member read_note create_project create_issue create_note upload_file create_merge_request_in - award_emoji read_release + award_emoji ] end @@ -24,7 +24,7 @@ RSpec.shared_context 'ProjectPolicy context' do download_code fork_project create_project_snippet update_issue admin_issue admin_label admin_list read_commit_status read_build read_container_image read_pipeline read_environment read_deployment - read_merge_request download_wiki_code read_sentry_issue + read_merge_request download_wiki_code read_sentry_issue read_release ] end diff --git a/yarn.lock b/yarn.lock index 5d40bec659d..15fa876300b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -658,10 +658,10 @@ eslint-plugin-promise "^4.0.1" eslint-plugin-vue "^5.0.0" -"@gitlab/svgs@^1.57.0": - version "1.57.0" - resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.57.0.tgz#969ac7bf16337d5de3808fee6fb5c13eefd99478" - integrity sha512-AAVvPDaxCsojmOyVVTyaOcob+bPhtYJ+GbtmmNNCHg2dXYDAEgy3+TYzAfV5fQ08TCZ9DPiKEjDIi2ODh0x/8g== +"@gitlab/svgs@^1.58.0": + version "1.58.0" + resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.58.0.tgz#bb05263ff2eb7ca09a25cd14d0b1a932d2ea9c2f" + integrity sha512-RlWSjjBT4lMIFuNC1ziCO1nws9zqZtxCjhrqK2DxDDTgp2W0At9M/BFkHp8RHyMCrO3g1fHTrLPUgzr5oR3Epg== "@gitlab/ui@^3.0.0": version "3.0.0" @@ -2804,7 +2804,7 @@ d3-dsv@1, d3-dsv@1.0.8: iconv-lite "0.4" rw "1" -d3-ease@1, d3-ease@1.0.3: +d3-ease@1, d3-ease@1.0.3, d3-ease@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-1.0.3.tgz#68bfbc349338a380c44d8acc4fbc3304aa2d8c0e" integrity sha1-aL+8NJM4o4DETYrMT7wzBKotjA4= @@ -2920,7 +2920,7 @@ d3-timer@1, d3-timer@1.0.7: resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-1.0.7.tgz#df9650ca587f6c96607ff4e60cc38229e8dd8531" integrity sha512-vMZXR88XujmG/L5oB96NNKH5lCWwiLM/S2HyyAQLcjWJCloK5shxta4CwOFYLZoY3AWX73v8Lgv4cCAdWtRmOA== -d3-transition@1, d3-transition@1.1.1: +d3-transition@1, d3-transition@1.1.1, d3-transition@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/d3-transition/-/d3-transition-1.1.1.tgz#d8ef89c3b848735b060e54a39b32aaebaa421039" integrity sha512-xeg8oggyQ+y5eb4J13iDgKIjUcEfIOZs2BqV/eEmXm2twx80wTzJ4tB4vaZ5BKfz7XsI/DFmQL5me6O27/5ykQ== |