diff options
32 files changed, 413 insertions, 147 deletions
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION index 6f875b6cfb8..2927a9c0482 100644 --- a/GITALY_SERVER_VERSION +++ b/GITALY_SERVER_VERSION @@ -1 +1 @@ -4a144bdd080a7eeca4399d43add443fd7326b227 +82da6c9eb6897bf3bbb7a791ba13a184f5679d24 diff --git a/app/assets/javascripts/vue_merge_request_widget/components/widget/widget.vue b/app/assets/javascripts/vue_merge_request_widget/components/widget/widget.vue index 40873245beb..c6a8c07da52 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/widget/widget.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/widget/widget.vue @@ -219,6 +219,8 @@ export default { this.fetchExpandedContent(); } } + + this.$emit('toggle', { expanded: !this.isCollapsed }); }, async fetchExpandedContent() { this.isLoadingExpandedContent = true; diff --git a/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/base_token.vue b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/base_token.vue index b0fa3e4c27e..b5783265ffa 100644 --- a/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/base_token.vue +++ b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/base_token.vue @@ -9,7 +9,7 @@ import { } from '@gitlab/ui'; import { debounce } from 'lodash'; -import { DEBOUNCE_DELAY, FILTERS_NONE_ANY, OPERATOR_NOT } from '../constants'; +import { DEBOUNCE_DELAY, FILTERS_NONE_ANY, OPERATOR_NOT, OPERATOR_OR } from '../constants'; import { getRecentlyUsedSuggestions, setTokenValueToRecentlyUsed, @@ -100,7 +100,7 @@ export default { return this.getActiveTokenValue(this.suggestions, this.value.data); }, availableDefaultSuggestions() { - if (this.value.operator === OPERATOR_NOT) { + if ([OPERATOR_NOT, OPERATOR_OR].includes(this.value.operator)) { return this.defaultSuggestions.filter( (suggestion) => !FILTERS_NONE_ANY.includes(suggestion.value), ); diff --git a/app/assets/javascripts/vue_shared/issuable/list/components/issuable_item.vue b/app/assets/javascripts/vue_shared/issuable/list/components/issuable_item.vue index cc8c834fff4..2200bb08863 100644 --- a/app/assets/javascripts/vue_shared/issuable/list/components/issuable_item.vue +++ b/app/assets/javascripts/vue_shared/issuable/list/components/issuable_item.vue @@ -286,7 +286,6 @@ export default { </span> <slot name="timeframe"></slot> </span> - <p v-if="labels.length" role="group" :aria-label="__('Labels')" class="gl-mt-1 gl-mb-0"> <gl-label v-for="(label, index) in labels" @@ -296,7 +295,7 @@ export default { :description="label.description" :scoped="scopedLabel(label)" :target="labelTarget(label)" - :class="{ 'gl-ml-2': index }" + class="gl-mr-2" size="sm" /> </p> diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb index daed4023d02..b9964e8ca01 100644 --- a/app/controllers/omniauth_callbacks_controller.rb +++ b/app/controllers/omniauth_callbacks_controller.rb @@ -183,7 +183,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController persist_accepted_terms_if_required(user) if new_user store_after_sign_up_path_for_user if intent_to_register? - sign_in_and_redirect_or_confirm_identity(user, auth_user, new_user) + sign_in_and_redirect_or_verify_identity(user, auth_user, new_user) end else fail_login(user) @@ -315,7 +315,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController end # overridden in EE - def sign_in_and_redirect_or_confirm_identity(user, _, _) + def sign_in_and_redirect_or_verify_identity(user, _, _) sign_in_and_redirect(user, event: :authentication) end end diff --git a/app/models/project.rb b/app/models/project.rb index d0c89edf407..2462777400a 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -2423,6 +2423,7 @@ class Project < ApplicationRecord def api_variables Gitlab::Ci::Variables::Collection.new.tap do |variables| variables.append(key: 'CI_API_V4_URL', value: API::Helpers::Version.new('v4').root_url) + variables.append(key: 'CI_API_GRAPHQL_URL', value: Gitlab::Routing.url_helpers.api_graphql_url) end end diff --git a/app/views/projects/merge_requests/_merge_request.html.haml b/app/views/projects/merge_requests/_merge_request.html.haml index 7b449134567..85396134db2 100644 --- a/app/views/projects/merge_requests/_merge_request.html.haml +++ b/app/views/projects/merge_requests/_merge_request.html.haml @@ -39,9 +39,9 @@ = sprite_icon('branch', size: 12, css_class: 'fork-sprite') = merge_request.target_branch - if merge_request.labels.any? - - - presented_labels_sorted_by_title(merge_request.labels, merge_request.project).each do |label| - = link_to_label(label, type: :merge_request, small: true) + .gl-mt-1{ role: 'group', 'aria-label': _('Labels') } + - presented_labels_sorted_by_title(merge_request.labels, merge_request.project).each do |label| + = link_to_label(label, type: :merge_request, small: true) .issuable-meta %ul.controls.d-flex.align-items-end @@ -66,6 +66,6 @@ = render 'shared/issuable_meta_data', issuable: merge_request - .float-right.issuable-updated-at.d-none.d-sm-inline-block + .float-right.issuable-updated-at.d-none.d-sm-inline-block.gl-text-gray-500 %span = _('updated %{time_ago}').html_safe % { time_ago: time_ago_with_tooltip(merge_request.updated_at, placement: 'bottom', html_class: 'merge_request_updated_ago') } diff --git a/db/migrate/20230328020316_delete_unused_index_on_merge_requests_on_state_id_and_merge_status.rb b/db/migrate/20230328020316_delete_unused_index_on_merge_requests_on_state_id_and_merge_status.rb new file mode 100644 index 00000000000..eac1d4e30c1 --- /dev/null +++ b/db/migrate/20230328020316_delete_unused_index_on_merge_requests_on_state_id_and_merge_status.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +class DeleteUnusedIndexOnMergeRequestsOnStateIdAndMergeStatus < Gitlab::Database::Migration[2.1] + # TODO: Index to be destroyed synchronously in https://gitlab.com/gitlab-org/gitlab/-/issues/402491 + + def up + prepare_async_index_removal :merge_requests, [:state_id, :merge_status], + where: "((state_id = 1) AND ((merge_status)::text = 'can_be_merged'::text))", + name: 'idx_merge_requests_on_state_id_and_merge_status' + end + + def down + unprepare_async_index :merge_requests, [:state_id, :merge_status], + where: "((state_id = 1) AND ((merge_status)::text = 'can_be_merged'::text))", + name: 'idx_merge_requests_on_state_id_and_merge_status' + end +end diff --git a/db/schema_migrations/20230328020316 b/db/schema_migrations/20230328020316 new file mode 100644 index 00000000000..01eda556b86 --- /dev/null +++ b/db/schema_migrations/20230328020316 @@ -0,0 +1 @@ +8b5c31f035ede013e589d310fb477a9776b3e3f9554170638bb3b7a299721545
\ No newline at end of file diff --git a/doc/api/environments.md b/doc/api/environments.md index 64b64dfbfab..745abdd7ab3 100644 --- a/doc/api/environments.md +++ b/doc/api/environments.md @@ -339,7 +339,7 @@ curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://git > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/296625) in GitLab 14.2. It schedules for deletion multiple environments that have already been -[stopped](../ci/environments/index.md#stop-an-environment) and +[stopped](../ci/environments/index.md#stopping-an-environment) and are [in the review app folder](../ci/review_apps/index.md). The actual deletion is performed after 1 week from the time of execution. By default, it only deletes environments 30 days or older. You can change this default using the `before` parameter. @@ -415,7 +415,7 @@ Example response: ## Stop stale environments -Issue stop request to all environments that were last modified or deployed to before a specified date. Excludes protected environments. Returns `200` if stop request was successful and `400` if the before date is invalid. For details of exactly when the environment is stopped, see [Stop an environment](../ci/environments/index.md#stop-an-environment). +Issue stop request to all environments that were last modified or deployed to before a specified date. Excludes protected environments. Returns `200` if stop request was successful and `400` if the before date is invalid. For details of exactly when the environment is stopped, see [Stop an environment](../ci/environments/index.md#stopping-an-environment). ```plaintext POST /projects/:id/environments/stop_stale diff --git a/doc/ci/environments/img/environment_auto_stop_v13_10.png b/doc/ci/environments/img/environment_auto_stop_v13_10.png Binary files differdeleted file mode 100644 index 50f268da27f..00000000000 --- a/doc/ci/environments/img/environment_auto_stop_v13_10.png +++ /dev/null diff --git a/doc/ci/environments/index.md b/doc/ci/environments/index.md index fe0d71d5f1e..577cbce2943 100644 --- a/doc/ci/environments/index.md +++ b/doc/ci/environments/index.md @@ -167,7 +167,7 @@ You cannot rename an environment by using the UI, and the API method was depreca To achieve the same result as renaming an environment: -1. [Stop the existing environment](#stop-an-environment-through-the-ui). +1. [Stop the existing environment](#stop-an-environment-by-using-the-ui). 1. [Delete the existing environment](#delete-an-environment). 1. [Create a new environment](#create-a-static-environment) with the desired name. @@ -452,28 +452,31 @@ For example: With GitLab [Route Maps](../review_apps/index.md#route-maps), you can go directly from source files to public pages in the environment set for Review Apps. -### Stop an environment +### Stopping an environment -When you stop an environment: +Stopping an environment means its deployments are not accessible on the target server. You must stop +an environment before it can be deleted. -- On the **Environments** page, it moves from the list of **Available** environments - to the list of **Stopped** environments. -- An [`on_stop` action](../yaml/index.md#environmenton_stop), if defined, is executed. - -There are multiple ways to clean up [dynamic environments](#create-a-dynamic-environment): - -- If you use [merge request pipelines](../pipelines/merge_request_pipelines.md), GitLab stops an environment [when a merge request is merged or closed](#stop-an-environment-when-a-merge-request-is-merged-or-closed). -- If you do _NOT_ use [merge request pipelines](../pipelines/merge_request_pipelines.md), GitLab stops an environment [when the associated feature branch is deleted](#stop-an-environment-when-a-branch-is-deleted). -- If you set [an expiry period to an environment](../yaml/index.md#environmentauto_stop_in), GitLab stops an environment [when it's expired](#stop-an-environment-after-a-certain-time-period). - -To stop stale environments, you can [use the API](../../api/environments.md#stop-stale-environments). +If the environment has an [`on_stop` action](../yaml/index.md#environmenton_stop) defined, it's +executed to stop the environment. #### Stop an environment when a branch is deleted You can configure environments to stop when a branch is deleted. -The following example shows a `deploy_review` job that calls a `stop_review` job -to clean up and stop the environment. +In the following example, a `deploy_review` job calls a `stop_review` job to clean up and stop the +environment. + +- Both jobs must have the same [`rules`](../yaml/index.md#rules) + or [`only/except`](../yaml/index.md#only--except) configuration. Otherwise, + the `stop_review` job might not be included in all pipelines that include the + `deploy_review` job, and you cannot trigger `action: stop` to stop the environment automatically. +- The job with [`action: stop` might not run](#the-job-with-action-stop-doesnt-run) + if it's in a later stage than the job that started the environment. +- If you can't use [merge request pipelines](../pipelines/merge_request_pipelines.md), + set the [`GIT_STRATEGY`](../runners/configure_runners.md#git-strategy) to `none` in the + `stop_review` job. Then the [runner](https://docs.gitlab.com/runner/) doesn't + try to check out the code after the branch is deleted. ```yaml deploy_review: @@ -495,30 +498,13 @@ stop_review: when: manual ``` -Both jobs must have the same [`rules`](../yaml/index.md#rules) -or [`only/except`](../yaml/index.md#only--except) configuration. Otherwise, -the `stop_review` job might not be included in all pipelines that include the -`deploy_review` job, and you cannot trigger `action: stop` to stop the environment automatically. - -The job with [`action: stop` might not run](#the-job-with-action-stop-doesnt-run) -if it's in a later stage than the job that started the environment. - -If you can't use [merge request pipelines](../pipelines/merge_request_pipelines.md), -set the [`GIT_STRATEGY`](../runners/configure_runners.md#git-strategy) to `none` in the -`stop_review` job. Then the [runner](https://docs.gitlab.com/runner/) doesn't -try to check out the code after the branch is deleted. - -Read more in the [`.gitlab-ci.yml` reference](../yaml/index.md#environmenton_stop). - #### Stop an environment when a merge request is merged or closed -> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/60885) in GitLab 11.10. - -You can configure environments to stop when a merge request is merged or closed. -This stop trigger is automatically enabled when you use [merge request pipelines](../pipelines/merge_request_pipelines.md). +When you use the [merge request pipelines](../pipelines/merge_request_pipelines.md) configuration, +the `stop` trigger is automatically enabled. -The following example shows a `deploy_review` job that calls a `stop_review` job -to clean up and stop the environment. +In the following example, the `deploy_review` job calls a `stop_review` job to clean up and stop +the environment. ```yaml deploy_review: @@ -543,38 +529,35 @@ stop_review: when: manual ``` -#### Stop an environment when another job is finished - -You can set an environment to stop when another job is finished. - -In your `.gitlab-ci.yml` file, specify in the [`on_stop`](../yaml/index.md#environmenton_stop) -keyword the name of the job that stops the environment. +#### Run a pipeline job when environment is stopped -The following example shows a `review_app` job that calls a `stop_review_app` job after the first -job is finished. The `stop_review_app` is triggered based on what is defined under `when`. In this -case, it is set to `manual`, so it needs a -[manual action](../jobs/job_control.md#create-a-job-that-must-be-run-manually) -from the GitLab UI to run. +You can specify a job to run when an environment is stopped. -Both jobs must have the same rules or only/except configuration. -In this example, if the configuration is not identical: +Prerequisites: -- The `stop_review_app` job might not be included in all pipelines that include the `review_app` job. -- It is not possible to trigger the `action: stop` to stop the environment automatically. +- Both jobs must have the same rules or only/except configuration. +- The `stop_review_app` job **must** have the following keywords defined: + - `when`, defined at either: + - [The job level](../yaml/index.md#when). + - [In a rules clause](../yaml/index.md#rules). If you use `rules` and `when: manual`, you should + also set [`allow_failure: true`](../yaml/index.md#allow_failure) so the pipeline can complete + even if the job doesn't run. + - `environment:name` + - `environment:action` -Also in the example, `GIT_STRATEGY` is set to `none`. If the -`stop_review_app` job is [automatically triggered](../environments/index.md#stop-an-environment), -the runner doesn't try to check out the code after the branch is deleted. +In your `.gitlab-ci.yml` file, specify in the [`on_stop`](../yaml/index.md#environmenton_stop) +keyword the name of the job that stops the environment. -The `stop_review_app` job **must** have the following keywords defined: +In the following example: -- `when`, defined at either: - - [The job level](../yaml/index.md#when). - - [In a rules clause](../yaml/index.md#rules). If you use `rules` and `when: manual`, you should - also set [`allow_failure: true`](../yaml/index.md#allow_failure) so the pipeline can complete - even if the job doesn't run. -- `environment:name` -- `environment:action` +- A `review_app` job calls a `stop_review_app` job after the first job is finished. +- The `stop_review_app` is triggered based on what is defined under `when`. In this + case, it is set to `manual`, so it needs a + [manual action](../jobs/job_control.md#create-a-job-that-must-be-run-manually) + from the GitLab UI to run. +- The `GIT_STRATEGY` is set to `none`. If the `stop_review_app` job is + [automatically triggered](../environments/index.md#stopping-an-environment), + the runner doesn't try to check out the code after the branch is deleted. ```yaml review_app: @@ -598,21 +581,23 @@ stop_review_app: #### Stop an environment after a certain time period -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/20956) in GitLab 12.8. +You can set an environment to stop automatically after a certain time period. -You can set environments to stop automatically after a certain time period. +NOTE: +Due to resource limitations, a background worker for stopping environments runs only once every +hour. This means that environments may not be stopped after the exact time period specified, but are +instead stopped when the background worker detects expired environments. In your `.gitlab-ci.yml` file, specify the [`environment:auto_stop_in`](../yaml/index.md#environmentauto_stop_in) -keyword. You can specify a human-friendly date as the value, such as `1 hour and 30 minutes` or `1 day`. +keyword. Specify the time period in natural language, such as `1 hour and 30 minutes` or `1 day`. After the time period passes, GitLab automatically triggers a job to stop the environment. -Due to resource limitations, a background worker for stopping environments only runs once -every hour. This means that environments aren't stopped at the exact timestamp specified, but are -instead stopped when the hourly cron worker detects expired environments. +In the following example: -In the following example, each merge request creates a Review App environment. -Each push triggers the `review_app` job and an environment named `review/your-branch-name` -is created or updated. The environment runs until `stop_review_app` is executed: +- Each commit on a merge request triggers a `review_app` job that deploys the latest change to the + environment and resets its expiry period. +- If the environment is inactive for more than a week, GitLab automatically triggers the + `stop_review_app` job to stop the environment. ```yaml review_app: @@ -634,13 +619,33 @@ stop_review_app: when: manual ``` -As long as the merge request is active and keeps getting new commits, -the Review App doesn't stop. Developers don't need to worry about -re-initiating Review App. +##### View an environment's scheduled stop date and time + +When a environment has been [scheduled to stop after a specified time period](#stop-an-environment-after-a-certain-time-period), +you can view its expiration date and time. + +To view an environment's expiration date and time: + +1. On the top bar, select **Main menu > Projects** and find your project. +1. On the left sidebar, select **Deployments > Environments**. +1. Select the name of the environment. + +The expiration date and time is displayed in the upper-left corner, next to the environment's name. + +##### Override a environment's scheduled stop date and time + +When a environment has been [scheduled to stop after a specified time period](#stop-an-environment-after-a-certain-time-period), +you can override its expiration. -Because `stop_review_app` is set to `auto_stop_in: 1 week`, -if a merge request is inactive for more than a week, -GitLab automatically triggers the `stop_review_app` job to stop the environment. +To override an environment's expiration: + +1. On the top bar, select **Main menu > Projects** and find your project. +1. On the left sidebar, select **Deployments > Environments**. +1. Select the deployment name. +1. in the upper-right corner, select the thumbtack (**{thumbtack}**). + +The `auto_stop_in` setting is overridden and the environment remains active until it's stopped +manually. #### Stop an environment without running the `on_stop` action @@ -652,7 +657,7 @@ To stop an environment without running the defined `on_stop` action, execute the [Stop an environment API](../../api/environments.md#stop-an-environment) with the parameter `force=true`. -#### Stop an environment through the UI +#### Stop an environment by using the UI NOTE: To trigger an `on_stop` action and manually stop an environment from the @@ -671,15 +676,20 @@ To stop an environment in the GitLab UI: > - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/22456) in GitLab 14.10 [with a flag](../../administration/feature_flags.md) named `environment_multiple_stop_actions`. Disabled by default. > - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/358911) in GitLab 15.0. [Feature flag `environment_multiple_stop_actions`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/86685) removed. -This feature is useful when you need to perform multiple **parallel** stop actions on an environment. +To configure multiple **parallel** stop actions on an environment, specify the +[`on_stop`](../yaml/index.md#environmenton_stop) keyword across multiple +[deployment jobs](../jobs/index.md#deployment-jobs) for the same `environment`, as defined in the +`.gitlab-ci.yml` file. + +When an environment is stopped, the matching `on_stop` actions from only successful deployment jobs are run in parallel, in no particular order. -To configure multiple stop actions on an environment, specify the [`on_stop`](../yaml/index.md#environmenton_stop) -keyword across multiple [deployment jobs](../jobs/index.md#deployment-jobs) for the same `environment`, as defined in the `.gitlab-ci.yml` file. +In the following example, for the `test` environment there are two deployment jobs: -When an environment is stopped, the matching `on_stop` actions from *successful deployment jobs* alone are run in parallel in no particular order. +- `deploy-to-cloud-a` +- `deploy-to-cloud-b` -In the following example, for the `test` environment there are two deployment jobs `deploy-to-cloud-a` -and `deploy-to-cloud-b`. +When the environment is stopped, the system runs `on_stop` actions `teardown-cloud-a` and +`teardown-cloud-b` in parallel. ```yaml deploy-to-cloud-a: @@ -709,32 +719,6 @@ teardown-cloud-b: when: manual ``` -When the environment is stopped, the system runs `on_stop` actions -`teardown-cloud-a` and `teardown-cloud-b` in parallel. - -#### View a deployment's scheduled stop time - -You can view a deployment's expiration date in the GitLab UI. - -1. On the top bar, select **Main menu > Projects** and find your project. -1. On the left sidebar, select **Deployments > Environments**. -1. Select the name of the deployment. - -In the upper-left corner, next to the environment name, the expiration date is displayed. - -#### Override a deployment's scheduled stop time - -You can manually override a deployment's expiration date. - -1. On the top bar, select **Main menu > Projects** and find your project. -1. On the left sidebar, select **Deployments > Environments**. -1. Select the deployment name. -1. in the upper-right corner, select the thumbtack (**{thumbtack}**). - -![Environment auto stop](img/environment_auto_stop_v13_10.png) - -The `auto_stop_in` setting is overwritten and the environment remains active until it's stopped manually. - ### Delete an environment Delete an environment when you want to remove it and all its deployments. @@ -742,7 +726,7 @@ Delete an environment when you want to remove it and all its deployments. Prerequisites: - You must have at least the Developer role. -- You must [stop](#stop-an-environment) the environment before it can be deleted. +- You must [stop](#stopping-an-environment) the environment before it can be deleted. To delete an environment: diff --git a/doc/ci/environments/protected_environments.md b/doc/ci/environments/protected_environments.md index 420569ec08b..faeaca1038e 100644 --- a/doc/ci/environments/protected_environments.md +++ b/doc/ci/environments/protected_environments.md @@ -124,7 +124,7 @@ access to a protected environment through any of these methods: If the user also has push or merge access to the branch deployed on production, they have the following privileges: -- [Stop an environment](index.md#stop-an-environment). +- [Stop an environment](index.md#stopping-an-environment). - [Delete an environment](index.md#delete-an-environment). - [Create an environment terminal](index.md#web-terminals-deprecated). diff --git a/doc/ci/pipelines/index.md b/doc/ci/pipelines/index.md index a912c7f4557..b9c8e9e1e09 100644 --- a/doc/ci/pipelines/index.md +++ b/doc/ci/pipelines/index.md @@ -93,7 +93,7 @@ This table lists the refspecs injected for each pipeline type: The refs `refs/heads/<name>` and `refs/tags/<name>` exist in your project repository. GitLab generates the special ref `refs/pipelines/<id>` during a running pipeline job. This ref can be created even after the associated branch or tag has been -deleted. It's therefore useful in some features such as [automatically stopping an environment](../environments/index.md#stop-an-environment), +deleted. It's therefore useful in some features such as [automatically stopping an environment](../environments/index.md#stopping-an-environment), and [merge trains](../pipelines/merge_trains.md) that might run pipelines after branch deletion. diff --git a/doc/ci/review_apps/index.md b/doc/ci/review_apps/index.md index 9e69ab1ccb8..fb0bf7b2ae1 100644 --- a/doc/ci/review_apps/index.md +++ b/doc/ci/review_apps/index.md @@ -59,7 +59,7 @@ The process of configuring review apps is as follows: 1. Set up a job in `.gitlab-ci.yml` that uses the [predefined CI/CD variable](../variables/index.md) `${CI_COMMIT_REF_SLUG}` to create dynamic environments and restrict it to run only on branches. Alternatively, you can get a YAML template for this job by [enabling review apps](#enable-review-app-button) for your project. -1. Optionally, set a job that [manually stops](../environments/index.md#stop-an-environment) the review apps. +1. Optionally, set a job that [manually stops](../environments/index.md#stopping-an-environment) the review apps. ### Enable review app button diff --git a/doc/ci/variables/predefined_variables.md b/doc/ci/variables/predefined_variables.md index 45dc1a7fe37..b7b7bed4d2d 100644 --- a/doc/ci/variables/predefined_variables.md +++ b/doc/ci/variables/predefined_variables.md @@ -27,6 +27,7 @@ as it can cause the pipeline to behave unexpectedly. | `CHAT_USER_ID` | 14.4 | all | The chat service's user ID of the user who triggered the [ChatOps](../chatops/index.md) command. | | `CI` | all | 0.4 | Available for all jobs executed in CI/CD. `true` when available. | | `CI_API_V4_URL` | 11.7 | all | The GitLab API v4 root URL. | +| `CI_API_GRAPHQL_URL` | 15.11 | all | The GitLab API GraphQL root URL. | | `CI_BUILDS_DIR` | all | 11.10 | The top-level directory where builds are executed. | | `CI_COMMIT_AUTHOR` | 13.11 | all | The author of the commit in `Name <email>` format. | | `CI_COMMIT_BEFORE_SHA` | 11.2 | all | The previous latest commit present on a branch or tag. Is always `0000000000000000000000000000000000000000` in merge request pipelines and for the first commit in pipelines for branches or tags. | diff --git a/doc/ci/yaml/index.md b/doc/ci/yaml/index.md index 0bbd3bf37b4..01173f43c2e 100644 --- a/doc/ci/yaml/index.md +++ b/doc/ci/yaml/index.md @@ -1734,7 +1734,7 @@ Use the `action` keyword to specify how the job interacts with the environment. |:----------|:----------------| | `start` | Default value. Indicates that the job starts the environment. The deployment is created after the job starts. | | `prepare` | Indicates that the job is only preparing the environment. It does not trigger deployments. [Read more about preparing environments](../environments/index.md#access-an-environment-for-preparation-or-verification-purposes). | -| `stop` | Indicates that the job stops an environment. [Read more about stopping an environment](../environments/index.md#stop-an-environment). | +| `stop` | Indicates that the job stops an environment. [Read more about stopping an environment](../environments/index.md#stopping-an-environment). | | `verify` | Indicates that the job is only verifying the environment. It does not trigger deployments. [Read more about verifying environments](../environments/index.md#access-an-environment-for-preparation-or-verification-purposes). | | `access` | Indicates that the job is only accessing the environment. It does not trigger deployments. [Read more about accessing environments](../environments/index.md#access-an-environment-for-preparation-or-verification-purposes). | diff --git a/doc/development/documentation/styleguide/index.md b/doc/development/documentation/styleguide/index.md index baa46f7bfc2..e66d095a7a4 100644 --- a/doc/development/documentation/styleguide/index.md +++ b/doc/development/documentation/styleguide/index.md @@ -718,6 +718,15 @@ This is overridden by the [documentation-specific punctuation rules](#punctuatio Links help the docs adhere to the [single source of truth](#documentation-is-the-single-source-of-truth-ssot) principle. +However, you should avoid putting too many links on any page. Too many links can hinder readability. + +- Do not duplicate links on the same page. For example, on **Page A**, do not link to **Page B** multiple times. +- Avoid multiple links in a single paragraph. +- Avoid multiple links in a single task. +- On any one page, try not to use more than 15 links to other pages. +- Consider using [Related topics](../topic_types/index.md#related-topics) to reduce links that interrupt the flow of a task. +- Try to avoid anchor links to sections on the same page. Let users rely on the right navigation instead. + ### Links within the same repository To link to another page in the same repository, diff --git a/doc/development/testing_guide/review_apps.md b/doc/development/testing_guide/review_apps.md index 4e968cea3a0..1e5ee9f3003 100644 --- a/doc/development/testing_guide/review_apps.md +++ b/doc/development/testing_guide/review_apps.md @@ -227,7 +227,7 @@ Review apps are automatically stopped 2 days after the last deployment thanks to the [Environment auto-stop](../../ci/environments/index.md#stop-an-environment-after-a-certain-time-period) feature. If you need your review app to stay up for a longer time, you can -[pin its environment](../../ci/environments/index.md#override-a-deployments-scheduled-stop-time) or retry the +[pin its environment](../../ci/environments/index.md#override-a-environments-scheduled-stop-date-and-time) or retry the `review-deploy` job to update the "latest deployed at" time. The `review-cleanup` job that automatically runs in scheduled diff --git a/doc/topics/autodevops/cloud_deployments/auto_devops_with_eks.md b/doc/topics/autodevops/cloud_deployments/auto_devops_with_eks.md index f322ebd0c9c..32a47bb790b 100644 --- a/doc/topics/autodevops/cloud_deployments/auto_devops_with_eks.md +++ b/doc/topics/autodevops/cloud_deployments/auto_devops_with_eks.md @@ -217,7 +217,7 @@ you to common environment tasks: - **Re-deploy to environment** (**{repeat}**) - For more information, see [Retrying and rolling back](../../../ci/environments/index.md#retry-or-roll-back-a-deployment) - **Stop environment** (**{stop}**) - For more information, see - [Stopping an environment](../../../ci/environments/index.md#stop-an-environment) + [Stopping an environment](../../../ci/environments/index.md#stopping-an-environment) GitLab displays the [deploy board](../../../user/project/deploy_boards.md) below the environment's information, with squares representing pods in your diff --git a/doc/topics/autodevops/cloud_deployments/auto_devops_with_gke.md b/doc/topics/autodevops/cloud_deployments/auto_devops_with_gke.md index 7f608d3951c..1a03a66d17a 100644 --- a/doc/topics/autodevops/cloud_deployments/auto_devops_with_gke.md +++ b/doc/topics/autodevops/cloud_deployments/auto_devops_with_gke.md @@ -221,7 +221,7 @@ you to common environment tasks: - **Re-deploy to environment** (**{repeat}**) - For more information, see [Retrying and rolling back](../../../ci/environments/index.md#retry-or-roll-back-a-deployment) - **Stop environment** (**{stop}**) - For more information, see - [Stopping an environment](../../../ci/environments/index.md#stop-an-environment) + [Stopping an environment](../../../ci/environments/index.md#stopping-an-environment) GitLab displays the [deploy board](../../../user/project/deploy_boards.md) below the environment's information, with squares representing pods in your diff --git a/doc/user/application_security/secret_detection/post_processing.md b/doc/user/application_security/secret_detection/post_processing.md index 539d9e6fd88..6d29a488ca2 100644 --- a/doc/user/application_security/secret_detection/post_processing.md +++ b/doc/user/application_security/secret_detection/post_processing.md @@ -32,10 +32,11 @@ GitLab supports post-processing for the following vendors and secrets: ## Feature availability +> [Enabled for non-default branches](https://gitlab.com/gitlab-org/gitlab/-/issues/299212) in GitLab 15.11. + Credentials are only post-processed when Secret Detection finds them: - In public projects, because publicly exposed credentials pose an increased threat. Expansion to private projects is considered in [issue 391379](https://gitlab.com/gitlab-org/gitlab/-/issues/391379). -- On the project [default branch](../../project/repository/branches/default.md), for technical reasons. Expansion to all branches is tracked in [issue 299212](https://gitlab.com/gitlab-org/gitlab/-/issues/299212). - In projects with GitLab Ultimate, for technical reasons. Expansion to all tiers is tracked in [issue 391763](https://gitlab.com/gitlab-org/gitlab/-/issues/391763). ## High-level architecture @@ -45,8 +46,9 @@ This diagram describes how a post-processing hook revokes a secret within the Gi ```mermaid sequenceDiagram autonumber - GitLab Rails->>+Sidekiq: gl-secret-detection-report.json - Sidekiq-->+Sidekiq: StoreSecurityReportsWorker + GitLab Rails-->+GitLab Rails: gl-secret-detection-report.json + GitLab Rails->>+Sidekiq: StoreScansService + Sidekiq-->+Sidekiq: ScanSecurityReportSecretsWorker Sidekiq-->+Token Revocation API: GET revocable keys types Token Revocation API-->>-Sidekiq: OK Sidekiq->>+Token Revocation API: POST revoke revocable keys @@ -55,14 +57,13 @@ sequenceDiagram Receiver Service-->>+Token Revocation API: ACCEPTED ``` -1. A pipeline with a Secret Detection job completes on the project's default branch, producing a scan - report (**1**). -1. The report is processed (**2**) by an asynchronous worker, which communicates with an externally - deployed HTTP service (**3** and **4**) to determine which kinds of secrets can be automatically - revoked. -1. The worker sends (**5** and **6**) the list of detected secrets which the Token Revocation API is able to +1. A pipeline with a Secret Detection job completes, producing a scan report (**1**). +1. The report is processed (**2**) by a service class, which schedules an asychronous worker if token revocation is possible. +1. The asynchronous worker (**3**) communicates with an externally deployed HTTP service + (**4** and **5**) to determine which kinds of secrets can be automatically revoked. +1. The worker sends (**6** and **7**) the list of detected secrets which the Token Revocation API is able to revoke. -1. The Token Revocation API sends (**7** and **8**) each revocable token to their respective vendor's [receiver service](#integrate-your-cloud-provider-service-with-gitlabcom). +1. The Token Revocation API sends (**8** and **9**) each revocable token to their respective vendor's [receiver service](#integrate-your-cloud-provider-service-with-gitlabcom). See the [Token Revocation API](../../../development/sec/token_revocation_api.md) documentation for more information. diff --git a/doc/user/profile/account/create_accounts.md b/doc/user/profile/account/create_accounts.md index 08d23902095..f405dc42f46 100644 --- a/doc/user/profile/account/create_accounts.md +++ b/doc/user/profile/account/create_accounts.md @@ -36,9 +36,27 @@ To create a user manually: 1. On the top bar, select **Main menu > Admin**. 1. On the left sidebar, select **Overview > Users** (`/admin/users`). 1. Select **New user**. -1. Complete the fields. +1. Complete the required fields, such as name, username, and email. 1. Select **Create user**. +A reset link is sent to the user's email and they are forced to set their +password on first sign in. + +To set a user's password without relying on the email confirmation, after you +create a user following the previous steps: + +1. Select the user. +1. Select **Edit**. +1. Complete the password and password confirmation fields. +1. Select **Save changes**. + +The user can now sign in with the new username and password, and they are asked +to change the password you set up for them. + +NOTE: +If you wanted to create a test user, you could follow the previous steps +by providing a fake email and using the same password in the final confirmation. + ## Create users through authentication integrations Users are: diff --git a/doc/user/profile/achievements.md b/doc/user/profile/achievements.md new file mode 100644 index 00000000000..96940eec766 --- /dev/null +++ b/doc/user/profile/achievements.md @@ -0,0 +1,195 @@ +--- +stage: Data Stores +group: Tenant Scale +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments +--- + +# Achievements (Alpha) **(FREE)** + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/113156) in GitLab 15.10 [with a flag](../../administration/feature_flags.md) named `achievements`. Disabled by default. + +FLAG: +On self-managed GitLab, by default this feature is not available. To make it available, +ask an administrator to [enable the feature flag](../../administration/feature_flags.md) named `achievements`. +The feature is not ready for production use. + +Achievements are a way to reward users for their activity on GitLab. +As a namespace maintainer or owner, you can create custom achievements for specific contributions, which you can award to or revoke from users based on your criteria. + +As a user, you can collect achievements to highlight your contributions to different projects or groups on your profile. +An achievement consists of a name, a description, and an avatar. + +![Achievements on user profile page](img/user_profile_achievements_v15_11.png) + +This feature is in Alpha. +For more information about planned work, see [epic 9429](https://gitlab.com/groups/gitlab-org/-/epics/9429). +Tell us about your use cases by leaving comments in the epic. + +## Types of achievement + +Programmatically, there is only one way to create, award, revoke, or delete achievements. + +Practically, you can differentiate between achievements that are awarded: + +- Once and irrevocable. For example, a "First contribution merged" achievement. +- Once and revocable. For example, a "Core team member" achievement. +- Multiple times. For example, a "Contributor of the month" achievement. + +## View a user's achievements + +You can view a user's achievements on their profile page. + +Prerequisites: + +- The user profile must be public. +- You must be a member of the namespace awarding the achievement, or the namespace must be public. + +To view a user's achievements: + +1. Go to the user's profile page. +1. Below the user's avatar, see their achievements. +1. To view details about an achievement, hover over it. + It displays the following information: + + - Name of the achievement + - Description of the achievement + - Date when the achievement was awarded to the user + - Namespace that awarded the achievement + +To retrieve a list of a user's achievements, query the [`user` GraphQL type](../../api/graphql/reference/index.md#user). + +```graphql +query { + user(username: "<username>") { + userAchievements { + nodes { + achievement { + name + description + avatarUrl + namespace { + fullPath + name + } + } + } + } + } +} +``` + +## Create an achievement + +You can create custom achievements to award for specific contributions. + +Prerequisites: + +- You must have the Maintainer or Owner role for the namespace. + +To create an achievement, call the [`achievementsCreate` GraphQL mutation](../../api/graphql/reference/index.md#mutationachievementscreate). + +```graphql +mutation achievementsCreate($file: Upload!) { + achievementsCreate( + input: { + namespaceId: "gid://gitlab/Namespace/<namespace id>", + name: "<name>", + description: "<description>", + avatar: $file} + ) { + errors + achievement { + id + name + description + avatarUrl + } + } +} +``` + +## Award an achievement + +You can award an achievement to a user to recognize their contributions. + +Prerequisites: + +- You must have the Maintainer or Owner role for the namespace. + +To award an achievement to a user, call the [`achievementsAward` GraphQL mutation](../../api/graphql/reference/index.md#mutationachievementsaward). + +```graphql +mutation { + achievementsAward(input: { + achievementId: "gid://gitlab/Achievements::Achievement/<achievement id>", + userId: "gid://gitlab/User/<user id>" }) { + userAchievement { + id + achievement { + id + name + } + user { + id + username + } + } + errors + } +} +``` + +## Revoke an achievement + +You can revoke a user's achievement if you consider the user no longer meets the awarding criteria. + +Prerequisites: + +- You must have the Maintainer or Owner role for the namespace. + +To revoke an achievement, call the [`achievementsRevoke` GraphQL mutation](../../api/graphql/reference/index.md#mutationachievementsrevoke). + +```graphql +mutation { + achievementsRevoke(input: { + userAchievementId: "gid://gitlab/Achievements::UserAchievement/<user achievement id>" }) { + userAchievement { + id + achievement { + id + name + } + user { + id + username + } + revokedAt + } + errors + } +} +``` + +## Delete an achievement + +If you consider you no longer need an achievement, you can delete it. +This will delete all related awarded and revoked instances of the achievement. + +Prerequisites: + +- You must have the Maintainer or Owner role for the namespace. + +To delete an achievement, call the [`achievementsDelete` GraphQL mutation](../../api/graphql/reference/index.md#mutationachievementsdelete). + +```graphql +mutation { + achievementsDelete(input: { + achievementId: "gid://gitlab/Achievements::Achievement/<achievement id>" }) { + achievement { + id + name + } + errors + } +} +``` diff --git a/doc/user/profile/img/user_profile_achievements_v15_11.png b/doc/user/profile/img/user_profile_achievements_v15_11.png Binary files differnew file mode 100644 index 00000000000..28c5661dd54 --- /dev/null +++ b/doc/user/profile/img/user_profile_achievements_v15_11.png diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 123dd25200d..abc8ec296e1 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -4762,6 +4762,9 @@ msgstr "" msgid "Analytics|Add to Dashboard" msgstr "" +msgid "Analytics|An error occurred while loading data" +msgstr "" + msgid "Analytics|An error occurred while loading the %{visualizationTitle} visualization." msgstr "" @@ -13981,6 +13984,9 @@ msgstr "" msgid "DeletionSettings|Owners and administrators can delete projects." msgstr "" +msgid "DeletionSettings|Period that deleted groups and projects will remain restorable for. Personal projects are always deleted immediately." +msgstr "" + msgid "DeletionSettings|Retention period that deleted groups and projects will remain restorable. Personal projects are always deleted immediately. Some groups can opt-out their projects." msgstr "" diff --git a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_project_spec.rb b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_project_spec.rb index 43701a6b740..daf77b7b67c 100644 --- a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_project_spec.rb +++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_project_spec.rb @@ -6,7 +6,8 @@ module QA include_context 'with gitlab project migration' # this spec is used as a sanity test for gitlab migration because it can run outside of orchestrated setup - context 'with import within same instance', :reliable, orchestrated: false, import: false do + # TODO: `:reliable` should be added back once https://gitlab.com/gitlab-org/gitlab/-/issues/403001 is resolved + context 'with import within same instance', orchestrated: false, import: false do let!(:source_project_with_readme) { true } let!(:source_gitlab_address) { Runtime::Scenario.gitlab_address } let!(:source_admin_api_client) { admin_api_client } diff --git a/spec/frontend/vue_merge_request_widget/components/widget/widget_spec.js b/spec/frontend/vue_merge_request_widget/components/widget/widget_spec.js index 5887670a58d..ea7dabf34c9 100644 --- a/spec/frontend/vue_merge_request_widget/components/widget/widget_spec.js +++ b/spec/frontend/vue_merge_request_widget/components/widget/widget_spec.js @@ -287,6 +287,21 @@ describe('~/vue_merge_request_widget/components/widget/widget.vue', () => { expect(findExpandedSection().text()).toBe('More complex content'); }); + it('emits a toggle even when button is toggled', async () => { + createComponent({ + propsData: { + isCollapsible: true, + }, + slots: { + content: '<b>More complex content</b>', + }, + }); + + expect(findExpandedSection().exists()).toBe(false); + findToggleButton().vm.$emit('click'); + expect(wrapper.emitted('toggle')).toEqual([[{ expanded: true }]]); + }); + it('does not display the toggle button if isCollapsible is false', () => { createComponent({ propsData: { diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/base_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/base_token_spec.js index 9941abbfaea..f115ec2d6ca 100644 --- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/base_token_spec.js +++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/base_token_spec.js @@ -18,6 +18,7 @@ import { OPTIONS_NONE_ANY, OPERATOR_IS, OPERATOR_NOT, + OPERATOR_OR, } from '~/vue_shared/components/filtered_search_bar/constants'; import { getRecentlyUsedSuggestions, @@ -300,6 +301,7 @@ describe('BaseToken', () => { operator | shouldRenderFilteredSearchSuggestion ${OPERATOR_IS} | ${true} ${OPERATOR_NOT} | ${false} + ${OPERATOR_OR} | ${false} `('when operator is $operator', ({ shouldRenderFilteredSearchSuggestion, operator }) => { beforeEach(() => { const props = { diff --git a/spec/lib/gitlab/ci/variables/builder_spec.rb b/spec/lib/gitlab/ci/variables/builder_spec.rb index 2c6f0320242..914159c0984 100644 --- a/spec/lib/gitlab/ci/variables/builder_spec.rb +++ b/spec/lib/gitlab/ci/variables/builder_spec.rb @@ -101,6 +101,8 @@ RSpec.describe Gitlab::Ci::Variables::Builder, :clean_gitlab_redis_cache, featur value: project.pages_url }, { key: 'CI_API_V4_URL', value: API::Helpers::Version.new('v4').root_url }, + { key: 'CI_API_GRAPHQL_URL', + value: Gitlab::Routing.url_helpers.api_graphql_url }, { key: 'CI_TEMPLATE_REGISTRY_HOST', value: template_registry_host }, { key: 'CI_PIPELINE_IID', diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb index e93b5733d1a..880e1d3bcee 100644 --- a/spec/models/ci/build_spec.rb +++ b/spec/models/ci/build_spec.rb @@ -2788,6 +2788,7 @@ RSpec.describe Ci::Build, feature_category: :continuous_integration, factory_def public: true, masked: false }, { key: 'CI_API_V4_URL', value: 'http://localhost/api/v4', public: true, masked: false }, + { key: 'CI_API_GRAPHQL_URL', value: 'http://localhost/api/graphql', public: true, masked: false }, { key: 'CI_TEMPLATE_REGISTRY_HOST', value: template_registry_host, public: true, masked: false }, { key: 'CI_PIPELINE_IID', value: pipeline.iid.to_s, public: true, masked: false }, { key: 'CI_PIPELINE_SOURCE', value: pipeline.source, public: true, masked: false }, diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 11adbf161ee..1348ca4f3b3 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -5807,8 +5807,19 @@ RSpec.describe Project, factory_default: :keep, feature_category: :projects do let_it_be(:project) { create(:project) } it 'exposes API v4 URL' do - expect(project.api_variables.first[:key]).to eq 'CI_API_V4_URL' - expect(project.api_variables.first[:value]).to include '/api/v4' + v4_variable = project.api_variables.find { |variable| variable[:key] == "CI_API_V4_URL" } + + expect(v4_variable).not_to be_nil + expect(v4_variable[:key]).to eq 'CI_API_V4_URL' + expect(v4_variable[:value]).to end_with '/api/v4' + end + + it 'exposes API GraphQL URL' do + graphql_variable = project.api_variables.find { |variable| variable[:key] == "CI_API_GRAPHQL_URL" } + + expect(graphql_variable).not_to be_nil + expect(graphql_variable[:key]).to eq 'CI_API_GRAPHQL_URL' + expect(graphql_variable[:value]).to end_with '/api/graphql' end it 'contains a URL variable for every supported API version' do @@ -5823,7 +5834,7 @@ RSpec.describe Project, factory_default: :keep, feature_category: :projects do end expect(project.api_variables.map { |variable| variable[:key] }) - .to contain_exactly(*required_variables) + .to include(*required_variables) end end |