Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
75a95cff04
commit
ff961c5927
|
|
@ -280,7 +280,6 @@ Lint/RedundantCopDisableDirective:
|
|||
- 'lib/gitlab/background_migration/destroy_invalid_project_members.rb'
|
||||
- 'lib/gitlab/background_migration/fix_first_mentioned_in_commit_at.rb'
|
||||
- 'lib/gitlab/background_migration/fix_namespace_ids_of_vulnerability_reads.rb'
|
||||
- 'lib/gitlab/background_migration/fix_vulnerability_reads_has_issues.rb'
|
||||
- 'lib/gitlab/background_migration/mailers/unconfirm_mailer.rb'
|
||||
- 'lib/gitlab/background_migration/migrate_approver_to_approval_rules.rb'
|
||||
- 'lib/gitlab/background_migration/migrate_approver_to_approval_rules_check_progress.rb'
|
||||
|
|
@ -404,7 +403,6 @@ Lint/RedundantCopDisableDirective:
|
|||
- 'spec/lib/gitlab/background_migration/batching_strategies/backfill_project_statistics_with_container_registry_size_batching_strategy_spec.rb'
|
||||
- 'spec/lib/gitlab/background_migration/convert_credit_card_validation_data_to_hashes_spec.rb'
|
||||
- 'spec/lib/gitlab/background_migration/drop_vulnerabilities_without_finding_id_spec.rb'
|
||||
- 'spec/lib/gitlab/background_migration/fix_vulnerability_reads_has_issues_spec.rb'
|
||||
- 'spec/lib/gitlab/background_migration/populate_vulnerability_dismissal_fields_spec.rb'
|
||||
- 'spec/lib/gitlab/background_migration/resolve_vulnerabilities_for_removed_analyzers_spec.rb'
|
||||
- 'spec/lib/gitlab/ci/parsers/security/validators/schema_validator_spec.rb'
|
||||
|
|
|
|||
|
|
@ -2020,7 +2020,6 @@ Style/InlineDisableAnnotation:
|
|||
- 'lib/gitlab/background_migration/fix_first_mentioned_in_commit_at.rb'
|
||||
- 'lib/gitlab/background_migration/fix_namespace_ids_of_vulnerability_reads.rb'
|
||||
- 'lib/gitlab/background_migration/fix_projects_without_prometheus_service.rb'
|
||||
- 'lib/gitlab/background_migration/fix_vulnerability_reads_has_issues.rb'
|
||||
- 'lib/gitlab/background_migration/job_coordinator.rb'
|
||||
- 'lib/gitlab/background_migration/legacy_upload_mover.rb'
|
||||
- 'lib/gitlab/background_migration/mailers/unconfirm_mailer.rb'
|
||||
|
|
@ -2520,7 +2519,6 @@ Style/InlineDisableAnnotation:
|
|||
- 'spec/lib/gitlab/background_migration/delete_orphans_approval_merge_request_rules2_spec.rb'
|
||||
- 'spec/lib/gitlab/background_migration/delete_orphans_approval_project_rules2_spec.rb'
|
||||
- 'spec/lib/gitlab/background_migration/destroy_invalid_members_spec.rb'
|
||||
- 'spec/lib/gitlab/background_migration/fix_vulnerability_reads_has_issues_spec.rb'
|
||||
- 'spec/lib/gitlab/background_migration/legacy_upload_mover_spec.rb'
|
||||
- 'spec/lib/gitlab/background_migration/legacy_uploads_migrator_spec.rb'
|
||||
- 'spec/lib/gitlab/background_migration/populate_vulnerability_dismissal_fields_spec.rb'
|
||||
|
|
|
|||
|
|
@ -186,7 +186,8 @@ export default {
|
|||
return this.$apollo.queries.environments.loading;
|
||||
},
|
||||
areHiddenVariablesAvailable() {
|
||||
return Boolean(this.entity && this.glFeatures?.ciHiddenVariables);
|
||||
// group and project variables can be hidden, instance variables cannot
|
||||
return Boolean(this.entity);
|
||||
},
|
||||
hasEnvScopeQuery() {
|
||||
return Boolean(this.queryData?.environments?.query);
|
||||
|
|
|
|||
|
|
@ -234,7 +234,7 @@ export default {
|
|||
</div>
|
||||
<diff-row
|
||||
v-if="!line.isMatchLineLeft && !line.isMatchLineRight"
|
||||
:key="line.line_code"
|
||||
:key="line.lineCode"
|
||||
:file-hash="diffFile.file_hash"
|
||||
:file-path="diffFile.file_path"
|
||||
:line="line"
|
||||
|
|
@ -261,7 +261,7 @@ export default {
|
|||
/>
|
||||
<div
|
||||
v-if="line.renderCommentRow"
|
||||
:key="`dcr-${line.line_code || index}`"
|
||||
:key="`dcr-${line.lineCode}`"
|
||||
:class="line.commentRowClasses"
|
||||
class="diff-grid-comments diff-tr notes_holder"
|
||||
>
|
||||
|
|
@ -297,7 +297,7 @@ export default {
|
|||
</div>
|
||||
<div
|
||||
v-if="shouldRenderParallelDraftRow(diffFile.file_hash, line)"
|
||||
:key="`drafts-${index}`"
|
||||
:key="`drafts-${line.lineCode}`"
|
||||
:class="line.draftRowClasses"
|
||||
class="diff-grid-drafts diff-tr notes_holder"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -101,8 +101,10 @@ export default {
|
|||
}
|
||||
},
|
||||
onSearchInput() {
|
||||
this.$refs.virtualScoller.setScrollTop(0);
|
||||
this.$refs.virtualScoller.forceRender();
|
||||
if (this.$refs.virtualScoller) {
|
||||
this.$refs.virtualScoller.setScrollTop(0);
|
||||
this.$refs.virtualScoller.forceRender();
|
||||
}
|
||||
},
|
||||
async onScroll(event, { offset }) {
|
||||
const categories = await getEmojiCategories();
|
||||
|
|
@ -111,8 +113,6 @@ export default {
|
|||
},
|
||||
onShow() {
|
||||
this.isVisible = true;
|
||||
this.$refs.searchValue.focusInput();
|
||||
|
||||
this.$emit('shown');
|
||||
},
|
||||
onHide() {
|
||||
|
|
@ -166,7 +166,7 @@ export default {
|
|||
</gl-button>
|
||||
</template>
|
||||
|
||||
<template #header>
|
||||
<template v-if="isVisible" #header>
|
||||
<gl-search-box-by-type
|
||||
ref="searchValue"
|
||||
v-model="searchValue"
|
||||
|
|
@ -180,6 +180,7 @@ export default {
|
|||
</template>
|
||||
|
||||
<div
|
||||
v-if="isVisible"
|
||||
v-show="!searchValue"
|
||||
class="award-list gl-flex gl-border-b-1 gl-border-gray-100 gl-border-b-solid"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -3,18 +3,15 @@
|
|||
module RendersBlob
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def blob_json(blob)
|
||||
viewer =
|
||||
case params[:viewer]
|
||||
when 'rich'
|
||||
blob.rich_viewer
|
||||
when 'auxiliary'
|
||||
blob.auxiliary_viewer
|
||||
else
|
||||
blob.simple_viewer
|
||||
end
|
||||
def blob_viewer_json(blob)
|
||||
viewer = case params[:viewer]
|
||||
when 'rich' then blob.rich_viewer
|
||||
when 'auxiliary' then blob.auxiliary_viewer
|
||||
when 'none' then nil
|
||||
else blob.simple_viewer
|
||||
end
|
||||
|
||||
return unless viewer
|
||||
return {} unless viewer
|
||||
|
||||
{
|
||||
html: view_to_html_string("projects/blob/_viewer", viewer: viewer, load_async: false)
|
||||
|
|
@ -22,8 +19,8 @@ module RendersBlob
|
|||
end
|
||||
|
||||
def render_blob_json(blob)
|
||||
json = blob_json(blob)
|
||||
return render_404 unless json
|
||||
json = blob_viewer_json(blob)
|
||||
return render_404 unless json.present?
|
||||
|
||||
render json: json
|
||||
end
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ module Groups
|
|||
|
||||
before_action do
|
||||
push_frontend_feature_flag(:ci_variables_pages, current_user)
|
||||
push_frontend_feature_flag(:ci_hidden_variables, group)
|
||||
end
|
||||
|
||||
urgency :low
|
||||
|
|
|
|||
|
|
@ -28,10 +28,10 @@ class Projects::BlobController < Projects::ApplicationController
|
|||
|
||||
before_action :authorize_edit_tree!, only: [:new, :create, :update, :destroy]
|
||||
|
||||
before_action :commit, except: [:new, :create]
|
||||
before_action :require_commit, except: [:new, :create]
|
||||
before_action :set_is_ambiguous_ref, only: [:show]
|
||||
before_action :check_for_ambiguous_ref, only: [:show]
|
||||
before_action :blob, except: [:new, :create]
|
||||
before_action :require_blob, except: [:new, :create]
|
||||
before_action :require_branch_head, only: [:edit, :update]
|
||||
before_action :editor_variables, except: [:show, :preview, :diff]
|
||||
before_action :validate_diff_params, only: :diff
|
||||
|
|
@ -62,7 +62,7 @@ class Projects::BlobController < Projects::ApplicationController
|
|||
end
|
||||
|
||||
def show
|
||||
conditionally_expand_blob(@blob)
|
||||
conditionally_expand_blob(blob)
|
||||
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
|
|
@ -70,8 +70,8 @@ class Projects::BlobController < Projects::ApplicationController
|
|||
end
|
||||
|
||||
format.json do
|
||||
page_title @blob.path, @ref, @project.full_name
|
||||
|
||||
page_title blob.path, @ref, @project.full_name
|
||||
set_last_commit_sha
|
||||
show_json
|
||||
end
|
||||
end
|
||||
|
|
@ -102,8 +102,8 @@ class Projects::BlobController < Projects::ApplicationController
|
|||
|
||||
def preview
|
||||
@content = params[:content]
|
||||
@blob.load_all_data!
|
||||
diffy = Diffy::Diff.new(@blob.data, @content, diff: '-U 3', include_diff_info: true)
|
||||
blob.load_all_data!
|
||||
diffy = Diffy::Diff.new(blob.data, @content, diff: '-U 3', include_diff_info: true)
|
||||
diff_lines = diffy.diff.scan(/.*\n/)[2..]
|
||||
diff_lines = Gitlab::Diff::Parser.new.parse(diff_lines).to_a
|
||||
@diff_lines = Gitlab::Diff::Highlight.new(diff_lines, repository: @repository).highlight
|
||||
|
|
@ -139,17 +139,22 @@ class Projects::BlobController < Projects::ApplicationController
|
|||
attr_reader :branch_name
|
||||
|
||||
def blob
|
||||
@blob ||= @repository.blob_at(@commit.id, @path)
|
||||
return unless commit
|
||||
|
||||
if @blob
|
||||
@blob
|
||||
else
|
||||
if tree = @repository.tree(@commit.id, @path)
|
||||
return redirect_to project_tree_path(@project, File.join(@ref, @path)) if tree.entries.any?
|
||||
end
|
||||
@blob = @repository.blob_at(commit.id, @path)
|
||||
end
|
||||
strong_memoize_attr :blob
|
||||
|
||||
redirect_to_tree_root_for_missing_path(@project, @ref, @path)
|
||||
def require_blob
|
||||
redirect_to_project_tree_path unless blob
|
||||
end
|
||||
|
||||
def redirect_to_project_tree_path
|
||||
if @repository.tree(commit.id, @path).entries.any?
|
||||
return redirect_to(project_tree_path(@project, File.join(@ref, @path)))
|
||||
end
|
||||
|
||||
redirect_to_tree_root_for_missing_path(@project, @ref, @path)
|
||||
end
|
||||
|
||||
def check_for_ambiguous_ref
|
||||
|
|
@ -157,9 +162,12 @@ class Projects::BlobController < Projects::ApplicationController
|
|||
end
|
||||
|
||||
def commit
|
||||
@commit ||= @repository.commit(@ref)
|
||||
@commit = @repository.commit(@ref)
|
||||
end
|
||||
strong_memoize_attr :commit
|
||||
|
||||
render_404 unless @commit
|
||||
def require_commit
|
||||
render_404 unless commit
|
||||
end
|
||||
|
||||
def redirect_renamed_default_branch?
|
||||
|
|
@ -241,20 +249,18 @@ class Projects::BlobController < Projects::ApplicationController
|
|||
end
|
||||
|
||||
def show_html
|
||||
environment_params = @repository.branch_exists?(@ref) ? { ref: @ref } : { commit: @commit }
|
||||
environment_params = @repository.branch_exists?(@ref) ? { ref: @ref } : { commit: commit }
|
||||
environment_params[:find_latest] = true
|
||||
@environment = ::Environments::EnvironmentsByDeploymentsFinder.new(@project, current_user, environment_params).execute.last
|
||||
@last_commit = @repository.last_commit_for_path(@commit.id, @blob.path, literal_pathspec: true)
|
||||
@code_navigation_path = Gitlab::CodeNavigationPath.new(@project, @blob.commit_id).full_json_path_for(@blob.path)
|
||||
@last_commit = @repository.last_commit_for_path(commit.id, blob.path, literal_pathspec: true)
|
||||
@code_navigation_path = Gitlab::CodeNavigationPath.new(@project, blob.commit_id).full_json_path_for(blob.path)
|
||||
|
||||
render 'show'
|
||||
end
|
||||
|
||||
def show_json
|
||||
set_last_commit_sha
|
||||
|
||||
json = {
|
||||
id: @blob.id,
|
||||
json = blob_viewer_json(blob).merge(
|
||||
id: blob.id,
|
||||
last_commit_sha: @last_commit_sha,
|
||||
path: blob.path,
|
||||
name: blob.name,
|
||||
|
|
@ -270,10 +276,8 @@ class Projects::BlobController < Projects::ApplicationController
|
|||
blame_path: project_blame_path(project, @id),
|
||||
commits_path: project_commits_path(project, @id),
|
||||
tree_path: project_tree_path(project, File.join(@ref, tree_path)),
|
||||
permalink: project_blob_path(project, File.join(@commit.id, @path))
|
||||
}
|
||||
|
||||
json.merge!(blob_json(@blob) || {}) unless params[:viewer] == 'none'
|
||||
permalink: project_blob_path(project, File.join(commit.id, @path))
|
||||
)
|
||||
|
||||
render json: json
|
||||
end
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ module Projects
|
|||
before_action do
|
||||
push_frontend_feature_flag(:ci_variables_pages, current_user)
|
||||
push_frontend_feature_flag(:allow_push_repository_for_job_token, @project)
|
||||
push_frontend_feature_flag(:ci_hidden_variables, @project.root_ancestor)
|
||||
|
||||
push_frontend_ability(ability: :admin_project, resource: @project, user: current_user)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -9,26 +9,11 @@ module Ci
|
|||
end
|
||||
|
||||
def evaluate
|
||||
return variable.value if hidden_variables_feature_flag_is_disabled?
|
||||
|
||||
variable.hidden? ? nil : variable.value
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# This logic will go away on the ff `ci_hidden_variables` deprecation
|
||||
def hidden_variables_feature_flag_is_disabled?
|
||||
parent = if variable.is_a?(Ci::Variable)
|
||||
variable.project&.root_ancestor
|
||||
elsif variable.is_a?(Ci::GroupVariable)
|
||||
variable.group
|
||||
end
|
||||
|
||||
return true unless parent
|
||||
|
||||
::Feature.disabled?(:ci_hidden_variables, parent)
|
||||
end
|
||||
|
||||
attr_reader :variable
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -13,14 +13,12 @@ module Ci
|
|||
private
|
||||
|
||||
def validate_masked_and_hidden_on_create
|
||||
return if hidden_variables_feature_flag_is_disabled?
|
||||
return unless masked == false && hidden == true
|
||||
|
||||
errors.add(:masked, 'should be true when variable is hidden')
|
||||
end
|
||||
|
||||
def validate_masked_and_hidden_on_update
|
||||
return if hidden_variables_feature_flag_is_disabled?
|
||||
return if !masked_changed? && !hidden_changed?
|
||||
return if hidden == false && !hidden_changed?
|
||||
|
||||
|
|
@ -30,18 +28,5 @@ module Ci
|
|||
errors.add(:base, 'Updating masked attribute is not allowed on updates for hidden variables.')
|
||||
end
|
||||
end
|
||||
|
||||
# This logic will go away on the ff `ci_hidden_variables` deprecation
|
||||
def hidden_variables_feature_flag_is_disabled?
|
||||
parent = if is_a?(Ci::Variable)
|
||||
project&.root_ancestor
|
||||
elsif is_a?(Ci::GroupVariable)
|
||||
group
|
||||
end
|
||||
|
||||
return true unless parent
|
||||
|
||||
::Feature.disabled?(:ci_hidden_variables, parent)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ module MirrorAuthentication
|
|||
end
|
||||
|
||||
def ssh_known_hosts_verified_by
|
||||
@ssh_known_hosts_verified_by ||= ::User.find_by(id: ssh_known_hosts_verified_by_id)
|
||||
@ssh_known_hosts_verified_by ||= user_by_ssh_known_hosts_verified_by_id
|
||||
end
|
||||
|
||||
def ssh_known_hosts_fingerprints
|
||||
|
|
@ -85,4 +85,12 @@ module MirrorAuthentication
|
|||
def generate_ssh_private_key!
|
||||
self.ssh_private_key = SSHData::PrivateKey::RSA.generate(4096).openssl.to_pem
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def user_by_ssh_known_hosts_verified_by_id
|
||||
return unless ssh_known_hosts_verified_by_id
|
||||
|
||||
::User.find_by(id: ssh_known_hosts_verified_by_id)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
- hidden_variables_enabled = (@group.present? && Feature.enabled?(:ci_hidden_variables, @group)) || (@project.present? && Feature.enabled?(:ci_hidden_variables, @project.group))
|
||||
|
||||
%p
|
||||
= s_('CiVariables|Variables can be accidentally exposed in a job log, or maliciously sent to a third party server. The masked variable feature can help reduce the risk of accidentally exposing variable values, but is not a guaranteed method to prevent malicious users from accessing variables.')
|
||||
= link_to _('How can I make my variables more secure?'), help_page_path('ci/variables/index.md', anchor: 'cicd-variable-security'), target: '_blank', rel: 'noopener noreferrer'
|
||||
%p
|
||||
= s_('CiVariables|Variables can have several attributes.')
|
||||
= link_to _('Learn more.'), help_page_path('ci/variables/index.md', anchor: 'define-a-cicd-variable-in-the-ui'), target: '_blank', rel: 'noopener noreferrer'
|
||||
- if hidden_variables_enabled
|
||||
- if @group.present? || @project.present?
|
||||
%ul
|
||||
%li
|
||||
= safe_format(s_('CiVariables|%{strong_start}Visibility:%{strong_end} Set the visibility level for the value. Can be visible, masked, or masked and hidden.'), tag_pair(tag.strong, :strong_start, :strong_end))
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: ci_hidden_variables
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/141926
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/451326
|
||||
milestone: '16.11'
|
||||
type: development
|
||||
group: group::pipeline security
|
||||
default_enabled: true
|
||||
|
|
@ -330,10 +330,7 @@ Different versions of [GitLab Runner](../runners/index.md) have different maskin
|
|||
### Hide a CI/CD variable
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/29674) in GitLab 17.4 [with a flag](../../administration/feature_flags.md) named `ci_hidden_variables`. Enabled by default.
|
||||
|
||||
FLAG:
|
||||
The availability of this feature is controlled by a feature flag.
|
||||
For more information, see the history.
|
||||
> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/165843) in GitLab 17.6. Feature flag `ci_hidden_variables` removed.
|
||||
|
||||
In addition to masking, you can also prevent the value of CI/CD variables from being revealed
|
||||
in the **CI/CD** settings page. Hiding a variable is only possible when creating a new variable,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
stage: AI-powered
|
||||
group: AI Framework
|
||||
group: Duo Workflow
|
||||
info: Any user with at least the Maintainer role can merge updates to this content. For details, see https://docs.gitlab.com/ee/development/development_processes.html#development-guidelines-review.
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,20 @@ GitLab Duo inline in your current file.
|
|||
|
||||
To learn more, see the [documentation for Code Suggestions](../../user/project/repository/code_suggestions/index.md).
|
||||
|
||||
### Configure more languages for Code Suggestions
|
||||
|
||||
To add more languages to Code Suggestions:
|
||||
|
||||
1. Find your desired language in the list of
|
||||
[language identifiers](https://code.visualstudio.com/docs/languages/identifiers#_known-language-identifiers)
|
||||
for VS Code. You need the **Identifier** for a later step.
|
||||
1. In VS Code, open the extension settings for **GitLab Workflow**:
|
||||
1. On the top bar, go to **Code > Settings > Extensions**.
|
||||
1. Search for **GitLab Workflow** in the list, then select **Manage** (**{settings}**) **> Extension Settings**.
|
||||
1. In your **User** settings, find
|
||||
**GitLab › Duo Code Suggestions: Additional Languages** and select **Add Item**.
|
||||
1. In **Item**, add the language identifier, and select **OK**.
|
||||
|
||||
## Set up the GitLab Workflow extension
|
||||
|
||||
This extension requires you to create a GitLab personal access token, and assign it to the extension:
|
||||
|
|
@ -45,7 +59,7 @@ This extension requires you to create a GitLab personal access token, and assign
|
|||
- When manually adding an instance to **URL to GitLab instance**, paste the full URL to your
|
||||
GitLab instance, including the `http://` or `https://`. Press <kbd>Enter</kbd> to confirm.
|
||||
1. For `GitLab.com`, you can use the OAuth authentication method.
|
||||
1. If you don't use OAuth, use a personal access token to log in.
|
||||
1. If you don't use OAuth, use a personal access token to sign in.
|
||||
- If you have an existing personal access token with `api` scope, select **Enter an existing token** to enter it.
|
||||
- If you don't, select **Create a token first**, and the extension opens the token settings page for you.
|
||||
If this method fails, follow the instructions to [create a personal access token](../../user/profile/personal_access_tokens.md#create-a-personal-access-token).
|
||||
|
|
@ -81,20 +95,6 @@ or **Accept Next Line Of Inline Suggestion**:
|
|||
or **Accept Next Line Of Inline Suggestion**.
|
||||
1. Press <kbd>Enter</kbd> to save your changes.
|
||||
|
||||
## Configure more languages for Code Suggestions
|
||||
|
||||
To add more languages to Code Suggestions:
|
||||
|
||||
1. Find your desired language in the list of
|
||||
[language identifiers](https://code.visualstudio.com/docs/languages/identifiers#_known-language-identifiers)
|
||||
for VS Code. You need the **Identifier** for a later step.
|
||||
1. In VS Code, open the extension settings for **GitLab Workflow**:
|
||||
1. On the top bar, go to **Code > Settings > Extensions**.
|
||||
1. Search for **GitLab Workflow** in the list, then select **Manage** (**{settings}**) **> Extension Settings**.
|
||||
1. In your **User** settings, find
|
||||
**GitLab › Duo Code Suggestions: Additional Languages** and select **Add Item**.
|
||||
1. In **Item**, add the language identifier, and select **OK**.
|
||||
|
||||
## Integrate with GitLab
|
||||
|
||||
This extension brings the GitLab features you use every day directly into your VS Code environment:
|
||||
|
|
@ -114,6 +114,59 @@ This extension brings the GitLab features you use every day directly into your V
|
|||
|
||||
For detailed information on these features, refer to the [GitLab Workflow extension documentation](https://gitlab.com/gitlab-org/gitlab-vscode-extension/-/blob/main/README.md).
|
||||
|
||||
## Create a snippet
|
||||
|
||||
Create a [snippet](../../user/snippets.md) to store and share bits of code and text with other users.
|
||||
Snippets can be a selection or an entire file.
|
||||
|
||||
To create a snippet in VS Code:
|
||||
|
||||
1. Choose the content for your snippet:
|
||||
- For a **Snippet from file**, open the file.
|
||||
- For a **Snippet from selection**, open the file and select the lines you want to include.
|
||||
1. Open the Command Palette:
|
||||
- For macOS, press <kbd>Command</kbd>+<kbd>Shift</kbd>+<kbd>P</kbd>.
|
||||
- For Windows or Linux, press <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>P</kbd>.
|
||||
1. In the command palette, run the command `GitLab: Create Snippet`.
|
||||
1. Select the snippet's privacy level:
|
||||
- **Private** snippets are visible only to project members.
|
||||
- **Public** snippets are visible to everyone.
|
||||
1. Select the snippet's scope:
|
||||
- **Snippet from file** uses the entire contents of the active file.
|
||||
- **Snippet from selection** uses the lines you selected in the active file.
|
||||
|
||||
GitLab opens the new snippet's page in a new browser tab.
|
||||
|
||||
### Create a patch file
|
||||
|
||||
When you review a merge request, create a snippet patch when you want to suggest multi-file changes.
|
||||
|
||||
1. On your local machine, check out the branch you want to propose changes to.
|
||||
1. In VS Code, edit all files you want to change. Do not commit your changes.
|
||||
1. Open the Command Palette, enter `GitLab: Create snippet patch`, and select it. This command runs a
|
||||
`git diff` command and creates a GitLab snippet in your project.
|
||||
1. Enter a **Patch name** and press <kbd>Enter</kbd>. GitLab uses this name as the
|
||||
snippet title, and converts it into a filename appended with `.patch`.
|
||||
1. Select the snippet's privacy level:
|
||||
- **Private** snippets are visible only to project members.
|
||||
- **Public** snippets are visible to everyone.
|
||||
|
||||
VS Code opens the snippet patch in a new browser tab. The snippet patch's
|
||||
description contains instructions on how to apply the patch.
|
||||
|
||||
### Insert a snippet
|
||||
|
||||
To insert an existing single-file or [multi-file](../../user/snippets.md#add-or-remove-multiple-files) snippet from a project you are a member of:
|
||||
|
||||
1. Place your cursor where you want to insert the snippet.
|
||||
1. Open the Command Palette:
|
||||
- For macOS, press <kbd>Command</kbd>+<kbd>Shift</kbd>+<kbd>P</kbd>.
|
||||
- For Windows or Linux, press <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>P</kbd>.
|
||||
1. Type `GitLab: Insert Snippet` and select it.
|
||||
1. Select the project containing your snippet.
|
||||
1. Select the snippet to apply.
|
||||
1. For a multi-file snippet, select the file to apply.
|
||||
|
||||
## Related topics
|
||||
|
||||
- [Download the GitLab Workflow extension](https://marketplace.visualstudio.com/items?itemName=GitLab.gitlab-workflow)
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ If you cannot [provide GitLab with your Jenkins server URL and authentication in
|
|||
1. Under **Secret Token**, select **Generate**.
|
||||
1. Copy the token, and save the job configuration.
|
||||
1. In GitLab:
|
||||
- [Create a webhook for your project](../user/project/integrations/webhooks.md#configure-webhooks-in-gitlab).
|
||||
- [Create a webhook for your project](../user/project/integrations/webhooks.md#configure-webhooks).
|
||||
- Enter the trigger URL (such as `https://JENKINS_URL/project/YOUR_JOB`).
|
||||
- Paste the token in **Secret Token**.
|
||||
1. To test the webhook, select **Test**.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
stage: AI-powered
|
||||
group: AI Framework
|
||||
group: Duo Workflow
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ an internal list of certificate authorities. The SSL certificate cannot
|
|||
be self-signed.
|
||||
|
||||
You can disable SSL verification when you configure
|
||||
[webhooks](webhooks.md#configure-webhooks-in-gitlab) and some integrations.
|
||||
[webhooks](webhooks.md#configure-webhooks) and some integrations.
|
||||
|
||||
## Related topics
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,12 @@ specific to a group, including:
|
|||
- [Group member events](webhook_events.md#group-member-events)
|
||||
- [Subgroup events](webhook_events.md#subgroup-events)
|
||||
|
||||
## Configure webhooks in GitLab
|
||||
## Configure webhooks
|
||||
|
||||
Create and configure webhooks in GitLab to integrate with your project's workflow.
|
||||
|
||||
This section covers creating webhooks, securing sensitive information, adding custom headers, using templates, and
|
||||
filtering events. Use these options to set up webhooks that meet your specific requirements.
|
||||
|
||||
### Create a webhook
|
||||
|
||||
|
|
@ -172,289 +177,9 @@ You can filter push events by branch. Use one of the following options to filter
|
|||
```
|
||||
|
||||
To configure branch filtering for a project or group, see
|
||||
[Configure a webhook in GitLab](#configure-webhooks-in-gitlab)
|
||||
[Configure a webhook in GitLab](#configure-webhooks)
|
||||
|
||||
## View webhook request history
|
||||
|
||||
> - **Recent events** for group webhooks [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/325642) in GitLab 15.3.
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- For project webhooks, you must have at least the Maintainer role for the project.
|
||||
- For group webhooks, you must have the Owner role for the group.
|
||||
|
||||
GitLab records the history of each webhook request.
|
||||
In **Recent events**, you can view all requests made to a webhook in the last two days.
|
||||
|
||||
To view the request history for a webhook:
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your project or group.
|
||||
1. Select **Settings > Webhooks**.
|
||||
1. Select **Edit** for the webhook.
|
||||
1. Go to the **Recent events** section.
|
||||
|
||||
The table includes the following details about each request:
|
||||
|
||||
- HTTP status code (green for `200`-`299` codes, red for the others, and `internal error` for failed deliveries)
|
||||
- Triggered event
|
||||
- Elapsed time of the request
|
||||
- Relative time for when the request was made
|
||||
|
||||

|
||||
|
||||
### Inspect request and response details
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- For project webhooks, you must have at least the Maintainer role for the project.
|
||||
- For group webhooks, you must have the Owner role for the group.
|
||||
|
||||
Each webhook request in [**Recent events**](#view-webhook-request-history) has a **Request details** page.
|
||||
This page contains the body and headers of:
|
||||
|
||||
- The response GitLab received from the webhook receiver endpoint
|
||||
- The webhook request GitLab sent
|
||||
|
||||
To inspect the request and response details of a webhook event:
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your project or group.
|
||||
1. Select **Settings > Webhooks**.
|
||||
1. Select **Edit** for the webhook.
|
||||
1. Go to the **Recent events** section.
|
||||
1. Select **View details** for the event.
|
||||
|
||||
To send the request again with the same data and the same [`Idempotency-Key` header](#delivery-headers)), select **Resend Request**.
|
||||
If the webhook URL has changed, you cannot resend the request.
|
||||
For resending programmatically, refer to our [API documentation](../../../api/project_webhooks.md#resend-a-project-webhook-event).
|
||||
|
||||
## Webhook receiver requirements
|
||||
|
||||
Webhook receiver endpoints should be fast and stable.
|
||||
Slow and unstable receivers might be [disabled automatically](#auto-disabled-webhooks) to ensure system reliability.
|
||||
Webhooks that [time out](../../../user/gitlab_com/index.md#other-limits) might lead to duplicate events.
|
||||
|
||||
Endpoints should follow these best practices:
|
||||
|
||||
- **Respond quickly with a `200` or `201` status response.**
|
||||
Avoid any significant processing of webhooks in the same request.
|
||||
Instead, implement a queue to handle webhooks after they are received.
|
||||
Webhook receivers that do not respond before the [timeout limit](../../../user/gitlab_com/index.md#other-limits)
|
||||
might be disabled automatically on GitLab.com.
|
||||
- **Be prepared to handle duplicate events.**
|
||||
If a webhook has timed out, the same event might be sent twice.
|
||||
To mitigate this issue, ensure your endpoint is reliably fast and stable.
|
||||
- **Keep the response headers and body minimal.**
|
||||
GitLab stores the response headers and body so you can
|
||||
[inspect them later in the webhook request history](#inspect-request-and-response-details) to help diagnose problems.
|
||||
You should limit the number and size of returned headers.
|
||||
You can also respond to the webhook request with an empty body.
|
||||
- Only return client error status responses (in the `4xx` range) to indicate the webhook is misconfigured.
|
||||
Responses in this range might cause your webhooks to be disabled automatically.
|
||||
For example, if your receiver supports only push events, you can return `400` for issue payloads.
|
||||
Alternatively, you can ignore unrecognized event payloads.
|
||||
- Never return `500` server error status responses if the event has been handled.
|
||||
These responses might cause the webhook to be disabled automatically.
|
||||
- Invalid HTTP responses are treated as failed requests.
|
||||
|
||||
## Auto-disabled webhooks
|
||||
|
||||
> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/329849) for project webhooks in GitLab 15.7. Feature flag `web_hooks_disable_failed` removed.
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/385902) for group webhooks in GitLab 15.10.
|
||||
> - [Disabled on self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/390157) in GitLab 15.10 [with a flag](../../../administration/feature_flags.md) named `auto_disabling_web_hooks`.
|
||||
|
||||
FLAG:
|
||||
On self-managed GitLab, by default this feature is not available. To make it available, an administrator can [enable the feature flag](../../../administration/feature_flags.md) named `auto_disabling_web_hooks`.
|
||||
On GitLab.com, this feature is available. On GitLab Dedicated, this feature is not available.
|
||||
|
||||
Project or group webhooks that fail four consecutive times are disabled automatically.
|
||||
|
||||
To view auto-disabled webhooks:
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your project or group.
|
||||
1. Select **Settings > Webhooks**.
|
||||
|
||||
An auto-disabled webhook appears in the list of project or group webhooks as:
|
||||
|
||||
- **Fails to connect** if the webhook is [temporarily disabled](#temporarily-disabled-webhooks)
|
||||
- **Failed to connect** if the webhook is [permanently disabled](#permanently-disabled-webhooks)
|
||||
|
||||

|
||||
|
||||
### Temporarily disabled webhooks
|
||||
|
||||
Project or group webhooks that return response codes in the `5xx` range
|
||||
or experience a [timeout](../../../user/gitlab_com/index.md#webhooks) or other HTTP errors
|
||||
are considered to be failing intermittently and are temporarily disabled.
|
||||
These webhooks are initially disabled for one minute, which is extended
|
||||
on each subsequent failure up to a maximum of 24 hours.
|
||||
|
||||
You can [re-enable temporarily disabled webhooks manually](#re-enable-disabled-webhooks)
|
||||
if the webhook receiver no longer returns an error.
|
||||
|
||||
### Permanently disabled webhooks
|
||||
|
||||
Project or group webhooks that return response codes in the `4xx` range
|
||||
are considered to be misconfigured and are permanently disabled.
|
||||
|
||||
These webhooks remain disabled until you [re-enable them manually](#re-enable-disabled-webhooks).
|
||||
|
||||
### Re-enable disabled webhooks
|
||||
|
||||
> - Introduced in GitLab 15.2 [with a flag](../../../administration/feature_flags.md) named `webhooks_failed_callout`. Disabled by default.
|
||||
> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/365535) in GitLab 15.7. Feature flag `webhooks_failed_callout` removed.
|
||||
|
||||
To re-enable a temporarily or permanently disabled webhook manually, [send a test request](#test-a-webhook).
|
||||
|
||||
The webhook is re-enabled if the test request returns a response code in the `2xx` range.
|
||||
|
||||
## Test a webhook
|
||||
|
||||
You can trigger a webhook manually, to ensure it's working properly. You can also send
|
||||
a test request to re-enable a [disabled webhook](#re-enable-disabled-webhooks).
|
||||
|
||||
For example, to test `push events`, your project should have at least one commit. The webhook uses this commit in the webhook.
|
||||
|
||||
NOTE:
|
||||
Testing is not supported for some types of events for project and groups webhooks.
|
||||
For more information, see [issue 379201](https://gitlab.com/gitlab-org/gitlab/-/issues/379201).
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- To test project webhooks, you must have at least the Maintainer role for the project.
|
||||
- To test group webhooks, you must have the Owner role for the group.
|
||||
|
||||
To test a webhook:
|
||||
|
||||
1. In your project or group, on the left sidebar, select **Settings > Webhooks**.
|
||||
1. Scroll down to the list of configured webhooks.
|
||||
1. From the **Test** dropdown list, select the type of event to test.
|
||||
|
||||
You can also test a webhook from its edit page.
|
||||
|
||||

|
||||
|
||||
## Delivery headers
|
||||
|
||||
> - `X-Gitlab-Event-UUID` header [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/329743) in GitLab 14.8.
|
||||
> - `X-Gitlab-Instance` header [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/31333) in GitLab 15.5.
|
||||
> - `X-Gitlab-Webhook-UUID` header [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/230830) in GitLab 16.2.
|
||||
> - `Idempotency-Key` header [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/388692) in GitLab 17.4.
|
||||
|
||||
Webhook requests to your endpoint include the following headers:
|
||||
|
||||
| Header | Description | Example |
|
||||
| ------ | ------ | ------ |
|
||||
| `User-Agent` | User agent in the format `"Gitlab/<VERSION>"`. | `"GitLab/15.5.0-pre"` |
|
||||
| `X-Gitlab-Instance` | Hostname of the GitLab instance that sent the webhook. | `"https://gitlab.com"` |
|
||||
| `X-Gitlab-Webhook-UUID` | Unique ID per webhook. | `"02affd2d-2cba-4033-917d-ec22d5dc4b38"` |
|
||||
| `X-Gitlab-Event` | Name of the webhook type. Corresponds to [event types](webhook_events.md) but in the format `"<EVENT> Hook"`. | `"Push Hook"` |
|
||||
| `X-Gitlab-Event-UUID` | Unique ID per webhook that is not recursive. A hook is recursive if triggered by an earlier webhook that hit the GitLab instance. Recursive webhooks have the same value for this header. | `"13792a34-cac6-4fda-95a8-c58e00a3954e"` |
|
||||
| `Idempotency-Key` | Unique ID that remains consistent across webhook retries. Use this header to ensure idempotency of webhook effects on integrations. | `"f5e5f430-f57b-4e6e-9fac-d9128cd7232f"` |
|
||||
|
||||
## Debug webhooks
|
||||
|
||||
To debug GitLab webhooks and capture payloads, you can use:
|
||||
|
||||
- [Public webhook inspection and testing tools](#public-webhook-inspection-and-testing-tools)
|
||||
- [Webhook request and response details](#inspect-request-and-response-details)
|
||||
- [The GitLab Development Kit (GDK)](#gitlab-development-kit-gdk)
|
||||
- [A private webhook receiver](#create-a-private-webhook-receiver)
|
||||
|
||||
For information about webhook events and the JSON data sent in the webhook payload,
|
||||
see [webhook events](webhook_events.md).
|
||||
|
||||
### Public webhook inspection and testing tools
|
||||
|
||||
You can use public tools to inspect and test webhook payloads. These tools act as catch-all endpoints for HTTP requests and respond with a `200 OK` HTTP status code. You can use these payloads to develop your webhook services.
|
||||
|
||||
You should exercise caution when using these tools as you might be sending sensitive data to external tools.
|
||||
You should use test tokens with these tools and rotate any secrets inadvertently sent to a third party.
|
||||
To keep your webhook payloads private, [create a private webhook receiver](#create-a-private-webhook-receiver) instead.
|
||||
|
||||
These public tools include:
|
||||
|
||||
- [Beeceptor](https://beeceptor.com) to create a temporary HTTPS endpoint and inspect incoming payloads
|
||||
- [Webhook.site](https://webhook.site) to review incoming payloads
|
||||
- [Webhook Tester](https://webhook-test.com) to inspect and debug incoming payloads
|
||||
|
||||
### GitLab Development Kit (GDK)
|
||||
|
||||
For a safer development environment, you can use the [GitLab Development Kit (GDK)](https://gitlab.com/gitlab-org/gitlab-development-kit) to develop against GitLab webhooks locally. With the GDK, you can send webhooks from your local GitLab instance to a webhook receiver running locally on your machine. To use this approach, you must install and configure the GDK.
|
||||
|
||||
### Create a private webhook receiver
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- You must have Ruby installed.
|
||||
|
||||
If you cannot send webhook payloads to a [public receiver](#public-webhook-inspection-and-testing-tools),
|
||||
you can create your own private webhook receiver.
|
||||
|
||||
To create a private webhook receiver:
|
||||
|
||||
1. Save the following file as `print_http_body.rb`:
|
||||
|
||||
```ruby
|
||||
require 'webrick'
|
||||
|
||||
server = WEBrick::HTTPServer.new(:Port => ARGV.first)
|
||||
server.mount_proc '/' do |req, res|
|
||||
puts req.body
|
||||
end
|
||||
|
||||
trap 'INT' do
|
||||
server.shutdown
|
||||
end
|
||||
server.start
|
||||
```
|
||||
|
||||
1. Choose an unused port (for example, `8000`) and start the script:
|
||||
|
||||
```shell
|
||||
ruby print_http_body.rb 8000
|
||||
```
|
||||
|
||||
1. In GitLab, [configure the webhook](#configure-webhooks-in-gitlab) and add your
|
||||
receiver's URL (for example, `http://receiver.example.com:8000/`).
|
||||
1. Select **Test**. You should see a similar message in the console:
|
||||
|
||||
```plaintext
|
||||
{"before":"077a85dd266e6f3573ef7e9ef8ce3343ad659c4e","after":"95cd4a99e93bc4bbabacfa2cd10e6725b1403c60",<SNIP>}
|
||||
example.com - - [14/May/2014:07:45:26 EDT] "POST / HTTP/1.1" 200 0
|
||||
- -> /
|
||||
```
|
||||
|
||||
To add this receiver, you might have to [allow requests to the local network](../../../security/webhooks.md).
|
||||
|
||||
## How image URLs are displayed in the webhook body
|
||||
|
||||
Relative image references are rewritten to use an absolute URL
|
||||
in the body of a webhook.
|
||||
For example, if an image, merge request, comment, or wiki page includes the
|
||||
following image reference:
|
||||
|
||||
```markdown
|
||||

|
||||
```
|
||||
|
||||
If:
|
||||
|
||||
- GitLab is installed at `gitlab.example.com`.
|
||||
- The project is at `example-group/example-project`.
|
||||
|
||||
The reference is rewritten in the webhook body as follows:
|
||||
|
||||
```markdown
|
||||

|
||||
```
|
||||
|
||||
Image URLs are not rewritten if:
|
||||
|
||||
- They already point to HTTP, HTTPS, or
|
||||
protocol-relative URLs.
|
||||
- They use advanced Markdown features like link labels.
|
||||
|
||||
## Configure webhooks to support mutual TLS
|
||||
### Configure webhooks to support mutual TLS
|
||||
|
||||
DETAILS:
|
||||
**Offering:** Self-managed
|
||||
|
|
@ -535,7 +260,7 @@ To configure the certificate:
|
|||
|
||||
::EndTabs
|
||||
|
||||
## Configuring firewalls for webhook traffic
|
||||
### Configuring firewalls for webhook traffic
|
||||
|
||||
When configuring firewalls for webhooks traffic, you can configure assuming that webhooks are usually sent asynchronously from Sidekiq nodes. However, there are cases
|
||||
when webhooks are sent synchronously from Rails nodes, including when:
|
||||
|
|
@ -543,6 +268,222 @@ when webhooks are sent synchronously from Rails nodes, including when:
|
|||
- [Testing a Webhook](#test-a-webhook) in the UI.
|
||||
- [Retrying a Webhook](#inspect-request-and-response-details) in the UI.
|
||||
|
||||
## Manage webhooks
|
||||
|
||||
Monitor and maintain your configured webhooks in GitLab.
|
||||
|
||||
### View webhook request history
|
||||
|
||||
> - **Recent events** for group webhooks [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/325642) in GitLab 15.3.
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- For project webhooks, you must have at least the Maintainer role for the project.
|
||||
- For group webhooks, you must have the Owner role for the group.
|
||||
|
||||
GitLab records the history of each webhook request.
|
||||
In **Recent events**, you can view all requests made to a webhook in the last two days.
|
||||
|
||||
To view the request history for a webhook:
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your project or group.
|
||||
1. Select **Settings > Webhooks**.
|
||||
1. Select **Edit** for the webhook.
|
||||
1. Go to the **Recent events** section.
|
||||
|
||||
The table includes the following details about each request:
|
||||
|
||||
- HTTP status code (green for `200`-`299` codes, red for the others, and `internal error` for failed deliveries)
|
||||
- Triggered event
|
||||
- Elapsed time of the request
|
||||
- Relative time for when the request was made
|
||||
|
||||

|
||||
|
||||
#### Inspect request and response details
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- For project webhooks, you must have at least the Maintainer role for the project.
|
||||
- For group webhooks, you must have the Owner role for the group.
|
||||
|
||||
Each webhook request in [**Recent events**](#view-webhook-request-history) has a **Request details** page.
|
||||
This page contains the body and headers of:
|
||||
|
||||
- The response GitLab received from the webhook receiver endpoint
|
||||
- The webhook request GitLab sent
|
||||
|
||||
To inspect the request and response details of a webhook event:
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your project or group.
|
||||
1. Select **Settings > Webhooks**.
|
||||
1. Select **Edit** for the webhook.
|
||||
1. Go to the **Recent events** section.
|
||||
1. Select **View details** for the event.
|
||||
|
||||
To send the request again with the same data and the same [`Idempotency-Key` header](#delivery-headers)), select **Resend Request**.
|
||||
If the webhook URL has changed, you cannot resend the request.
|
||||
For resending programmatically, refer to our [API documentation](../../../api/project_webhooks.md#resend-a-project-webhook-event).
|
||||
|
||||
### Test a webhook
|
||||
|
||||
You can trigger a webhook manually, to ensure it's working properly. You can also send
|
||||
a test request to re-enable a [disabled webhook](#re-enable-disabled-webhooks).
|
||||
|
||||
For example, to test `push events`, your project should have at least one commit. The webhook uses this commit in the webhook.
|
||||
|
||||
NOTE:
|
||||
Testing is not supported for some types of events for project and groups webhooks.
|
||||
For more information, see [issue 379201](https://gitlab.com/gitlab-org/gitlab/-/issues/379201).
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- To test project webhooks, you must have at least the Maintainer role for the project.
|
||||
- To test group webhooks, you must have the Owner role for the group.
|
||||
|
||||
To test a webhook:
|
||||
|
||||
1. In your project or group, on the left sidebar, select **Settings > Webhooks**.
|
||||
1. Scroll down to the list of configured webhooks.
|
||||
1. From the **Test** dropdown list, select the type of event to test.
|
||||
|
||||
You can also test a webhook from its edit page.
|
||||
|
||||

|
||||
|
||||
## Webhook reference
|
||||
|
||||
This section collects technical details about GitLab webhooks.
|
||||
|
||||
Use this information to better understand how webhooks work and integrate with your systems.
|
||||
Refer to these specifics when setting up, troubleshooting, or optimizing your webhook configurations.
|
||||
|
||||
### Webhook receiver requirements
|
||||
|
||||
Webhook receiver endpoints should be fast and stable.
|
||||
Slow and unstable receivers might be [disabled automatically](#auto-disabled-webhooks) to ensure system reliability.
|
||||
Webhooks that [time out](../../../user/gitlab_com/index.md#other-limits) might lead to duplicate events.
|
||||
|
||||
Endpoints should follow these best practices:
|
||||
|
||||
- **Respond quickly with a `200` or `201` status response.**
|
||||
Avoid any significant processing of webhooks in the same request.
|
||||
Instead, implement a queue to handle webhooks after they are received.
|
||||
Webhook receivers that do not respond before the [timeout limit](../../../user/gitlab_com/index.md#other-limits)
|
||||
might be disabled automatically on GitLab.com.
|
||||
- **Be prepared to handle duplicate events.**
|
||||
If a webhook has timed out, the same event might be sent twice.
|
||||
To mitigate this issue, ensure your endpoint is reliably fast and stable.
|
||||
- **Keep the response headers and body minimal.**
|
||||
GitLab stores the response headers and body so you can
|
||||
[inspect them later in the webhook request history](#inspect-request-and-response-details) to help diagnose problems.
|
||||
You should limit the number and size of returned headers.
|
||||
You can also respond to the webhook request with an empty body.
|
||||
- Only return client error status responses (in the `4xx` range) to indicate the webhook is misconfigured.
|
||||
Responses in this range might cause your webhooks to be disabled automatically.
|
||||
For example, if your receiver supports only push events, you can return `400` for issue payloads.
|
||||
Alternatively, you can ignore unrecognized event payloads.
|
||||
- Never return `500` server error status responses if the event has been handled.
|
||||
These responses might cause the webhook to be disabled automatically.
|
||||
- Invalid HTTP responses are treated as failed requests.
|
||||
|
||||
### Auto-disabled webhooks
|
||||
|
||||
> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/329849) for project webhooks in GitLab 15.7. Feature flag `web_hooks_disable_failed` removed.
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/385902) for group webhooks in GitLab 15.10.
|
||||
> - [Disabled on self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/390157) in GitLab 15.10 [with a flag](../../../administration/feature_flags.md) named `auto_disabling_web_hooks`.
|
||||
|
||||
FLAG:
|
||||
On self-managed GitLab, by default this feature is not available. To make it available, an administrator can [enable the feature flag](../../../administration/feature_flags.md) named `auto_disabling_web_hooks`.
|
||||
On GitLab.com, this feature is available. On GitLab Dedicated, this feature is not available.
|
||||
|
||||
Project or group webhooks that fail four consecutive times are disabled automatically.
|
||||
|
||||
To view auto-disabled webhooks:
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your project or group.
|
||||
1. Select **Settings > Webhooks**.
|
||||
|
||||
An auto-disabled webhook appears in the list of project or group webhooks as:
|
||||
|
||||
- **Fails to connect** if the webhook is [temporarily disabled](#temporarily-disabled-webhooks)
|
||||
- **Failed to connect** if the webhook is [permanently disabled](#permanently-disabled-webhooks)
|
||||
|
||||

|
||||
|
||||
#### Temporarily disabled webhooks
|
||||
|
||||
Project or group webhooks that return response codes in the `5xx` range
|
||||
or experience a [timeout](../../../user/gitlab_com/index.md#webhooks) or other HTTP errors
|
||||
are considered to be failing intermittently and are temporarily disabled.
|
||||
These webhooks are initially disabled for one minute, which is extended
|
||||
on each subsequent failure up to a maximum of 24 hours.
|
||||
|
||||
You can [re-enable temporarily disabled webhooks manually](#re-enable-disabled-webhooks)
|
||||
if the webhook receiver no longer returns an error.
|
||||
|
||||
#### Permanently disabled webhooks
|
||||
|
||||
Project or group webhooks that return response codes in the `4xx` range
|
||||
are considered to be misconfigured and are permanently disabled.
|
||||
|
||||
These webhooks remain disabled until you [re-enable them manually](#re-enable-disabled-webhooks).
|
||||
|
||||
#### Re-enable disabled webhooks
|
||||
|
||||
> - Introduced in GitLab 15.2 [with a flag](../../../administration/feature_flags.md) named `webhooks_failed_callout`. Disabled by default.
|
||||
> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/365535) in GitLab 15.7. Feature flag `webhooks_failed_callout` removed.
|
||||
|
||||
To re-enable a temporarily or permanently disabled webhook manually, [send a test request](#test-a-webhook).
|
||||
|
||||
The webhook is re-enabled if the test request returns a response code in the `2xx` range.
|
||||
|
||||
### Delivery headers
|
||||
|
||||
> - `X-Gitlab-Event-UUID` header [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/329743) in GitLab 14.8.
|
||||
> - `X-Gitlab-Instance` header [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/31333) in GitLab 15.5.
|
||||
> - `X-Gitlab-Webhook-UUID` header [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/230830) in GitLab 16.2.
|
||||
> - `Idempotency-Key` header [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/388692) in GitLab 17.4.
|
||||
|
||||
Webhook requests to your endpoint include the following headers:
|
||||
|
||||
| Header | Description | Example |
|
||||
| ------ | ------ | ------ |
|
||||
| `User-Agent` | User agent in the format `"Gitlab/<VERSION>"`. | `"GitLab/15.5.0-pre"` |
|
||||
| `X-Gitlab-Instance` | Hostname of the GitLab instance that sent the webhook. | `"https://gitlab.com"` |
|
||||
| `X-Gitlab-Webhook-UUID` | Unique ID per webhook. | `"02affd2d-2cba-4033-917d-ec22d5dc4b38"` |
|
||||
| `X-Gitlab-Event` | Name of the webhook type. Corresponds to [event types](webhook_events.md) but in the format `"<EVENT> Hook"`. | `"Push Hook"` |
|
||||
| `X-Gitlab-Event-UUID` | Unique ID per webhook that is not recursive. A hook is recursive if triggered by an earlier webhook that hit the GitLab instance. Recursive webhooks have the same value for this header. | `"13792a34-cac6-4fda-95a8-c58e00a3954e"` |
|
||||
| `Idempotency-Key` | Unique ID that remains consistent across webhook retries. Use this header to ensure idempotency of webhook effects on integrations. | `"f5e5f430-f57b-4e6e-9fac-d9128cd7232f"` |
|
||||
|
||||
### How image URLs are displayed in the webhook body
|
||||
|
||||
Relative image references are rewritten to use an absolute URL
|
||||
in the body of a webhook.
|
||||
For example, if an image, merge request, comment, or wiki page includes the
|
||||
following image reference:
|
||||
|
||||
```markdown
|
||||

|
||||
```
|
||||
|
||||
If:
|
||||
|
||||
- GitLab is installed at `gitlab.example.com`.
|
||||
- The project is at `example-group/example-project`.
|
||||
|
||||
The reference is rewritten in the webhook body as follows:
|
||||
|
||||
```markdown
|
||||

|
||||
```
|
||||
|
||||
Image URLs are not rewritten if:
|
||||
|
||||
- They already point to HTTP, HTTPS, or
|
||||
protocol-relative URLs.
|
||||
- They use advanced Markdown features like link labels.
|
||||
|
||||
## Related topics
|
||||
|
||||
- [Webhook events and webhook JSON payloads](webhook_events.md)
|
||||
|
|
@ -552,6 +493,81 @@ when webhooks are sent synchronously from Rails nodes, including when:
|
|||
|
||||
## Troubleshooting
|
||||
|
||||
### Debug webhooks
|
||||
|
||||
To debug GitLab webhooks and capture payloads, you can use:
|
||||
|
||||
- [Public webhook inspection and testing tools](#public-webhook-inspection-and-testing-tools)
|
||||
- [Webhook request and response details](#inspect-request-and-response-details)
|
||||
- [The GitLab Development Kit (GDK)](#gitlab-development-kit-gdk)
|
||||
- [A private webhook receiver](#create-a-private-webhook-receiver)
|
||||
|
||||
For information about webhook events and the JSON data sent in the webhook payload,
|
||||
see [webhook events](webhook_events.md).
|
||||
|
||||
#### Public webhook inspection and testing tools
|
||||
|
||||
You can use public tools to inspect and test webhook payloads. These tools act as catch-all endpoints for HTTP requests and respond with a `200 OK` HTTP status code. You can use these payloads to develop your webhook services.
|
||||
|
||||
You should exercise caution when using these tools as you might be sending sensitive data to external tools.
|
||||
You should use test tokens with these tools and rotate any secrets inadvertently sent to a third party.
|
||||
To keep your webhook payloads private, [create a private webhook receiver](#create-a-private-webhook-receiver) instead.
|
||||
|
||||
These public tools include:
|
||||
|
||||
- [Beeceptor](https://beeceptor.com) to create a temporary HTTPS endpoint and inspect incoming payloads
|
||||
- [Webhook.site](https://webhook.site) to review incoming payloads
|
||||
- [Webhook Tester](https://webhook-test.com) to inspect and debug incoming payloads
|
||||
|
||||
#### GitLab Development Kit (GDK)
|
||||
|
||||
For a safer development environment, you can use the [GitLab Development Kit (GDK)](https://gitlab.com/gitlab-org/gitlab-development-kit) to develop against GitLab webhooks locally. With the GDK, you can send webhooks from your local GitLab instance to a webhook receiver running locally on your machine. To use this approach, you must install and configure the GDK.
|
||||
|
||||
#### Create a private webhook receiver
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- You must have Ruby installed.
|
||||
|
||||
If you cannot send webhook payloads to a [public receiver](#public-webhook-inspection-and-testing-tools),
|
||||
you can create your own private webhook receiver.
|
||||
|
||||
To create a private webhook receiver:
|
||||
|
||||
1. Save the following file as `print_http_body.rb`:
|
||||
|
||||
```ruby
|
||||
require 'webrick'
|
||||
|
||||
server = WEBrick::HTTPServer.new(:Port => ARGV.first)
|
||||
server.mount_proc '/' do |req, res|
|
||||
puts req.body
|
||||
end
|
||||
|
||||
trap 'INT' do
|
||||
server.shutdown
|
||||
end
|
||||
server.start
|
||||
```
|
||||
|
||||
1. Choose an unused port (for example, `8000`) and start the script:
|
||||
|
||||
```shell
|
||||
ruby print_http_body.rb 8000
|
||||
```
|
||||
|
||||
1. In GitLab, [configure the webhook](#configure-webhooks) and add your
|
||||
receiver's URL (for example, `http://receiver.example.com:8000/`).
|
||||
1. Select **Test**. You should see a similar message in the console:
|
||||
|
||||
```plaintext
|
||||
{"before":"077a85dd266e6f3573ef7e9ef8ce3343ad659c4e","after":"95cd4a99e93bc4bbabacfa2cd10e6725b1403c60",<SNIP>}
|
||||
example.com - - [14/May/2014:07:45:26 EDT] "POST / HTTP/1.1" 200 0
|
||||
- -> /
|
||||
```
|
||||
|
||||
To add this receiver, you might have to [allow requests to the local network](../../../security/webhooks.md).
|
||||
|
||||
### `unable to get local issuer certificate`
|
||||
|
||||
When SSL verification is enabled, you might get an error that GitLab
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ and you can maintain your snippets with the [snippets API](../api/snippets.md).
|
|||
You can create and manage your snippets with:
|
||||
|
||||
- The GitLab user interface.
|
||||
- The [GitLab Workflow extension for VS Code](../editor_extensions/visual_studio_code/index.md).
|
||||
- The [GitLab Workflow extension for VS Code](../editor_extensions/visual_studio_code/index.md#create-a-snippet).
|
||||
- The [`glab` CLI](../editor_extensions/gitlab_cli/index.md).
|
||||
|
||||

|
||||
|
|
|
|||
|
|
@ -1,37 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module BackgroundMigration
|
||||
# This migration fixes existing `vulnerability_reads` records which did not have `has_issues`
|
||||
# correctly set at the time of creation.
|
||||
class FixVulnerabilityReadsHasIssues < BatchedMigrationJob
|
||||
operation_name :fix_has_issues
|
||||
feature_category :vulnerability_management
|
||||
|
||||
# rubocop:disable Style/Documentation
|
||||
class VulnerabilityRead < ::ApplicationRecord
|
||||
self.table_name = 'vulnerability_reads'
|
||||
|
||||
scope :with_vulnerability_ids, ->(ids) { where(vulnerability_id: ids) }
|
||||
scope :without_issues, -> { where(has_issues: false) }
|
||||
end
|
||||
# rubocop:enable Style/Documentation
|
||||
|
||||
def perform
|
||||
Gitlab::Database.allow_cross_joins_across_databases(
|
||||
url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/480746'
|
||||
) do
|
||||
each_sub_batch do |sub_batch|
|
||||
vulnerability_reads_with_issue_links(sub_batch).update_all('has_issues = true')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def vulnerability_reads_with_issue_links(sub_batch)
|
||||
VulnerabilityRead.with_vulnerability_ids(sub_batch.select(:vulnerability_id)).without_issues
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -2,15 +2,15 @@
|
|||
|
||||
browser_performance:
|
||||
stage: performance
|
||||
image: docker:20.10.12
|
||||
image: docker:27.3
|
||||
allow_failure: true
|
||||
variables:
|
||||
DOCKER_TLS_CERTDIR: ""
|
||||
SITESPEED_IMAGE: sitespeedio/sitespeed.io
|
||||
SITESPEED_VERSION: 26.1.0
|
||||
SITESPEED_VERSION: 35.0.0
|
||||
SITESPEED_OPTIONS: ''
|
||||
services:
|
||||
- name: 'docker:20.10.12-dind'
|
||||
- name: docker:27.3-dind
|
||||
command: ['--tls=false', '--host=tcp://0.0.0.0:2375']
|
||||
script:
|
||||
- |
|
||||
|
|
@ -21,11 +21,9 @@ browser_performance:
|
|||
fi
|
||||
- CI_ENVIRONMENT_URL="$(cat environment_url.txt)"
|
||||
- export CI_ENVIRONMENT_URL
|
||||
- mkdir gitlab-exporter
|
||||
# Busybox wget does not support proxied HTTPS, get the real thing.
|
||||
# See https://gitlab.com/gitlab-org/gitlab/-/issues/287611.
|
||||
- (env | grep -i _proxy= >/dev/null 2>&1) && apk --no-cache add wget
|
||||
- wget -O gitlab-exporter/index.js https://gitlab.com/gitlab-org/gl-performance/raw/1.1.0/index.js
|
||||
- git clone --branch 2.0.0 https://gitlab.com/gitlab-org/gl-performance.git gitlab-exporter
|
||||
- apk --no-cache add npm
|
||||
- npm install --prefix gitlab-exporter/
|
||||
- mkdir sitespeed-results
|
||||
- |
|
||||
function propagate_env_vars() {
|
||||
|
|
@ -50,7 +48,7 @@ browser_performance:
|
|||
HTTP_PROXY \
|
||||
NO_PROXY \
|
||||
) \
|
||||
--shm-size=1g --rm -v "$(pwd)":/sitespeed.io $SITESPEED_IMAGE:$SITESPEED_VERSION --plugins.add ./gitlab-exporter --cpu --outputFolder sitespeed-results .gitlab-urls.txt $SITESPEED_OPTIONS
|
||||
--shm-size=1g --rm -v "$(pwd)":/sitespeed.io $SITESPEED_IMAGE:$SITESPEED_VERSION --plugins.add ./gitlab-exporter/index.js --cpu --outputFolder sitespeed-results .gitlab-urls.txt $SITESPEED_OPTIONS
|
||||
else
|
||||
docker run \
|
||||
$(propagate_env_vars \
|
||||
|
|
@ -63,7 +61,7 @@ browser_performance:
|
|||
HTTP_PROXY \
|
||||
NO_PROXY \
|
||||
) \
|
||||
--shm-size=1g --rm -v "$(pwd)":/sitespeed.io $SITESPEED_IMAGE:$SITESPEED_VERSION --plugins.add ./gitlab-exporter --cpu --outputFolder sitespeed-results "$CI_ENVIRONMENT_URL" $SITESPEED_OPTIONS
|
||||
--shm-size=1g --rm -v "$(pwd)":/sitespeed.io $SITESPEED_IMAGE:$SITESPEED_VERSION --plugins.add ./gitlab-exporter/index.js --cpu --outputFolder sitespeed-results "$CI_ENVIRONMENT_URL" $SITESPEED_OPTIONS
|
||||
fi
|
||||
- mv sitespeed-results/data/performance.json browser-performance.json
|
||||
artifacts:
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
browser_performance:
|
||||
stage: performance
|
||||
image: docker:20.10.12
|
||||
image: docker:27.3
|
||||
allow_failure: true
|
||||
variables:
|
||||
DOCKER_TLS_CERTDIR: ""
|
||||
|
|
@ -10,7 +10,7 @@ browser_performance:
|
|||
SITESPEED_VERSION: latest
|
||||
SITESPEED_OPTIONS: ''
|
||||
services:
|
||||
- name: 'docker:20.10.12-dind'
|
||||
- name: docker:27.3-dind
|
||||
command: ['--tls=false', '--host=tcp://0.0.0.0:2375']
|
||||
script:
|
||||
- |
|
||||
|
|
@ -20,11 +20,9 @@ browser_performance:
|
|||
fi
|
||||
fi
|
||||
- export CI_ENVIRONMENT_URL=$(cat environment_url.txt)
|
||||
- mkdir gitlab-exporter
|
||||
# Busybox wget does not support proxied HTTPS, get the real thing.
|
||||
# See https://gitlab.com/gitlab-org/gitlab/-/issues/287611.
|
||||
- (env | grep -i _proxy= >/dev/null 2>&1) && apk --no-cache add wget
|
||||
- wget -O gitlab-exporter/index.js https://gitlab.com/gitlab-org/gl-performance/raw/1.1.0/index.js
|
||||
- git clone --branch https://gitlab.com/gitlab-org/gl-performance.git gitlab-exporter
|
||||
- apk --no-cache add npm
|
||||
- npm install --prefix gitlab-exporter/
|
||||
- mkdir sitespeed-results
|
||||
- |
|
||||
function propagate_env_vars() {
|
||||
|
|
@ -49,7 +47,7 @@ browser_performance:
|
|||
HTTP_PROXY \
|
||||
NO_PROXY \
|
||||
) \
|
||||
--shm-size=1g --rm -v "$(pwd)":/sitespeed.io $SITESPEED_IMAGE:$SITESPEED_VERSION --plugins.add ./gitlab-exporter --cpu --outputFolder sitespeed-results .gitlab-urls.txt $SITESPEED_OPTIONS
|
||||
--shm-size=1g --rm -v "$(pwd)":/sitespeed.io $SITESPEED_IMAGE:$SITESPEED_VERSION --plugins.add ./gitlab-exporter/index.js --cpu --outputFolder sitespeed-results .gitlab-urls.txt $SITESPEED_OPTIONS
|
||||
else
|
||||
docker run \
|
||||
$(propagate_env_vars \
|
||||
|
|
@ -62,7 +60,7 @@ browser_performance:
|
|||
HTTP_PROXY \
|
||||
NO_PROXY \
|
||||
) \
|
||||
--shm-size=1g --rm -v "$(pwd)":/sitespeed.io $SITESPEED_IMAGE:$SITESPEED_VERSION --plugins.add ./gitlab-exporter --cpu --outputFolder sitespeed-results "$CI_ENVIRONMENT_URL" $SITESPEED_OPTIONS
|
||||
--shm-size=1g --rm -v "$(pwd)":/sitespeed.io $SITESPEED_IMAGE:$SITESPEED_VERSION --plugins.add ./gitlab-exporter/index.js --cpu --outputFolder sitespeed-results "$CI_ENVIRONMENT_URL" $SITESPEED_OPTIONS
|
||||
fi
|
||||
- mv sitespeed-results/data/performance.json browser-performance.json
|
||||
artifacts:
|
||||
|
|
|
|||
|
|
@ -13,21 +13,19 @@ stages:
|
|||
|
||||
browser_performance:
|
||||
stage: performance
|
||||
image: docker:git
|
||||
image: docker:27.3
|
||||
variables:
|
||||
URL: ''
|
||||
SITESPEED_IMAGE: sitespeedio/sitespeed.io
|
||||
SITESPEED_VERSION: 26.1.0
|
||||
SITESPEED_VERSION: 35.0.0
|
||||
SITESPEED_OPTIONS: ''
|
||||
SITESPEED_DOCKER_OPTIONS: ''
|
||||
services:
|
||||
- docker:dind
|
||||
- docker:27.3-dind
|
||||
script:
|
||||
- mkdir gitlab-exporter
|
||||
# Busybox wget does not support proxied HTTPS, get the real thing.
|
||||
# See https://gitlab.com/gitlab-org/gitlab/-/issues/287611.
|
||||
- (env | grep -i _proxy= >/dev/null 2>&1) && apk --no-cache add wget
|
||||
- wget -O ./gitlab-exporter/index.js https://gitlab.com/gitlab-org/gl-performance/raw/1.1.0/index.js
|
||||
- git clone --branch 2.0.0 https://gitlab.com/gitlab-org/gl-performance.git gitlab-exporter
|
||||
- apk --no-cache add npm
|
||||
- npm install --prefix gitlab-exporter/
|
||||
- mkdir sitespeed-results
|
||||
- |
|
||||
function propagate_env_vars() {
|
||||
|
|
@ -49,7 +47,7 @@ browser_performance:
|
|||
HTTP_PROXY \
|
||||
NO_PROXY \
|
||||
) \
|
||||
$SITESPEED_DOCKER_OPTIONS --shm-size=1g --rm -v "$(pwd)":/sitespeed.io $SITESPEED_IMAGE:$SITESPEED_VERSION --plugins.add ./gitlab-exporter --cpu --outputFolder sitespeed-results $URL $SITESPEED_OPTIONS
|
||||
$SITESPEED_DOCKER_OPTIONS --shm-size=1g --rm -v "$(pwd)":/sitespeed.io $SITESPEED_IMAGE:$SITESPEED_VERSION --plugins.add ./gitlab-exporter/index.js --cpu --outputFolder sitespeed-results $URL $SITESPEED_OPTIONS
|
||||
- mv sitespeed-results/data/performance.json browser-performance.json
|
||||
artifacts:
|
||||
paths:
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ stages:
|
|||
|
||||
browser_performance:
|
||||
stage: performance
|
||||
image: docker:git
|
||||
image: docker:27.3
|
||||
variables:
|
||||
URL: ''
|
||||
SITESPEED_IMAGE: sitespeedio/sitespeed.io
|
||||
|
|
@ -21,13 +21,11 @@ browser_performance:
|
|||
SITESPEED_OPTIONS: ''
|
||||
SITESPEED_DOCKER_OPTIONS: ''
|
||||
services:
|
||||
- docker:dind
|
||||
- docker:27.3-dind
|
||||
script:
|
||||
- mkdir gitlab-exporter
|
||||
# Busybox wget does not support proxied HTTPS, get the real thing.
|
||||
# See https://gitlab.com/gitlab-org/gitlab/-/issues/287611.
|
||||
- (env | grep -i _proxy= >/dev/null 2>&1) && apk --no-cache add wget
|
||||
- wget -O ./gitlab-exporter/index.js https://gitlab.com/gitlab-org/gl-performance/raw/1.1.0/index.js
|
||||
- git clone https://gitlab.com/gitlab-org/gl-performance.git gitlab-exporter
|
||||
- apk --no-cache add npm
|
||||
- npm install --prefix gitlab-exporter/
|
||||
- mkdir sitespeed-results
|
||||
- |
|
||||
function propagate_env_vars() {
|
||||
|
|
@ -49,7 +47,7 @@ browser_performance:
|
|||
HTTP_PROXY \
|
||||
NO_PROXY \
|
||||
) \
|
||||
$SITESPEED_DOCKER_OPTIONS --shm-size=1g --rm -v "$(pwd)":/sitespeed.io $SITESPEED_IMAGE:$SITESPEED_VERSION --plugins.add ./gitlab-exporter --cpu --outputFolder sitespeed-results $URL $SITESPEED_OPTIONS
|
||||
$SITESPEED_DOCKER_OPTIONS --shm-size=1g --rm -v "$(pwd)":/sitespeed.io $SITESPEED_IMAGE:$SITESPEED_VERSION --plugins.add ./gitlab-exporter/index.js --cpu --outputFolder sitespeed-results $URL $SITESPEED_OPTIONS
|
||||
- mv sitespeed-results/data/performance.json browser-performance.json
|
||||
artifacts:
|
||||
paths:
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ source "https://rubygems.org"
|
|||
gemspec
|
||||
|
||||
group :test do
|
||||
gem "climate_control", "~> 1.2"
|
||||
gem "gitlab-styles", "~> 12.0", ">= 12.0.1"
|
||||
gem "climate_control", "~> 1.2.0"
|
||||
gem "gitlab-styles", "~> 13.0.0"
|
||||
gem "pry", "~> 0.14.2"
|
||||
gem "rspec", "~> 3.13"
|
||||
gem "simplecov", "~> 0.22.0"
|
||||
|
|
|
|||
|
|
@ -13,42 +13,45 @@ PATH
|
|||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
activesupport (7.1.3.2)
|
||||
activesupport (7.2.1)
|
||||
base64
|
||||
bigdecimal
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
concurrent-ruby (~> 1.0, >= 1.3.1)
|
||||
connection_pool (>= 2.2.5)
|
||||
drb
|
||||
i18n (>= 1.6, < 2)
|
||||
logger (>= 1.4.2)
|
||||
minitest (>= 5.1)
|
||||
mutex_m
|
||||
tzinfo (~> 2.0)
|
||||
securerandom (>= 0.3)
|
||||
tzinfo (~> 2.0, >= 2.0.5)
|
||||
ast (2.4.2)
|
||||
base64 (0.2.0)
|
||||
bigdecimal (3.1.7)
|
||||
bigdecimal (3.1.8)
|
||||
climate_control (1.2.0)
|
||||
coderay (1.1.3)
|
||||
concurrent-ruby (1.2.3)
|
||||
concurrent-ruby (1.3.4)
|
||||
connection_pool (2.4.1)
|
||||
diff-lcs (1.5.1)
|
||||
docile (1.4.0)
|
||||
drb (2.2.1)
|
||||
gitlab-styles (12.0.1)
|
||||
rubocop (~> 1.62.1)
|
||||
rubocop-factory_bot (~> 2.25.1)
|
||||
rubocop-graphql (~> 1.5.0)
|
||||
rubocop-performance (~> 1.20.2)
|
||||
rubocop-rails (~> 2.24.0)
|
||||
rubocop-rspec (~> 2.27.1)
|
||||
i18n (1.14.4)
|
||||
gitlab-styles (13.0.0)
|
||||
rubocop (~> 1.66.0)
|
||||
rubocop-capybara (~> 2.21.0)
|
||||
rubocop-factory_bot (~> 2.26.1)
|
||||
rubocop-graphql (~> 1.5.4)
|
||||
rubocop-performance (~> 1.21.1)
|
||||
rubocop-rails (~> 2.26.0)
|
||||
rubocop-rspec (~> 3.0.4)
|
||||
rubocop-rspec_rails (~> 2.30.0)
|
||||
i18n (1.14.6)
|
||||
concurrent-ruby (~> 1.0)
|
||||
json (2.7.2)
|
||||
language_server-protocol (3.17.0.3)
|
||||
logger (1.6.1)
|
||||
method_source (1.1.0)
|
||||
minitest (5.22.3)
|
||||
mutex_m (0.2.0)
|
||||
parallel (1.25.1)
|
||||
parser (3.3.3.0)
|
||||
minitest (5.25.1)
|
||||
parallel (1.26.3)
|
||||
parser (3.3.5.0)
|
||||
ast (~> 2.4.1)
|
||||
racc
|
||||
pastel (0.8.0)
|
||||
|
|
@ -56,13 +59,11 @@ GEM
|
|||
pry (0.14.2)
|
||||
coderay (~> 1.1)
|
||||
method_source (~> 1.0)
|
||||
racc (1.8.0)
|
||||
rack (3.1.6)
|
||||
racc (1.8.1)
|
||||
rack (3.1.8)
|
||||
rainbow (3.1.1)
|
||||
regexp_parser (2.9.2)
|
||||
require_all (3.0.0)
|
||||
rexml (3.3.1)
|
||||
strscan
|
||||
rspec (3.13.0)
|
||||
rspec-core (~> 3.13.0)
|
||||
rspec-expectations (~> 3.13.0)
|
||||
|
|
@ -76,45 +77,45 @@ GEM
|
|||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.13.0)
|
||||
rspec-support (3.13.1)
|
||||
rubocop (1.62.1)
|
||||
rubocop (1.66.1)
|
||||
json (~> 2.3)
|
||||
language_server-protocol (>= 3.17.0)
|
||||
parallel (~> 1.10)
|
||||
parser (>= 3.3.0.2)
|
||||
rainbow (>= 2.2.2, < 4.0)
|
||||
regexp_parser (>= 1.8, < 3.0)
|
||||
rexml (>= 3.2.5, < 4.0)
|
||||
rubocop-ast (>= 1.31.1, < 2.0)
|
||||
regexp_parser (>= 2.4, < 3.0)
|
||||
rubocop-ast (>= 1.32.2, < 2.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (>= 2.4.0, < 3.0)
|
||||
rubocop-ast (1.31.3)
|
||||
rubocop-ast (1.32.3)
|
||||
parser (>= 3.3.1.0)
|
||||
rubocop-capybara (2.21.0)
|
||||
rubocop (~> 1.41)
|
||||
rubocop-factory_bot (2.25.1)
|
||||
rubocop (~> 1.41)
|
||||
rubocop-graphql (1.5.3)
|
||||
rubocop-factory_bot (2.26.1)
|
||||
rubocop (~> 1.61)
|
||||
rubocop-graphql (1.5.4)
|
||||
rubocop (>= 1.50, < 2)
|
||||
rubocop-performance (1.20.2)
|
||||
rubocop-performance (1.21.1)
|
||||
rubocop (>= 1.48.1, < 2.0)
|
||||
rubocop-ast (>= 1.30.0, < 2.0)
|
||||
rubocop-rails (2.24.1)
|
||||
rubocop-ast (>= 1.31.1, < 2.0)
|
||||
rubocop-rails (2.26.2)
|
||||
activesupport (>= 4.2.0)
|
||||
rack (>= 1.1)
|
||||
rubocop (>= 1.33.0, < 2.0)
|
||||
rubocop (>= 1.52.0, < 2.0)
|
||||
rubocop-ast (>= 1.31.1, < 2.0)
|
||||
rubocop-rspec (2.27.1)
|
||||
rubocop (~> 1.40)
|
||||
rubocop-capybara (~> 2.17)
|
||||
rubocop-factory_bot (~> 2.22)
|
||||
rubocop-rspec (3.0.5)
|
||||
rubocop (~> 1.61)
|
||||
rubocop-rspec_rails (2.30.0)
|
||||
rubocop (~> 1.61)
|
||||
rubocop-rspec (~> 3, >= 3.0.1)
|
||||
ruby-progressbar (1.13.0)
|
||||
securerandom (0.3.1)
|
||||
simplecov (0.22.0)
|
||||
docile (~> 1.1)
|
||||
simplecov-html (~> 0.11)
|
||||
simplecov_json_formatter (~> 0.1)
|
||||
simplecov-html (0.12.3)
|
||||
simplecov_json_formatter (0.1.4)
|
||||
strscan (3.1.0)
|
||||
thor (1.3.1)
|
||||
tty-color (0.6.0)
|
||||
tty-cursor (0.7.1)
|
||||
|
|
@ -131,16 +132,16 @@ GEM
|
|||
tty-which (0.5.0)
|
||||
tzinfo (2.0.6)
|
||||
concurrent-ruby (~> 1.0)
|
||||
unicode-display_width (2.5.0)
|
||||
unicode-display_width (2.6.0)
|
||||
wisper (2.0.1)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
climate_control (~> 1.2)
|
||||
climate_control (~> 1.2.0)
|
||||
gitlab-cng!
|
||||
gitlab-styles (~> 12.0, >= 12.0.1)
|
||||
gitlab-styles (~> 13.0.0)
|
||||
pry (~> 0.14.2)
|
||||
rspec (~> 3.13)
|
||||
simplecov (~> 0.22.0)
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ module Gitlab
|
|||
default: 0,
|
||||
type: :numeric
|
||||
|
||||
super(name)
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ RSpec.describe Gitlab::Cng::Commands::Doctor do
|
|||
context "with all tools present" do
|
||||
it "does not raise an error", :aggregate_failures do
|
||||
expect do
|
||||
expect { invoke_command(command_name) }.not_to raise_error
|
||||
expect { invoke_command(command_name) }.not_to raise_error(SystemExit)
|
||||
end.to output(/All system dependencies are present/).to_stdout
|
||||
end
|
||||
end
|
||||
|
|
@ -38,7 +38,7 @@ RSpec.describe Gitlab::Cng::Commands::Doctor do
|
|||
|
||||
it "prints missing dependencies warning", :aggregate_failures do
|
||||
expect do
|
||||
expect { invoke_command(command_name) }.not_to raise_error
|
||||
expect { invoke_command(command_name) }.not_to raise_error(SystemExit)
|
||||
end.to output(/Following optional system dependecies are missing: tar/).to_stdout
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,100 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::BackgroundMigration::FixVulnerabilityReadsHasIssues, schema: 20230728020644, feature_category: :vulnerability_management do # rubocop:disable Layout/LineLength
|
||||
let(:namespaces) { table(:namespaces) }
|
||||
let(:projects) { table(:projects) }
|
||||
let(:users) { table(:users) }
|
||||
let(:scanners) { table(:vulnerability_scanners) }
|
||||
let(:vulnerabilities) { table(:vulnerabilities) }
|
||||
let(:vulnerability_reads) { table(:vulnerability_reads) }
|
||||
let(:work_item_types) { table(:work_item_types) }
|
||||
let(:issues) { table(:issues) }
|
||||
let(:vulnerability_issue_links) { table(:vulnerability_issue_links) }
|
||||
|
||||
let(:namespace) { namespaces.create!(name: 'user', path: 'user') }
|
||||
let(:project) { projects.create!(namespace_id: namespace.id, project_namespace_id: namespace.id) }
|
||||
let(:user) { users.create!(username: 'john_doe', email: 'johndoe@gitlab.com', projects_limit: 10) }
|
||||
let(:scanner) { scanners.create!(project_id: project.id, external_id: 'external_id', name: 'Test Scanner') }
|
||||
let(:work_item_type) { work_item_types.find_by(base_type: 0) } # base_type 0 is the `issue` type
|
||||
|
||||
let(:vulnerability_records) do
|
||||
Array.new(4).map do |_, n|
|
||||
vulnerabilities.create!(
|
||||
project_id: project.id,
|
||||
author_id: user.id,
|
||||
title: "vulnerability #{n}",
|
||||
severity: 1,
|
||||
confidence: 1,
|
||||
report_type: 1
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
let(:vulnerabilities_with_issues) { [vulnerability_records.first, vulnerability_records.third] }
|
||||
let(:vulnerabilities_without_issues) { vulnerability_records - vulnerabilities_with_issues }
|
||||
|
||||
let(:vulnerability_read_records) do
|
||||
vulnerability_records.map do |vulnerability|
|
||||
vulnerability_reads.create!(
|
||||
project_id: project.id,
|
||||
vulnerability_id: vulnerability.id,
|
||||
scanner_id: scanner.id,
|
||||
has_issues: false,
|
||||
severity: 1,
|
||||
report_type: 1,
|
||||
state: 1,
|
||||
uuid: SecureRandom.uuid
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
let!(:issue_links) do
|
||||
vulnerabilities_with_issues.map do |vulnerability|
|
||||
issue = issues.create!(
|
||||
title: vulnerability.title,
|
||||
author_id: user.id,
|
||||
project_id: project.id,
|
||||
confidential: true,
|
||||
work_item_type_id: work_item_type.id,
|
||||
namespace_id: namespace.id
|
||||
)
|
||||
|
||||
vulnerability_issue_links.create!(
|
||||
vulnerability_id: vulnerability.id,
|
||||
issue_id: issue.id
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def vulnerability_read_for(vulnerability)
|
||||
vulnerability_read_records.find { |read| read.vulnerability_id == vulnerability.id }
|
||||
end
|
||||
|
||||
subject(:perform_migration) do
|
||||
described_class.new(
|
||||
start_id: issue_links.first.vulnerability_id,
|
||||
end_id: issue_links.last.vulnerability_id,
|
||||
batch_table: :vulnerability_issue_links,
|
||||
batch_column: :vulnerability_id,
|
||||
sub_batch_size: issue_links.size,
|
||||
pause_ms: 0,
|
||||
connection: ActiveRecord::Base.connection
|
||||
).perform
|
||||
end
|
||||
|
||||
it 'only changes records with issue links' do
|
||||
expect(vulnerability_read_records).to all(have_attributes(has_issues: false))
|
||||
|
||||
perform_migration
|
||||
|
||||
vulnerabilities_with_issues.each do |vulnerability|
|
||||
expect(vulnerability_read_for(vulnerability).reload.has_issues).to eq(true)
|
||||
end
|
||||
|
||||
vulnerabilities_without_issues.each do |vulnerability|
|
||||
expect(vulnerability_read_for(vulnerability).reload.has_issues).to eq(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -35,24 +35,6 @@ RSpec.describe Ci::VariableValue, feature_category: :secrets_management do
|
|||
|
||||
it_behaves_like 'hidden variable'
|
||||
end
|
||||
|
||||
context 'when feature flag `ci_hidden_variables` is disabled' do
|
||||
before do
|
||||
stub_feature_flags(ci_hidden_variables: false)
|
||||
end
|
||||
|
||||
context 'and it is not hidden' do
|
||||
let(:is_hidden) { false }
|
||||
|
||||
it_behaves_like 'not hidden variable'
|
||||
end
|
||||
|
||||
context 'and it is hidden' do
|
||||
let(:is_hidden) { true }
|
||||
|
||||
it_behaves_like 'not hidden variable'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when variable is a group variable' do
|
||||
|
|
@ -70,24 +52,6 @@ RSpec.describe Ci::VariableValue, feature_category: :secrets_management do
|
|||
|
||||
it_behaves_like 'hidden variable'
|
||||
end
|
||||
|
||||
context 'when feature flag `ci_hidden_variables` is disabled' do
|
||||
before do
|
||||
stub_feature_flags(ci_hidden_variables: false)
|
||||
end
|
||||
|
||||
context 'and it is not hidden' do
|
||||
let(:is_hidden) { false }
|
||||
|
||||
it_behaves_like 'not hidden variable'
|
||||
end
|
||||
|
||||
context 'and it is hidden' do
|
||||
let(:is_hidden) { true }
|
||||
|
||||
it_behaves_like 'not hidden variable'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -18,25 +18,6 @@ RSpec.describe Ci::HidableVariable, feature_category: :secrets_management do
|
|||
describe '#validate_masked_and_hidden_on_create' do
|
||||
subject(:validate_create) { create_variable }
|
||||
|
||||
context 'when feature flag `ci_hidden_variables` is disabled' do
|
||||
before do
|
||||
stub_feature_flags(ci_hidden_variables: false)
|
||||
end
|
||||
|
||||
where(:pending_masked, :pending_hidden) do
|
||||
true | true
|
||||
false | false
|
||||
true | false
|
||||
false | true
|
||||
end
|
||||
|
||||
with_them do
|
||||
it 'passes the validation' do
|
||||
expect { validate_create }.not_to raise_error
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when masked and hidden attribute are allowed' do
|
||||
where(:pending_masked, :pending_hidden) do
|
||||
true | true
|
||||
|
|
@ -79,31 +60,6 @@ RSpec.describe Ci::HidableVariable, feature_category: :secrets_management do
|
|||
test_variable.update!(masked: pending_masked, hidden: pending_hidden)
|
||||
end
|
||||
|
||||
context 'when feature flag `ci_hidden_variables` is disabled' do
|
||||
before do
|
||||
stub_feature_flags(ci_hidden_variables: false)
|
||||
end
|
||||
|
||||
where(:stored_masked, :stored_hidden, :pending_masked,
|
||||
:pending_hidden) do
|
||||
true | false | true | false
|
||||
true | false | false | false
|
||||
true | true | true | true
|
||||
false | false | true | false
|
||||
true | true | true | false
|
||||
true | true | false | false
|
||||
false | false | true | true
|
||||
end
|
||||
|
||||
with_them do
|
||||
it 'passed the validation' do
|
||||
expect do
|
||||
validate_update
|
||||
end.not_to raise_error
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when update is allowed' do
|
||||
where(:stored_masked, :stored_hidden, :pending_masked,
|
||||
:pending_hidden) do
|
||||
|
|
|
|||
|
|
@ -56,25 +56,6 @@ RSpec.describe API::Ci::Variables, feature_category: :secrets_management do
|
|||
expect(json_response['description']).to be_nil
|
||||
expect(json_response['hidden']).to eq(true)
|
||||
end
|
||||
|
||||
context 'and feature flag `ci_hidden_variables is disabled`' do
|
||||
before do
|
||||
stub_feature_flags(ci_hidden_variables: false)
|
||||
end
|
||||
|
||||
it 'returns project variable details without changes' do
|
||||
get api("/projects/#{project.id}/variables/#{variable.key}", user)
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(json_response['value']).to eq(variable.value)
|
||||
expect(json_response['protected']).to eq(variable.protected?)
|
||||
expect(json_response['masked']).to eq(variable.masked?)
|
||||
expect(json_response['raw']).to eq(variable.raw?)
|
||||
expect(json_response['variable_type']).to eq('env_var')
|
||||
expect(json_response['description']).to be_nil
|
||||
expect(json_response['hidden']).to eq(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when variable is not hidden' do
|
||||
|
|
@ -93,25 +74,6 @@ RSpec.describe API::Ci::Variables, feature_category: :secrets_management do
|
|||
expect(json_response['description']).to be_nil
|
||||
expect(json_response['hidden']).to eq(false)
|
||||
end
|
||||
|
||||
context 'and feature flag `ci_hidden_variables is disabled`' do
|
||||
before do
|
||||
stub_feature_flags(ci_hidden_variables: false)
|
||||
end
|
||||
|
||||
it 'returns project variable details' do
|
||||
get api("/projects/#{project.id}/variables/#{variable.key}", user)
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(json_response['value']).to eq(variable.value)
|
||||
expect(json_response['protected']).to eq(variable.protected?)
|
||||
expect(json_response['masked']).to eq(variable.masked?)
|
||||
expect(json_response['raw']).to eq(variable.raw?)
|
||||
expect(json_response['variable_type']).to eq('env_var')
|
||||
expect(json_response['description']).to be_nil
|
||||
expect(json_response['hidden']).to eq(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'responds with 404 Not Found if requesting non-existing variable' do
|
||||
|
|
|
|||
|
|
@ -88,39 +88,6 @@ RSpec.describe 'Query.group(fullPath).ciVariables', feature_category: :secrets_m
|
|||
'environmentScope' => 'staging'
|
||||
})
|
||||
end
|
||||
|
||||
context 'when feature flag `ci_hidden_variables is disabled`' do
|
||||
before do
|
||||
stub_feature_flags(ci_hidden_variables: false)
|
||||
end
|
||||
|
||||
it "returns the value even if it is hidden" do
|
||||
variable = create(:ci_group_variable,
|
||||
group: group,
|
||||
key: 'TEST_VAR',
|
||||
value: 'TestValue',
|
||||
masked: true,
|
||||
hidden: true,
|
||||
protected: true,
|
||||
raw: false,
|
||||
environment_scope: 'staging')
|
||||
|
||||
post_graphql(query, current_user: user)
|
||||
|
||||
expect(graphql_data.dig('group', 'ciVariables', 'limit')).to be(30000)
|
||||
expect(graphql_data.dig('group', 'ciVariables', 'nodes')).to contain_exactly({
|
||||
'id' => variable.to_global_id.to_s,
|
||||
'key' => 'TEST_VAR',
|
||||
'value' => 'TestValue',
|
||||
'variableType' => 'ENV_VAR',
|
||||
'masked' => true,
|
||||
'protected' => true,
|
||||
'hidden' => true,
|
||||
'raw' => false,
|
||||
'environmentScope' => 'staging'
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the user cannot administer the group' do
|
||||
|
|
|
|||
|
|
@ -92,41 +92,6 @@ RSpec.describe 'Query.project(fullPath).ciVariables', feature_category: :secrets
|
|||
'environmentScope' => 'production'
|
||||
})
|
||||
end
|
||||
|
||||
context 'when feature flag `ci_hidden_variables is disabled`' do
|
||||
before do
|
||||
stub_feature_flags(ci_hidden_variables: false)
|
||||
end
|
||||
|
||||
it "returns the value even it it is hidden" do
|
||||
variable = create(
|
||||
:ci_variable,
|
||||
project: project,
|
||||
key: 'TEST_VAR',
|
||||
value: 'TestVariable',
|
||||
masked: true,
|
||||
hidden: true,
|
||||
protected: true,
|
||||
raw: false,
|
||||
environment_scope: 'production'
|
||||
)
|
||||
|
||||
post_graphql(query, current_user: user)
|
||||
|
||||
expect(graphql_data.dig('project', 'ciVariables', 'limit')).to be(8000)
|
||||
expect(graphql_data.dig('project', 'ciVariables', 'nodes')).to contain_exactly({
|
||||
'id' => variable.to_global_id.to_s,
|
||||
'key' => 'TEST_VAR',
|
||||
'value' => 'TestVariable',
|
||||
'variableType' => 'ENV_VAR',
|
||||
'masked' => true,
|
||||
'protected' => true,
|
||||
'hidden' => true,
|
||||
'raw' => false,
|
||||
'environmentScope' => 'production'
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the user cannot administer builds' do
|
||||
|
|
|
|||
|
|
@ -61,24 +61,6 @@ RSpec.describe API::GroupVariables, feature_category: :secrets_management do
|
|||
expect(json_response['environment_scope']).to eq(variable.environment_scope)
|
||||
expect(json_response['description']).to be_nil
|
||||
end
|
||||
|
||||
context 'and feature flag `ci_hidden_variables is disabled`' do
|
||||
before do
|
||||
stub_feature_flags(ci_hidden_variables: false)
|
||||
end
|
||||
|
||||
it 'returns group variable details without changes' do
|
||||
get api("/groups/#{group.id}/variables/#{variable.key}", user)
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(json_response['value']).to eq(variable.value)
|
||||
expect(json_response['protected']).to eq(variable.protected?)
|
||||
expect(json_response['hidden']).to eq(true)
|
||||
expect(json_response['variable_type']).to eq(variable.variable_type)
|
||||
expect(json_response['environment_scope']).to eq(variable.environment_scope)
|
||||
expect(json_response['description']).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when variable is not hidden' do
|
||||
|
|
@ -95,24 +77,6 @@ RSpec.describe API::GroupVariables, feature_category: :secrets_management do
|
|||
expect(json_response['environment_scope']).to eq(variable.environment_scope)
|
||||
expect(json_response['description']).to be_nil
|
||||
end
|
||||
|
||||
context 'and feature flag `ci_hidden_variables is disabled`' do
|
||||
before do
|
||||
stub_feature_flags(ci_hidden_variables: false)
|
||||
end
|
||||
|
||||
it 'returns group variable details' do
|
||||
get api("/groups/#{group.id}/variables/#{variable.key}", user)
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(json_response['value']).to eq(variable.value)
|
||||
expect(json_response['protected']).to eq(variable.protected?)
|
||||
expect(json_response['hidden']).to eq(false)
|
||||
expect(json_response['variable_type']).to eq(variable.variable_type)
|
||||
expect(json_response['environment_scope']).to eq(variable.environment_scope)
|
||||
expect(json_response['description']).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'responds with 404 Not Found if requesting non-existing variable' do
|
||||
|
|
|
|||
|
|
@ -11,14 +11,6 @@ RSpec.shared_examples 'search results filtered by labels' do
|
|||
ensure_elasticsearch_index!
|
||||
end
|
||||
|
||||
context 'when labels filter is provided' do
|
||||
let(:filters) { { labels: [project_label.id] } }
|
||||
|
||||
it 'filters by labels', :sidekiq_inline do
|
||||
expect(results.objects(scope)).to contain_exactly(labeled_issue)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when label_name filter is provided' do
|
||||
let(:filters) { { label_name: [project_label.name] } }
|
||||
|
||||
|
|
@ -26,12 +18,4 @@ RSpec.shared_examples 'search results filtered by labels' do
|
|||
expect(results.objects(scope)).to contain_exactly(labeled_issue)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when both labels and label_name filters are provided' do
|
||||
let(:filters) { { labels: [0], label_name: [project_label.name] } }
|
||||
|
||||
it 'uses label_name filter and filters by labels', :sidekiq_inline do
|
||||
expect(results.objects(scope)).to contain_exactly(labeled_issue)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in New Issue