Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
43c14d2d92
commit
4b4c254b2c
|
@ -1 +1 @@
|
|||
94055b253d05bc04f533c977be892b0cd6f225ea
|
||||
803b179a6834fbebcc7886083731bb0f4a67c796
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { spriteIcon } from '~/lib/utils/common_utils';
|
||||
import { differenceInMilliseconds } from '~/lib/utils/datetime_utility';
|
||||
import { s__ } from '~/locale';
|
||||
import { unrestrictedPages } from './constants';
|
||||
|
||||
// Renders math using KaTeX in any element with the
|
||||
// `js-render-math` class
|
||||
|
@ -48,6 +49,7 @@ class SafeMathRenderer {
|
|||
this.renderElement = this.renderElement.bind(this);
|
||||
this.render = this.render.bind(this);
|
||||
this.attachEvents = this.attachEvents.bind(this);
|
||||
this.pageName = document.querySelector('body').dataset.page;
|
||||
}
|
||||
|
||||
renderElement(chosenEl) {
|
||||
|
@ -56,7 +58,7 @@ class SafeMathRenderer {
|
|||
}
|
||||
|
||||
const el = chosenEl || this.queue.shift();
|
||||
const forceRender = Boolean(chosenEl);
|
||||
const forceRender = Boolean(chosenEl) || unrestrictedPages.includes(this.pageName);
|
||||
const text = el.textContent;
|
||||
|
||||
el.removeAttribute('style');
|
||||
|
|
|
@ -8,6 +8,7 @@ import { __ } from '~/locale';
|
|||
import '~/behaviors/markdown/render_gfm';
|
||||
import Suggestions from '~/vue_shared/components/markdown/suggestions.vue';
|
||||
import autosave from '../mixins/autosave';
|
||||
import { CONFIDENTIAL_CLASSES } from '../constants';
|
||||
import noteAttachment from './note_attachment.vue';
|
||||
import noteAwardsList from './note_awards_list.vue';
|
||||
import noteEditedText from './note_edited_text.vue';
|
||||
|
@ -54,6 +55,11 @@ export default {
|
|||
required: false,
|
||||
default: '',
|
||||
},
|
||||
isConfidential: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['getDiscussion', 'suggestionsCount', 'getSuggestionsFilePaths']),
|
||||
|
@ -95,6 +101,12 @@ export default {
|
|||
|
||||
return escape(suggestion);
|
||||
},
|
||||
confidentialContainerClasses() {
|
||||
if (this.isConfidential && !this.isEditing) {
|
||||
return CONFIDENTIAL_CLASSES;
|
||||
}
|
||||
return '';
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.renderGFM();
|
||||
|
@ -160,53 +172,61 @@ export default {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div ref="note-body" :class="{ 'js-task-list-container': canEdit }" class="note-body">
|
||||
<suggestions
|
||||
v-if="hasSuggestion && !isEditing"
|
||||
:suggestions="note.suggestions"
|
||||
:suggestions-count="suggestionsCount"
|
||||
:batch-suggestions-info="batchSuggestionsInfo"
|
||||
:note-html="note.note_html"
|
||||
:line-type="lineType"
|
||||
:help-page-path="helpPagePath"
|
||||
:default-commit-message="commitMessage"
|
||||
:failed-to-load-metadata="failedToLoadMetadata"
|
||||
@apply="applySuggestion"
|
||||
@applyBatch="applySuggestionBatch"
|
||||
@addToBatch="addSuggestionToBatch"
|
||||
@removeFromBatch="removeSuggestionFromBatch"
|
||||
/>
|
||||
<div v-else v-safe-html:[$options.safeHtmlConfig]="note.note_html" class="note-text md"></div>
|
||||
<note-form
|
||||
v-if="isEditing"
|
||||
ref="noteForm"
|
||||
:note-body="noteBody"
|
||||
:note-id="note.id"
|
||||
:line="line"
|
||||
:note="note"
|
||||
:save-button-title="saveButtonTitle"
|
||||
:help-page-path="helpPagePath"
|
||||
:discussion="discussion"
|
||||
:resolve-discussion="note.resolve_discussion"
|
||||
@handleFormUpdate="handleFormUpdate"
|
||||
@cancelForm="formCancelHandler"
|
||||
/>
|
||||
<!-- eslint-disable vue/no-mutating-props -->
|
||||
<textarea
|
||||
v-if="canEdit"
|
||||
v-model="note.note"
|
||||
:data-update-url="note.path"
|
||||
class="hidden js-task-list-field"
|
||||
dir="auto"
|
||||
></textarea>
|
||||
<!-- eslint-enable vue/no-mutating-props -->
|
||||
<note-edited-text
|
||||
v-if="note.last_edited_at"
|
||||
:edited-at="note.last_edited_at"
|
||||
:edited-by="note.last_edited_by"
|
||||
action-text="Edited"
|
||||
class="note_edited_ago"
|
||||
/>
|
||||
<div
|
||||
ref="note-body"
|
||||
:class="{
|
||||
'js-task-list-container': canEdit,
|
||||
}"
|
||||
class="note-body"
|
||||
>
|
||||
<div :class="confidentialContainerClasses" data-testid="note-confidential-container">
|
||||
<suggestions
|
||||
v-if="hasSuggestion && !isEditing"
|
||||
:suggestions="note.suggestions"
|
||||
:suggestions-count="suggestionsCount"
|
||||
:batch-suggestions-info="batchSuggestionsInfo"
|
||||
:note-html="note.note_html"
|
||||
:line-type="lineType"
|
||||
:help-page-path="helpPagePath"
|
||||
:default-commit-message="commitMessage"
|
||||
:failed-to-load-metadata="failedToLoadMetadata"
|
||||
@apply="applySuggestion"
|
||||
@applyBatch="applySuggestionBatch"
|
||||
@addToBatch="addSuggestionToBatch"
|
||||
@removeFromBatch="removeSuggestionFromBatch"
|
||||
/>
|
||||
<div v-else v-safe-html:[$options.safeHtmlConfig]="note.note_html" class="note-text md"></div>
|
||||
<note-form
|
||||
v-if="isEditing"
|
||||
ref="noteForm"
|
||||
:note-body="noteBody"
|
||||
:note-id="note.id"
|
||||
:line="line"
|
||||
:note="note"
|
||||
:save-button-title="saveButtonTitle"
|
||||
:help-page-path="helpPagePath"
|
||||
:discussion="discussion"
|
||||
:resolve-discussion="note.resolve_discussion"
|
||||
@handleFormUpdate="handleFormUpdate"
|
||||
@cancelForm="formCancelHandler"
|
||||
/>
|
||||
<!-- eslint-disable vue/no-mutating-props -->
|
||||
<textarea
|
||||
v-if="canEdit"
|
||||
v-model="note.note"
|
||||
:data-update-url="note.path"
|
||||
class="hidden js-task-list-field"
|
||||
dir="auto"
|
||||
></textarea>
|
||||
<!-- eslint-enable vue/no-mutating-props -->
|
||||
<note-edited-text
|
||||
v-if="note.last_edited_at"
|
||||
:edited-at="note.last_edited_at"
|
||||
:edited-by="note.last_edited_by"
|
||||
action-text="Edited"
|
||||
class="note_edited_ago"
|
||||
/>
|
||||
</div>
|
||||
<note-awards-list
|
||||
v-if="note.award_emoji && note.award_emoji.length"
|
||||
:note-id="note.id"
|
||||
|
|
|
@ -236,6 +236,7 @@ export default {
|
|||
data-testid="internalNoteIndicator"
|
||||
variant="warning"
|
||||
size="sm"
|
||||
class="gl-mb-3 gl-ml-2"
|
||||
:title="noteConfidentialityTooltip"
|
||||
>
|
||||
{{ __('Internal note') }}
|
||||
|
|
|
@ -493,9 +493,10 @@ export default {
|
|||
<note-body
|
||||
ref="noteBody"
|
||||
:note="note"
|
||||
:can-edit="note.current_user.can_edit"
|
||||
:is-confidential="note.confidential"
|
||||
:line="line"
|
||||
:file="diffFile"
|
||||
:can-edit="note.current_user.can_edit"
|
||||
:is-editing="isEditing"
|
||||
:help-page-path="helpPagePath"
|
||||
@handleFormUpdate="formUpdateHandler"
|
||||
|
|
|
@ -51,3 +51,5 @@ export const toggleStateErrorMessage = {
|
|||
[REOPENED]: __('Something went wrong while closing the merge request. Please try again later.'),
|
||||
},
|
||||
};
|
||||
|
||||
export const CONFIDENTIAL_CLASSES = ['gl-bg-orange-50', 'gl-px-4', 'gl-py-2'];
|
||||
|
|
|
@ -168,7 +168,7 @@ export default {
|
|||
if (data || operator) {
|
||||
this.searchKey = data;
|
||||
|
||||
if (!this.suggestionsLoading && !this.activeTokenValue) {
|
||||
if (!this.activeTokenValue) {
|
||||
let search = this.searchTerm ? this.searchTerm : data;
|
||||
|
||||
if (search.startsWith('"') && search.endsWith('"')) {
|
||||
|
|
|
@ -568,6 +568,10 @@ module Ci
|
|||
options&.dig(:environment, :on_stop)
|
||||
end
|
||||
|
||||
def stop_action_successful?
|
||||
Feature.disabled?(:env_stopped_on_stop_success, project) || success?
|
||||
end
|
||||
|
||||
##
|
||||
# All variables, including persisted environment variables.
|
||||
#
|
||||
|
|
|
@ -132,10 +132,16 @@ class Environment < ApplicationRecord
|
|||
end
|
||||
|
||||
event :stop do
|
||||
transition available: :stopped
|
||||
transition available: :stopping, if: :wait_for_stop?
|
||||
transition available: :stopped, unless: :wait_for_stop?
|
||||
end
|
||||
|
||||
event :stop_complete do
|
||||
transition %i(available stopping) => :stopped
|
||||
end
|
||||
|
||||
state :available
|
||||
state :stopping
|
||||
state :stopped
|
||||
|
||||
before_transition any => :stopped do |environment|
|
||||
|
@ -293,6 +299,10 @@ class Environment < ApplicationRecord
|
|||
end
|
||||
end
|
||||
|
||||
def wait_for_stop?
|
||||
stop_actions.present? && Feature.enabled?(:env_stopped_on_stop_success, project)
|
||||
end
|
||||
|
||||
def stop_with_actions!(current_user)
|
||||
return unless available?
|
||||
|
||||
|
|
|
@ -7,7 +7,11 @@ module Environments
|
|||
def execute(environment)
|
||||
return unless can?(current_user, :stop_environment, environment)
|
||||
|
||||
environment.stop_with_actions!(current_user)
|
||||
if params[:force]
|
||||
environment.stop_complete!
|
||||
else
|
||||
environment.stop_with_actions!(current_user)
|
||||
end
|
||||
end
|
||||
|
||||
def execute_for_branch(branch_name)
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
- if impersonation_enabled? && @user.can?(:log_in)
|
||||
= link_to _('Impersonate'), impersonate_admin_user_path(@user), method: :post, class: "btn btn-default gl-button", data: { qa_selector: 'impersonate_user_link' }
|
||||
- if can_force_email_confirmation?(@user)
|
||||
%button.btn.gl-button.btn-info.js-confirm-modal-button{ data: confirm_user_data(@user) }
|
||||
%button.btn.gl-button.btn-confirm.js-confirm-modal-button{ data: confirm_user_data(@user) }
|
||||
= _('Confirm user')
|
||||
.gl-p-2
|
||||
#js-admin-user-actions{ data: admin_user_actions_data_attributes(@user) }
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
title: group_url_error_message,
|
||||
maxlength: ::Namespace::URL_MAX_LENGTH,
|
||||
"data-bind-in" => "#{'create_chat_team' if Gitlab.config.mattermost.enabled}"
|
||||
= f.submit s_('GroupSettings|Change group URL'), class: 'btn gl-button btn-warning'
|
||||
= f.submit s_('GroupSettings|Change group URL'), class: 'btn gl-button btn-danger'
|
||||
|
||||
= render 'groups/settings/transfer', group: @group
|
||||
= render 'groups/settings/remove', group: @group, remove_form_id: remove_form_id
|
||||
|
|
|
@ -2983,15 +2983,6 @@
|
|||
:weight: 1
|
||||
:idempotent:
|
||||
:tags: []
|
||||
- :name: repository_remove_remote
|
||||
:worker_name: RepositoryRemoveRemoteWorker
|
||||
:feature_category: :source_code_management
|
||||
:has_external_dependencies:
|
||||
:urgency: :low
|
||||
:resource_boundary: :unknown
|
||||
:weight: 1
|
||||
:idempotent:
|
||||
:tags: []
|
||||
- :name: repository_update_remote_mirror
|
||||
:worker_name: RepositoryUpdateRemoteMirrorWorker
|
||||
:feature_category: :source_code_management
|
||||
|
|
|
@ -13,13 +13,13 @@ class BuildSuccessWorker # rubocop:disable Scalability/IdempotentWorker
|
|||
|
||||
def perform(build_id)
|
||||
Ci::Build.find_by_id(build_id).try do |build|
|
||||
stop_environment(build) if build.stops_environment?
|
||||
stop_environment(build) if build.stops_environment? && build.stop_action_successful?
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def stop_environment(build)
|
||||
build.persisted_environment.fire_state_event(:stop)
|
||||
build.persisted_environment.fire_state_event(:stop_complete)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RepositoryRemoveRemoteWorker # rubocop:disable Scalability/IdempotentWorker
|
||||
include ApplicationWorker
|
||||
|
||||
data_consistency :always
|
||||
|
||||
sidekiq_options retry: 3
|
||||
include ExclusiveLeaseGuard
|
||||
|
||||
feature_category :source_code_management
|
||||
loggable_arguments 1
|
||||
|
||||
LEASE_TIMEOUT = 1.hour
|
||||
|
||||
attr_reader :project, :remote_name
|
||||
|
||||
def perform(project_id, remote_name)
|
||||
# On-disk remotes are slated for removal, and GitLab doesn't create any of
|
||||
# them anymore. For backwards compatibility, we need to keep the worker
|
||||
# though such that we can be sure to drain all jobs on an update. Making
|
||||
# this a no-op is fine though: the worst that can happen is that we still
|
||||
# have old remotes lingering in the repository's config, but Gitaly will
|
||||
# start to clean these up in repository maintenance.
|
||||
# https://gitlab.com/gitlab-org/gitlab/-/issues/336745
|
||||
end
|
||||
|
||||
def lease_timeout
|
||||
LEASE_TIMEOUT
|
||||
end
|
||||
|
||||
def lease_key
|
||||
"remove_remote_#{project.id}_#{remote_name}"
|
||||
end
|
||||
end
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
name: env_stopped_on_stop_success
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/86478
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/361473
|
||||
milestone: '15.0'
|
||||
type: development
|
||||
group: group::release
|
||||
default_enabled: false
|
|
@ -407,8 +407,6 @@
|
|||
- 1
|
||||
- - repository_push_audit_event
|
||||
- 1
|
||||
- - repository_remove_remote
|
||||
- 1
|
||||
- - repository_update_mirror
|
||||
- 1
|
||||
- - repository_update_remote_mirror
|
||||
|
|
|
@ -3,7 +3,7 @@ table_name: ci_builds_runner_session
|
|||
classes:
|
||||
- Ci::BuildRunnerSession
|
||||
feature_categories:
|
||||
- continuous_integration
|
||||
description: TODO
|
||||
- runner
|
||||
description: Store build-related runner session. Data is removed after the respective job transitions from running to any state.
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/6208
|
||||
milestone: '11.1'
|
||||
|
|
|
@ -120,7 +120,7 @@ Learn how to install, configure, update, and maintain your GitLab instance.
|
|||
|
||||
- [Creating users](../user/profile/account/create_accounts.md): Create users manually or through authentication integrations.
|
||||
- [Libravatar](libravatar.md): Use Libravatar instead of Gravatar for user avatars.
|
||||
- [Sign-up restrictions](../user/admin_area/settings/sign_up_restrictions.md): block email addresses of specific domains, or whitelist only specific domains.
|
||||
- [Sign-up restrictions](../user/admin_area/settings/sign_up_restrictions.md): block email addresses of specific domains, or allow only specific domains.
|
||||
- [Access restrictions](../user/admin_area/settings/visibility_and_access_controls.md#configure-enabled-git-access-protocols): Define which Git access protocols can be used to talk to GitLab (SSH, HTTP, HTTPS).
|
||||
- [Authentication and Authorization](auth/index.md): Configure external authentication with LDAP, SAML, CAS, and additional providers.
|
||||
- [Sync LDAP](auth/ldap/index.md)
|
||||
|
|
|
@ -1170,7 +1170,7 @@ The flow described by the diagram above:
|
|||
|
||||
1. A user runs `docker login registry.gitlab.example` on their client. This reaches the web server (or LB) on port 443.
|
||||
1. Web server connects to the Registry backend pool (by default, using port 5000). Since the user
|
||||
didn’t provide a valid token, the Registry returns a 401 HTTP code and the URL (`token_realm` from
|
||||
didn't provide a valid token, the Registry returns a 401 HTTP code and the URL (`token_realm` from
|
||||
Registry configuration) where to get one. This points to the GitLab API.
|
||||
1. The Docker client then connects to the GitLab API and obtains a token.
|
||||
1. The API signs the token with the registry key and hands it to the Docker client
|
||||
|
|
|
@ -1187,7 +1187,8 @@ Rate limits are enforced using the following:
|
|||
|
||||
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
|
||||
one might have when setting this up, or when something is changed, or on upgrading, it's
|
||||
important to describe those, too. Think of things that may go wrong and include them here.
|
||||
important to describe those, too. Think of things that may go wrong and include them in
|
||||
the section below.
|
||||
This is important to minimize requests for support, and to avoid doc comments with
|
||||
questions that you know someone might ask.
|
||||
|
||||
|
@ -1541,7 +1542,7 @@ In GitLab 14.0-14.2 you can temporarily enable legacy storage and configuration
|
|||
|
||||
To do that:
|
||||
|
||||
1. Please describe the issue you're seeing in [here](https://gitlab.com/gitlab-org/gitlab/-/issues/331699).
|
||||
1. Please describe the issue you're seeing in the [migration feedback issue](https://gitlab.com/gitlab-org/gitlab/-/issues/331699).
|
||||
|
||||
1. Edit `/etc/gitlab/gitlab.rb`:
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ monitor .[#7FFFD4,norank]--> redis
|
|||
@enduml
|
||||
```
|
||||
|
||||
The diagram above shows that while GitLab can be installed on a single server, it is internally composed of multiple services. As a GitLab instance is scaled, each of these services are broken out and independently scaled according to the demands placed on them. In some cases PaaS can be leveraged for some services (e.g. Cloud Object Storage for some file systems). For the sake of redundancy some of the services become clusters of nodes storing the same data. In a horizontal configuration of GitLab there are various ancillary services required to coordinate clusters or discover of resources (e.g. PgBouncer for PostgreSQL connection management, Consul for Prometheus end point discovery).
|
||||
The diagram above shows that while GitLab can be installed on a single server, it is internally composed of multiple services. As a GitLab instance is scaled, each of these services are broken out and independently scaled according to the demands placed on them. In some cases PaaS can be leveraged for some services (for example, Cloud Object Storage for some file systems). For the sake of redundancy some of the services become clusters of nodes storing the same data. In a horizontal configuration of GitLab there are various ancillary services required to coordinate clusters or discover of resources (for example, PgBouncer for PostgreSQL connection management, Consul for Prometheus end point discovery).
|
||||
|
||||
## Requirements
|
||||
|
||||
|
|
|
@ -116,7 +116,7 @@ per 1,000 users:
|
|||
### How to interpret the results
|
||||
|
||||
NOTE:
|
||||
Read our blog post on [how our QA team leverages GitLab’s performance testing tool](https://about.gitlab.com/blog/2020/02/18/how-were-building-up-performance-testing-of-gitlab/).
|
||||
Read our blog post on [how our QA team leverages GitLab performance testing tool](https://about.gitlab.com/blog/2020/02/18/how-were-building-up-performance-testing-of-gitlab/).
|
||||
|
||||
Testing is done publicly and all results are shared.
|
||||
|
||||
|
|
|
@ -15,12 +15,12 @@ Get all environments for a given project.
|
|||
GET /projects/:id/environments
|
||||
```
|
||||
|
||||
| Attribute | Type | Required | Description |
|
||||
| --------- | ------- | -------- | --------------------- |
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `name` | string | no | Return the environment with this name. Mutually exclusive with `search` |
|
||||
| `search` | string | no | Return list of environments matching the search criteria. Mutually exclusive with `name` |
|
||||
| `states` | string | no | List all environments that match a specific state. Accepted values: `available` or `stopped`. If no state value given, returns all environments. |
|
||||
| Attribute | Type | Required | Description |
|
||||
| --------- | ------- | -------- |-------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `name` | string | no | Return the environment with this name. Mutually exclusive with `search` |
|
||||
| `search` | string | no | Return list of environments matching the search criteria. Mutually exclusive with `name` |
|
||||
| `states` | string | no | List all environments that match a specific state. Accepted values: `available`, `stopping` or `stopped`. If no state value given, returns all environments. |
|
||||
|
||||
```shell
|
||||
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/environments?name=review%2Ffix-foo"
|
||||
|
@ -382,10 +382,11 @@ It returns `200` if the environment was successfully stopped, and `404` if the e
|
|||
POST /projects/:id/environments/:environment_id/stop
|
||||
```
|
||||
|
||||
| Attribute | Type | Required | Description |
|
||||
| --------- | ------- | -------- | --------------------- |
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `environment_id` | integer | yes | The ID of the environment |
|
||||
| Attribute | Type | Required | Description |
|
||||
|------------------|----------------|----------|----------------------------------------------------------------------------------------------------------------|
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `environment_id` | integer | yes | The ID of the environment |
|
||||
| `force` | boolean | no | Force environment to stop even when `on_stop` action fails |
|
||||
|
||||
```shell
|
||||
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/environments/1/stop"
|
||||
|
|
|
@ -234,8 +234,8 @@ Parameters:
|
|||
|:-------------|:---------------|:---------|:----------------------------------------------------------------------------------------------------------------|
|
||||
| `id` | integer or string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
|
||||
| `snippet_id` | integer | yes | The ID of a project's snippet |
|
||||
| `ref` | string | yes | The name of a branch, tag or commit e.g. master |
|
||||
| `file_path` | string | yes | The URL-encoded path to the file, e.g. snippet%2Erb |
|
||||
| `ref` | string | yes | The name of a branch, tag or commit, for example, main |
|
||||
| `file_path` | string | yes | The URL-encoded path to the file, for example, snippet%2Erb |
|
||||
|
||||
Example request:
|
||||
|
||||
|
|
|
@ -90,6 +90,10 @@ To view CI/CD minutes being used for your group:
|
|||
|
||||
![Group CI/CD minutes quota](img/group_cicd_minutes_quota.png)
|
||||
|
||||
The projects list shows projects with CI/CD minute usage or shared runners usage
|
||||
in the current month only. The list includes all projects in the namespace and its
|
||||
subgroups, sorted in descending order of CI/CD minute usage.
|
||||
|
||||
## View CI/CD minutes used by a personal namespace
|
||||
|
||||
> Displaying shared runners duration [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/345795) in GitLab 15.0.
|
||||
|
@ -100,6 +104,10 @@ You can view the number of CI/CD minutes being used by a personal namespace:
|
|||
1. Select **Edit profile**.
|
||||
1. On the left sidebar, select **Usage Quotas**.
|
||||
|
||||
The projects list shows [personal projects](../../user/project/working_with_projects.md#view-personal-projects)
|
||||
with CI/CD minutes usage or shared runners usage in the current month only. The list
|
||||
is sorted in descending order of CI/CD minute usage.
|
||||
|
||||
## Purchase additional CI/CD minutes **(FREE SAAS)**
|
||||
|
||||
If you're using GitLab SaaS, you can purchase additional packs of CI/CD minutes.
|
||||
|
|
|
@ -9,7 +9,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9186) in GitLab 12.0.
|
||||
> - [Squash and merge](../../user/project/merge_requests/squash_and_merge.md) support [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13001) in GitLab 12.6.
|
||||
|
||||
For more information about why you might want to use merge trains, read [How merge trains keep your master green](https://about.gitlab.com/blog/2020/01/30/all-aboard-merge-trains/).
|
||||
For more information about why you might want to use merge trains, read [How starting merge trains improve efficiency for DevOps](https://about.gitlab.com/blog/2020/01/30/all-aboard-merge-trains/).
|
||||
|
||||
When [merged results pipelines](merged_results_pipelines.md) are
|
||||
enabled, the pipeline jobs run as if the changes from your source branch have already
|
||||
|
|
|
@ -53,7 +53,7 @@ and they serve us and our users well. Some examples of these principles are that
|
|||
- The feedback delivered by GitLab CI/CD and data produced by the platform should be accurate.
|
||||
If a job fails and we notify a user that it was successful, it can have severe negative consequences.
|
||||
- Feedback needs to be available when a user needs it and data can not disappear unexpectedly when engineers need it.
|
||||
- It all doesn’t matter if the platform is not secure and we
|
||||
- It all doesn't matter if the platform is not secure and we
|
||||
are leaking credentials or secrets.
|
||||
- When a user provides a set of preconditions in a form of CI/CD configuration, the result should be deterministic each time a pipeline runs, because otherwise the platform might not be trustworthy.
|
||||
- If it is fast, simple to use and has a great UX it will serve our users well.
|
||||
|
|
|
@ -67,9 +67,9 @@ In the `detect-tests` job, we use this mapping to identify the minimal tests nee
|
|||
In addition, there are a few circumstances where we would always run the full RSpec tests:
|
||||
|
||||
- when the `pipeline:run-all-rspec` label is set on the merge request
|
||||
- when the merge request is created by an automation (e.g. Gitaly update or MR targeting a stable branch)
|
||||
- when the merge request is created by an automation (for example, Gitaly update or MR targeting a stable branch)
|
||||
- when the merge request is created in a security mirror
|
||||
- when any CI configuration file is changed (i.e. `.gitlab-ci.yml` or `.gitlab/ci/**/*`)
|
||||
- when any CI configuration file is changed (for example, `.gitlab-ci.yml` or `.gitlab/ci/**/*`)
|
||||
|
||||
### Jest minimal jobs
|
||||
|
||||
|
@ -83,11 +83,11 @@ In this mode, `jest` would resolve all the dependencies of related to the change
|
|||
In addition, there are a few circumstances where we would always run the full Jest tests:
|
||||
|
||||
- when the `pipeline:run-all-jest` label is set on the merge request
|
||||
- when the merge request is created by an automation (e.g. Gitaly update or MR targeting a stable branch)
|
||||
- when the merge request is created by an automation (for example, Gitaly update or MR targeting a stable branch)
|
||||
- when the merge request is created in a security mirror
|
||||
- when any CI configuration file is changed (i.e. `.gitlab-ci.yml` or `.gitlab/ci/**/*`)
|
||||
- when any frontend "core" file is changed (i.e. `package.json`, `yarn.lock`, `babel.config.js`, `jest.config.*.js`, `config/helpers/**/*.js`)
|
||||
- when any vendored JavaScript file is changed (i.e. `vendor/assets/javascripts/**/*`)
|
||||
- when any CI configuration file is changed (for example, `.gitlab-ci.yml` or `.gitlab/ci/**/*`)
|
||||
- when any frontend "core" file is changed (for example, `package.json`, `yarn.lock`, `babel.config.js`, `jest.config.*.js`, `config/helpers/**/*.js`)
|
||||
- when any vendored JavaScript file is changed (for example, `vendor/assets/javascripts/**/*`)
|
||||
- when any backend file is changed ([see the patterns list for details](https://gitlab.com/gitlab-org/gitlab/-/blob/3616946936c1adbd9e754c1bd06f86ba670796d8/.gitlab/ci/rules.gitlab-ci.yml#L205-216))
|
||||
|
||||
### Fork pipelines
|
||||
|
@ -226,7 +226,7 @@ of `gitlab-org/gitlab-foss`. These jobs are only created in the following cases:
|
|||
|
||||
- when the `pipeline:run-as-if-foss` label is set on the merge request
|
||||
- when the merge request is created in the `gitlab-org/security/gitlab` project
|
||||
- when any CI configuration file is changed (i.e. `.gitlab-ci.yml` or `.gitlab/ci/**/*`)
|
||||
- when any CI configuration file is changed (for example, `.gitlab-ci.yml` or `.gitlab/ci/**/*`)
|
||||
|
||||
The `* as-if-foss` jobs are run in addition to the regular EE-context jobs. They have the `FOSS_ONLY='1'` variable
|
||||
set and get the `ee/` folder removed before the tests start running.
|
||||
|
@ -339,7 +339,7 @@ In general, pipelines for an MR fall into one of the following types (from short
|
|||
- [Frontend pipeline](#frontend-pipeline): For MRs that touch frontend code.
|
||||
- [End-to-end pipeline](#end-to-end-pipeline): For MRs that touch code in the `qa/` folder.
|
||||
|
||||
A "pipeline type" is an abstract term that mostly describes the "critical path" (i.e. the chain of jobs for which the sum
|
||||
A "pipeline type" is an abstract term that mostly describes the "critical path" (for example, the chain of jobs for which the sum
|
||||
of individual duration equals the pipeline's duration).
|
||||
We use these "pipeline types" in [metrics dashboards](https://app.periscopedata.com/app/gitlab/858266/GitLab-Pipeline-Durations)
|
||||
in order to detect what types and jobs need to be optimized first.
|
||||
|
@ -719,11 +719,11 @@ This job tries to download a generic package that contains GitLab Workhorse bina
|
|||
We also changed the `setup-test-env` job to:
|
||||
|
||||
1. First download the GitLab Workhorse generic package build and uploaded by `build-components`.
|
||||
1. If the package is retrieved successfully, its content is placed in the right folder (i.e. `tmp/tests/gitlab-workhorse`), preventing the building of the binaries when `scripts/setup-test-env` is run later on.
|
||||
1. If the package is retrieved successfully, its content is placed in the right folder (for example, `tmp/tests/gitlab-workhorse`), preventing the building of the binaries when `scripts/setup-test-env` is run later on.
|
||||
1. If the package URL returns a 404, the behavior doesn't change compared to the current one: the GitLab Workhorse binaries are built as part of `scripts/setup-test-env`.
|
||||
|
||||
NOTE:
|
||||
The version of the package is the workhorse tree SHA (i.e. `git rev-parse HEAD:workhorse`).
|
||||
The version of the package is the workhorse tree SHA (for example, `git rev-parse HEAD:workhorse`).
|
||||
|
||||
### Pre-clone step
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ By using a `before_action` you don't have to modify the controller method in
|
|||
question, reducing the likelihood of merge conflicts.
|
||||
|
||||
For Grape API endpoints there unfortunately is not a reliable way of running a
|
||||
hook before a specific endpoint. This means that you have to add the whitelist
|
||||
hook before a specific endpoint. This means that you have to add the allowlist
|
||||
call directly into the endpoint like so:
|
||||
|
||||
```ruby
|
||||
|
|
|
@ -24,7 +24,7 @@ Some examples where you would need to do this are:
|
|||
## Database connections in initializers
|
||||
|
||||
Ideally, database connections are not opened from Rails initializers. Opening a
|
||||
database connection (e.g. checking the database exists, or making a database
|
||||
database connection (for example, checking the database exists, or making a database
|
||||
query) from an initializer means that tasks like `db:drop`, and
|
||||
`db:test:prepare` will fail because an active session prevents the database from
|
||||
being dropped.
|
||||
|
|
|
@ -104,6 +104,6 @@ To get started, see an [example merge request](https://gitlab.com/gitlab-org/git
|
|||
|
||||
## Useful links
|
||||
|
||||
- [Routing improvements master plan](https://gitlab.com/gitlab-org/gitlab/-/issues/215362)
|
||||
- [Routing improvements main plan](https://gitlab.com/gitlab-org/gitlab/-/issues/215362)
|
||||
- [Scoped routing explained](https://gitlab.com/gitlab-org/gitlab/-/issues/214217)
|
||||
- [Removal of deprecated routes](https://gitlab.com/gitlab-org/gitlab/-/issues/28848)
|
||||
|
|
|
@ -698,7 +698,7 @@ tls.Config{
|
|||
}
|
||||
```
|
||||
|
||||
This example was taken [here](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/871b52dc700f1a66f6644fbb1e78a6d463a6ff83/internal/tool/tlstool/tlstool.go#L72).
|
||||
This example was taken [from the GitLab Agent](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/871b52dc700f1a66f6644fbb1e78a6d463a6ff83/internal/tool/tlstool/tlstool.go#L72).
|
||||
|
||||
For **Ruby**, you can use again [`HTTParty`](https://github.com/jnunemaker/httparty) and specify this time TLS 1.2 version alongside with the recommended ciphers:
|
||||
|
||||
|
|
|
@ -464,7 +464,7 @@ To generate Service Ping, use [Teleport](https://goteleport.com/docs/) or a deta
|
|||
|
||||
1. Get the metrics duration from logs:
|
||||
|
||||
Search in Google Console logs for `time_elapsed`. Query example [here](https://cloudlogging.app.goo.gl/nWheZvD8D3nWazNe6).
|
||||
Search in Google Console logs for `time_elapsed`. [Query example](https://cloudlogging.app.goo.gl/nWheZvD8D3nWazNe6).
|
||||
|
||||
### Verification (After approx 30 hours)
|
||||
|
||||
|
|
|
@ -531,7 +531,7 @@ When you implement a new type of reusable resource there are two `private` metho
|
|||
can be validated. They are:
|
||||
|
||||
- `reference_resource`: creates a new instance of the resource that can be compared with the one that was used during the tests.
|
||||
- `unique_identifiers`: returns an array of attributes that allow the resource to be identified (e.g., name) and that are therefore
|
||||
- `unique_identifiers`: returns an array of attributes that allow the resource to be identified (for example, name) and that are therefore
|
||||
expected to differ when comparing the reference resource with the resource reused in the tests.
|
||||
|
||||
The following example shows the implementation of those two methods in `QA::Resource::ReusableProject`.
|
||||
|
|
|
@ -211,7 +211,7 @@ sudo apt-get install -y libimage-exiftool-perl
|
|||
## 2. Ruby
|
||||
|
||||
The Ruby interpreter is required to run GitLab.
|
||||
See the [requirements section of this page](#software-requirements) for the minimum
|
||||
See the [requirements section](#software-requirements) for the minimum
|
||||
Ruby requirements.
|
||||
|
||||
The use of Ruby version managers such as [`RVM`](https://rvm.io/), [`rbenv`](https://github.com/rbenv/rbenv) or [`chruby`](https://github.com/postmodern/chruby) with GitLab
|
||||
|
|
|
@ -192,9 +192,9 @@ If you have any questions, send an email to `opensource@gitlab.com` for assistan
|
|||
|
||||
GitLab for Open Source Program benefits apply to an entire GitLab namespace. To qualify for the GitLab for Open Source Program, **all projects in an applicant's namespace** must carry an [OSI-approved license](https://opensource.org/licenses/).
|
||||
|
||||
To add a license:
|
||||
To add a license:
|
||||
|
||||
1. On the top bar, select **Menu > Projects** and find your project.
|
||||
1. On the top bar, select **Menu > Projects** and find your project.
|
||||
1. On the overview page, select **Add LICENSE**. If the license you want is not available as a license template, manually copy the entire, unaltered [text of your chosen license](https://opensource.org/licenses/alphabetical) into the `LICENSE` file. Note that GitLab defaults to **All rights reserved** if users do not perform this action.
|
||||
|
||||
Applicants must add the correct license to each project in their respective groups or namespaces When you're sure you're using OSI-approved licenses for your projects, you can take your screenshots.
|
||||
|
@ -229,7 +229,7 @@ Benefits of the GitLab Open Source Program apply to all projects in a GitLab nam
|
|||
|
||||
To be eligible for the GitLab Open Source Program, projects must be publicly visible. To check your project's public visibility settings:
|
||||
|
||||
1. On the top bar, select **Menu > Projects** and find your project.
|
||||
1. On the top bar, select **Menu > Projects** and find your project.
|
||||
1. From the left sidebar, select **Settings > General**.
|
||||
1. Expand **Visibility, project features, permissions**.
|
||||
1. From the **Project visibility** dropdown list, select **Public**.
|
||||
|
|
|
@ -589,7 +589,7 @@ You can only upgrade one minor release at a time.
|
|||
|
||||
This section describes the steps required to upgrade a multi-node / HA
|
||||
deployment with Geo. Some steps must be performed on a particular node. This
|
||||
node is known as the “deploy node” and is noted through the following
|
||||
node is known as the "deploy node" and is noted through the following
|
||||
instructions.
|
||||
|
||||
Updates must be performed in the following order:
|
||||
|
|
|
@ -95,7 +95,7 @@ is **not** `19.03.0`. See [troubleshooting information](#error-response-from-dae
|
|||
|
||||
WARNING:
|
||||
Dependency Scanning does not support run-time installation of compilers and interpreters.
|
||||
If you have need of this, please explain why by filling out the survey [here](https://docs.google.com/forms/d/e/1FAIpQLScKo7xEYA65rOjPTGIufAyfjPGnCALSJZoTxBlvskfFMEOZMw/viewform).
|
||||
If you need it, please explain why by filling out [the survey](https://docs.google.com/forms/d/e/1FAIpQLScKo7xEYA65rOjPTGIufAyfjPGnCALSJZoTxBlvskfFMEOZMw/viewform).
|
||||
|
||||
## Supported languages and package managers
|
||||
|
||||
|
@ -1225,7 +1225,7 @@ version `58.1.0+`, which doesn't support `2to3`. Therefore, a `setuptools` depen
|
|||
error in <dependency name> setup command: use_2to3 is invalid
|
||||
```
|
||||
|
||||
To work around this error, downgrade the analyzer's version of `setuptools` (e.g. `v57.5.0`):
|
||||
To work around this error, downgrade the analyzer's version of `setuptools` (for example, `v57.5.0`):
|
||||
|
||||
```yaml
|
||||
gemnasium-python-dependency_scanning:
|
||||
|
|
|
@ -136,13 +136,13 @@ GitLab also provides a [KPT package for the agent](https://gitlab.com/gitlab-org
|
|||
|
||||
To install a second agent in your cluster, you can follow the [previous steps](#register-the-agent-with-gitlab) a second time. To avoid resource name collisions within the cluster, you must either:
|
||||
|
||||
- Use a different release name for the agent, e.g. `second-gitlab-agent`:
|
||||
- Use a different release name for the agent, for example, `second-gitlab-agent`:
|
||||
|
||||
```shell
|
||||
helm upgrade --install second-gitlab-agent gitlab/gitlab-agent ...
|
||||
```
|
||||
|
||||
- Or, install the agent in a different namespace, e.g. `different-namespace`:
|
||||
- Or, install the agent in a different namespace, for example, `different-namespace`:
|
||||
|
||||
```shell
|
||||
helm upgrade --install gitlab-agent gitlab/gitlab-agent \
|
||||
|
@ -163,7 +163,7 @@ The following example projects can help you get started with the agent.
|
|||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/340882) in GitLab 14.8, GitLab warns you on the agent's list page to update the agent version installed on your cluster.
|
||||
|
||||
For the best experience, the version of the agent installed in your cluster should match the GitLab major and minor version. The previous minor version is also supported. For example, if your GitLab version is v14.9.4 (major version 14, minor version 9), then versions v14.9.0 and v14.9.1 of the agent are ideal, but any v14.8.x version of the agent is also supported. See [this page](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/releases) of releases of the GitLab agent.
|
||||
For the best experience, the version of the agent installed in your cluster should match the GitLab major and minor version. The previous minor version is also supported. For example, if your GitLab version is v14.9.4 (major version 14, minor version 9), then versions v14.9.0 and v14.9.1 of the agent are ideal, but any v14.8.x version of the agent is also supported. See [the release page](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/releases) of the GitLab agent.
|
||||
|
||||
### Update the agent version
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ Introduced in GitLab 13.6, the themes [Solarized](https://gitlab.com/gitlab-org/
|
|||
|
||||
## Diff colors
|
||||
|
||||
A diff compares the old/removed content with the new/added content (e.g. when
|
||||
A diff compares the old/removed content with the new/added content (for example, when
|
||||
[reviewing a merge request](../project/merge_requests/reviews/index.md#review-a-merge-request) or in a
|
||||
[Markdown inline diff](../markdown.md#inline-diff)).
|
||||
Typically, the colors red and green are used for removed and added lines in diffs.
|
||||
|
|
|
@ -128,14 +128,14 @@ module API
|
|||
end
|
||||
params do
|
||||
requires :environment_id, type: Integer, desc: 'The environment ID'
|
||||
optional :force, type: Boolean, default: false
|
||||
end
|
||||
post ':id/environments/:environment_id/stop' do
|
||||
authorize! :read_environment, user_project
|
||||
|
||||
environment = user_project.environments.find(params[:environment_id])
|
||||
authorize! :stop_environment, environment
|
||||
|
||||
environment.stop_with_actions!(current_user)
|
||||
::Environments::StopService.new(user_project, current_user, declared_params(include_missing: false))
|
||||
.execute(environment)
|
||||
|
||||
status 200
|
||||
present environment, with: Entities::Environment, current_user: current_user
|
||||
|
|
|
@ -24,7 +24,7 @@ module QA
|
|||
end
|
||||
|
||||
def enable_ff_only
|
||||
choose_element(:merge_ff_radio)
|
||||
choose_element(:merge_ff_radio, true)
|
||||
click_save_changes
|
||||
end
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ RSpec.describe "User comments on issue", :js do
|
|||
it "edits comment" do
|
||||
add_note("# Comment with a header")
|
||||
|
||||
page.within(".note-body > .note-text") do
|
||||
page.within(".note-body .note-text") do
|
||||
expect(page).to have_content("Comment with a header").and have_no_css("#comment-with-a-header")
|
||||
end
|
||||
|
||||
|
|
|
@ -67,4 +67,24 @@ RSpec.describe 'Math rendering', :js do
|
|||
expect(page).to have_selector('.js-lazy-render-math')
|
||||
end
|
||||
end
|
||||
|
||||
it 'renders without any limits on wiki page', :js do
|
||||
description = <<~MATH
|
||||
```math
|
||||
\Huge \sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
|
||||
```
|
||||
MATH
|
||||
|
||||
wiki_page = build(:wiki_page, { container: project, content: description })
|
||||
wiki_page.create message: 'math test commit' # rubocop:disable Rails/SaveBang
|
||||
wiki_page = project.wiki.find_page(wiki_page.slug)
|
||||
|
||||
visit project_wiki_path(project, wiki_page)
|
||||
|
||||
wait_for_requests
|
||||
|
||||
page.within '.js-wiki-page-content' do
|
||||
expect(page).not_to have_selector('.js-lazy-render-math')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -158,7 +158,7 @@ RSpec.describe 'Merge request > User posts notes', :js do
|
|||
page.within("#note_#{note.id}") do
|
||||
expect(find('.current-note-edit-form', visible: true)).to be_visible
|
||||
expect(find('.note-edit-form', visible: true)).to be_visible
|
||||
expect(find(:css, '.note-body > .note-text', visible: false)).not_to be_visible
|
||||
expect(find(:css, '.note-body .note-text', visible: false)).not_to be_visible
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -284,7 +284,6 @@ RSpec.describe 'Environment' do
|
|||
click_button('Stop')
|
||||
click_button('Stop environment') # confirm modal
|
||||
wait_for_all_requests
|
||||
expect(page).to have_button('Delete')
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -362,8 +361,6 @@ RSpec.describe 'Environment' do
|
|||
end
|
||||
|
||||
visit_environment(environment)
|
||||
|
||||
expect(page).not_to have_button('Stop')
|
||||
end
|
||||
|
||||
##
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { shallowMount } from '@vue/test-utils';
|
||||
import Vuex from 'vuex';
|
||||
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
||||
|
||||
import { suggestionCommitMessage } from '~/diffs/store/getters';
|
||||
import NoteBody from '~/notes/components/note_body.vue';
|
||||
|
@ -7,6 +7,7 @@ import NoteAwardsList from '~/notes/components/note_awards_list.vue';
|
|||
import NoteForm from '~/notes/components/note_form.vue';
|
||||
import createStore from '~/notes/stores';
|
||||
import notes from '~/notes/stores/modules/index';
|
||||
import { CONFIDENTIAL_CLASSES } from '~/notes/constants';
|
||||
|
||||
import Suggestions from '~/vue_shared/components/markdown/suggestions.vue';
|
||||
|
||||
|
@ -27,7 +28,7 @@ const createComponent = ({
|
|||
mockStore.dispatch('setNotesData', notesData);
|
||||
}
|
||||
|
||||
return shallowMount(NoteBody, {
|
||||
return shallowMountExtended(NoteBody, {
|
||||
store: mockStore || store,
|
||||
propsData: {
|
||||
note,
|
||||
|
@ -58,6 +59,24 @@ describe('issue_note_body component', () => {
|
|||
expect(wrapper.findComponent(NoteAwardsList).exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('should not have confidential classes', () => {
|
||||
expect(wrapper.findByTestId('note-confidential-container').classes()).not.toEqual(
|
||||
CONFIDENTIAL_CLASSES,
|
||||
);
|
||||
});
|
||||
|
||||
describe('isConfidential', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = createComponent({ props: { isConfidential: true } });
|
||||
});
|
||||
|
||||
it('should have confidential classes', () => {
|
||||
expect(wrapper.findByTestId('note-confidential-container').classes()).toEqual(
|
||||
CONFIDENTIAL_CLASSES,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isEditing', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = createComponent({ props: { isEditing: true } });
|
||||
|
@ -86,6 +105,18 @@ describe('issue_note_body component', () => {
|
|||
// which is defined in `app/assets/javascripts/notes/mixins/autosave.js`
|
||||
expect(wrapper.vm.autosave.key).toEqual(autosaveKey);
|
||||
});
|
||||
|
||||
describe('isConfidential', () => {
|
||||
beforeEach(() => {
|
||||
wrapper.setProps({ isConfidential: true });
|
||||
});
|
||||
|
||||
it('should not have confidential classes', () => {
|
||||
expect(wrapper.findByTestId('note-confidential-container').classes()).not.toEqual(
|
||||
CONFIDENTIAL_CLASSES,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('commitMessage', () => {
|
||||
|
|
|
@ -586,6 +586,24 @@ RSpec.describe Environment, :use_clean_rails_memory_store_caching do
|
|||
expect(action).to eq(close_action)
|
||||
expect(action.user).to eq(user)
|
||||
end
|
||||
|
||||
context 'env_stopped_on_stop_success feature flag' do
|
||||
it 'environment is not stopped when flag is enabled' do
|
||||
stub_feature_flags(env_stopped_on_stop_success: true)
|
||||
|
||||
subject
|
||||
|
||||
expect(environment).not_to be_stopped
|
||||
end
|
||||
|
||||
it 'environment is stopped when flag is disabled' do
|
||||
stub_feature_flags(env_stopped_on_stop_success: false)
|
||||
|
||||
subject
|
||||
|
||||
expect(environment).to be_stopped
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'if action did finish' do
|
||||
|
@ -1730,17 +1748,17 @@ RSpec.describe Environment, :use_clean_rails_memory_store_caching do
|
|||
let!(:environment3) { create(:environment, project: project, state: 'stopped') }
|
||||
|
||||
it 'returns the environments count grouped by state' do
|
||||
expect(project.environments.count_by_state).to eq({ stopped: 2, available: 1 })
|
||||
expect(project.environments.count_by_state).to eq({ stopped: 2, available: 1, stopping: 0 })
|
||||
end
|
||||
|
||||
it 'returns the environments count grouped by state with zero value' do
|
||||
environment2.update!(state: 'stopped')
|
||||
expect(project.environments.count_by_state).to eq({ stopped: 3, available: 0 })
|
||||
expect(project.environments.count_by_state).to eq({ stopped: 3, available: 0, stopping: 0 })
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns zero state counts when environments are empty' do
|
||||
expect(project.environments.count_by_state).to eq({ stopped: 0, available: 0 })
|
||||
expect(project.environments.count_by_state).to eq({ stopped: 0, available: 0, stopping: 0 })
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -254,8 +254,6 @@ RSpec.describe RemoteMirror, :mailer do
|
|||
it 'does not remove the remote' do
|
||||
mirror = create_mirror(url: 'http://foo:bar@test.com')
|
||||
|
||||
expect(RepositoryRemoveRemoteWorker).not_to receive(:perform_async)
|
||||
|
||||
mirror.destroy!
|
||||
end
|
||||
end
|
||||
|
|
|
@ -84,7 +84,7 @@ RSpec.describe Deployments::UpdateEnvironmentService do
|
|||
|
||||
context 'and environment is stopped' do
|
||||
before do
|
||||
environment.stop
|
||||
environment.stop_complete
|
||||
end
|
||||
|
||||
it 'makes environment available' do
|
||||
|
|
|
@ -37,7 +37,7 @@ RSpec.describe Environments::AutoStopService, :clean_gitlab_redis_shared_state,
|
|||
it 'stops environments and play stop jobs' do
|
||||
expect { subject }
|
||||
.to change { Environment.all.map(&:state).uniq }
|
||||
.from(['available']).to(['stopped'])
|
||||
.from(['available']).to(['stopping'])
|
||||
|
||||
expect(Ci::Build.where(name: 'stop_review_app').map(&:status).uniq).to eq(['pending'])
|
||||
end
|
||||
|
|
|
@ -29,14 +29,27 @@ RSpec.describe Environments::StopService do
|
|||
review_job.success!
|
||||
end
|
||||
|
||||
it 'stops the environment' do
|
||||
expect { subject }.to change { environment.reload.state }.from('available').to('stopped')
|
||||
context 'without stop action' do
|
||||
let!(:environment) { create(:environment, :available, project: project) }
|
||||
|
||||
it 'stops the environment' do
|
||||
expect { subject }.to change { environment.reload.state }.from('available').to('stopped')
|
||||
end
|
||||
end
|
||||
|
||||
it 'plays the stop action' do
|
||||
expect { subject }.to change { stop_review_job.reload.status }.from('manual').to('pending')
|
||||
end
|
||||
|
||||
context 'force option' do
|
||||
let(:service) { described_class.new(project, user, { force: true }) }
|
||||
|
||||
it 'does not play the stop action when forced' do
|
||||
expect { subject }.to change { environment.reload.state }.from('available').to('stopped')
|
||||
expect(stop_review_job.reload.status).to eq('manual')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when an environment has already been stopped' do
|
||||
let!(:environment) { create(:environment, :stopped, project: project) }
|
||||
|
||||
|
@ -77,7 +90,7 @@ RSpec.describe Environments::StopService do
|
|||
|
||||
context 'when environment is associated with removed branch' do
|
||||
it 'stops environment' do
|
||||
expect_environment_stopped_on('feature')
|
||||
expect_environment_stopping_on('feature')
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -195,8 +208,7 @@ RSpec.describe Environments::StopService do
|
|||
|
||||
it 'stops the active environment' do
|
||||
subject
|
||||
|
||||
expect(pipeline.environments_in_self_and_descendants.first).to be_stopped
|
||||
expect(pipeline.environments_in_self_and_descendants.first).to be_stopping
|
||||
end
|
||||
|
||||
context 'when pipeline is a branch pipeline for merge request' do
|
||||
|
@ -268,6 +280,11 @@ RSpec.describe Environments::StopService do
|
|||
.to change { Environment.last.state }.from('available').to('stopped')
|
||||
end
|
||||
|
||||
def expect_environment_stopping_on(branch)
|
||||
expect { service.execute_for_branch(branch) }
|
||||
.to change { Environment.last.state }.from('available').to('stopping')
|
||||
end
|
||||
|
||||
def expect_environment_not_stopped_on(branch)
|
||||
expect { service.execute_for_branch(branch) }
|
||||
.not_to change { Environment.last.state }
|
||||
|
|
|
@ -8,7 +8,7 @@ RSpec.describe BuildSuccessWorker do
|
|||
|
||||
context 'when build exists' do
|
||||
context 'when the build will stop an environment' do
|
||||
let!(:build) { create(:ci_build, :stop_review_app, environment: environment.name, project: environment.project) }
|
||||
let!(:build) { create(:ci_build, :stop_review_app, environment: environment.name, project: environment.project, status: :success) }
|
||||
let(:environment) { create(:environment, state: :available) }
|
||||
|
||||
it 'stops the environment' do
|
||||
|
@ -18,6 +18,33 @@ RSpec.describe BuildSuccessWorker do
|
|||
|
||||
expect(environment.reload).to be_stopped
|
||||
end
|
||||
|
||||
context 'when the build fails' do
|
||||
before do
|
||||
build.update!(status: :failed)
|
||||
environment.update!(state: :available)
|
||||
end
|
||||
|
||||
it 'does not stop the environment' do
|
||||
expect(environment).to be_available
|
||||
|
||||
stub_feature_flags(env_stopped_on_stop_success: true)
|
||||
|
||||
subject
|
||||
|
||||
expect(environment.reload).not_to be_stopped
|
||||
end
|
||||
|
||||
it 'does stop the environment when feature flag is disabled' do
|
||||
expect(environment).to be_available
|
||||
|
||||
stub_feature_flags(env_stopped_on_stop_success: false)
|
||||
|
||||
subject
|
||||
|
||||
expect(environment.reload).to be_stopped
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ RSpec.describe Environments::AutoStopWorker do
|
|||
it 'stops the environment' do
|
||||
expect { subject }
|
||||
.to change { Environment.find_by_name('review/feature').state }
|
||||
.from('available').to('stopped')
|
||||
.from('available').to('stopping')
|
||||
end
|
||||
|
||||
it 'executes the stop action' do
|
||||
|
|
|
@ -410,7 +410,6 @@ RSpec.describe 'Every Sidekiq worker' do
|
|||
'RepositoryCleanupWorker' => 3,
|
||||
'RepositoryForkWorker' => 5,
|
||||
'RepositoryImportWorker' => false,
|
||||
'RepositoryRemoveRemoteWorker' => 3,
|
||||
'RepositoryUpdateMirrorWorker' => false,
|
||||
'RepositoryPushAuditEventWorker' => 3,
|
||||
'RepositoryUpdateRemoteMirrorWorker' => 3,
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe RepositoryRemoveRemoteWorker do
|
||||
include ExclusiveLeaseHelpers
|
||||
include GitHelpers
|
||||
|
||||
describe '#perform' do
|
||||
let!(:project) { create(:project, :repository) }
|
||||
let(:remote_name) { 'joe'}
|
||||
let(:lease_key) { "remove_remote_#{project.id}_#{remote_name}" }
|
||||
let(:lease_timeout) { RepositoryRemoveRemoteWorker::LEASE_TIMEOUT }
|
||||
|
||||
it 'returns nil when project does not exist' do
|
||||
expect(subject.perform(-1, 'remote_name')).to be_nil
|
||||
end
|
||||
|
||||
context 'when project exists' do
|
||||
before do
|
||||
allow(Project)
|
||||
.to receive(:find_by)
|
||||
.with(id: project.id)
|
||||
.and_return(project)
|
||||
end
|
||||
|
||||
it 'does nothing when cannot obtain lease' do
|
||||
stub_exclusive_lease_taken(lease_key, timeout: lease_timeout)
|
||||
|
||||
expect(project.repository)
|
||||
.not_to receive(:remove_remote)
|
||||
expect(subject)
|
||||
.not_to receive(:log_error)
|
||||
|
||||
subject.perform(project.id, remote_name)
|
||||
end
|
||||
|
||||
it 'does nothing when obtain a lease' do
|
||||
stub_exclusive_lease(lease_key, timeout: lease_timeout)
|
||||
|
||||
expect(project.repository)
|
||||
.not_to receive(:remove_remote)
|
||||
|
||||
subject.perform(project.id, remote_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue