Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2023-04-12 09:14:57 +00:00
parent 913af9b06e
commit 60e7627c99
57 changed files with 950 additions and 136 deletions

View File

@ -1228,7 +1228,7 @@ lib/gitlab/checks/** @proglottis @toon
[Verify] @gitlab-org/maintainers/cicd-verify
# Verify Backend
/**/app/**/ci/
/**/app/**/ci/
/**/lib/**/ci/
/**/spec/**/ci/
/**/app/**/merge_trains/
@ -1347,7 +1347,7 @@ lib/gitlab/checks/** @proglottis @toon
/**/javascripts/jobs/ @gitlab-org/ci-cd/verify/frontend
/**/javascripts/token_access/ @gitlab-org/ci-cd/verify/frontend
/**/javascripts/admin/application_settings/runner_token_expiration/ @gitlab-org/ci-cd/verify/frontend
/**/javascripts/usage_quotas/pipelines/ @gitlab-org/ci-cd/verify/frontend @fulfillment-group/utilization-group/fe
/**/javascripts/usage_quotas/pipelines/ @gitlab-org/ci-cd/verify/frontend @sheldonled @aalakkad @kpalchyk
[Manage::Workspace]
lib/api/entities/basic_project_details.rb @gitlab-org/manage/manage-workspace/backend-approvers
@ -1419,9 +1419,9 @@ ee/lib/ee/api/entities/project.rb @gitlab-org/manage/manage-workspace/backend-ap
/lib/gitlab/audit_json_logger.rb @gitlab-org/govern/compliance
[Fulfillment::Utilization]
/ee/app/assets/javascripts/usage_quotas/components/ @fulfillment-group/utilization-group/fe
/ee/app/assets/javascripts/usage_quotas/seats/ @fulfillment-group/utilization-group/fe
/ee/app/assets/javascripts/usage_quotas/storage/ @fulfillment-group/utilization-group/fe
/ee/app/assets/javascripts/usage_quotas/components/ @sheldonled @aalakkad @kpalchyk
/ee/app/assets/javascripts/usage_quotas/seats/ @sheldonled @aalakkad @kpalchyk
/ee/app/assets/javascripts/usage_quotas/storage/ @sheldonled @aalakkad @kpalchyk
[Manage::Foundations]
/lib/sidebars/ @gitlab-org/manage/foundations/engineering

View File

@ -1 +1 @@
a5d056f2e268a775f6742046e284f33bae43078b
b8190668d147784e8be4a379b33f691363e08a0f

View File

@ -132,7 +132,10 @@ export default {
},
watch: {
descriptionHtml(newDescription, oldDescription) {
if (!this.initialUpdate && newDescription !== oldDescription) {
if (
!this.initialUpdate &&
this.stripClientState(newDescription) !== this.stripClientState(oldDescription)
) {
this.animateChange();
} else {
this.initialUpdate = false;
@ -321,6 +324,9 @@ export default {
listItem.append(element);
}
},
stripClientState(description) {
return description.replaceAll('<details open="true">', '<details>');
},
async createTask({ taskTitle, taskDescription, oldDescription }) {
try {
const { title, description } = extractTaskTitleAndDescription(taskTitle, taskDescription);

View File

@ -6,6 +6,7 @@ import {
REPORT_TYPE_SAST_IAC,
REPORT_TYPE_DAST,
REPORT_TYPE_DAST_PROFILES,
REPORT_TYPE_BREACH_AND_ATTACK_SIMULATION,
REPORT_TYPE_SECRET_DETECTION,
REPORT_TYPE_DEPENDENCY_SCANNING,
REPORT_TYPE_CONTAINER_SCANNING,
@ -67,6 +68,30 @@ export const DAST_PROFILES_DESCRIPTION = s__(
);
export const DAST_PROFILES_CONFIG_TEXT = s__('SecurityConfiguration|Manage profiles');
export const BAS_BADGE_TEXT = s__('SecurityConfiguration|Incubating feature');
export const BAS_BADGE_TOOLTIP = s__(
'SecurityConfiguration|Breach and Attack Simulation is an incubating feature extending existing security testing by simulating adversary activity.',
);
export const BAS_DESCRIPTION = s__(
'SecurityConfiguration|Simulate breach and attack scenarios against your running application by attempting to detect and exploit known vulnerabilities.',
);
export const BAS_HELP_PATH = helpPagePath(
'user/application_security/breach_and_attack_simulation/index',
);
export const BAS_NAME = s__('SecurityConfiguration|Breach and Attack Simulation (BAS)');
export const BAS_SHORT_NAME = s__('SecurityConfiguration|BAS');
export const BAS_DAST_FEATURE_FLAG_DESCRIPTION = s__(
'SecurityConfiguration|Enable incubating Breach and Attack Simulation focused features such as callback attacks in your DAST scans.',
);
export const BAS_DAST_FEATURE_FLAG_HELP_PATH = helpPagePath(
'user/application_security/breach_and_attack_simulation/index',
{ anchor: 'extend-dynamic-application-security-testing-dast' },
);
export const BAS_DAST_FEATURE_FLAG_NAME = s__(
'SecurityConfiguration|Out-of-Band Application Security Testing (OAST)',
);
export const SECRET_DETECTION_NAME = __('Secret Detection');
export const SECRET_DETECTION_DESCRIPTION = __(
'Analyze your source code and git history for secrets.',
@ -142,6 +167,7 @@ export const SCANNER_NAMES_MAP = {
COVERAGE_FUZZING: COVERAGE_FUZZING_NAME,
SECRET_DETECTION: SECRET_DETECTION_NAME,
DEPENDENCY_SCANNING: DEPENDENCY_SCANNING_NAME,
BAS: BAS_SHORT_NAME,
GENERIC: s__('ciReport|Manually added'),
};
@ -223,6 +249,25 @@ export const securityFeatures = [
configurationText: CORPUS_MANAGEMENT_CONFIG_TEXT,
},
},
{
anchor: 'bas',
badge: {
alwaysDisplay: true,
text: BAS_BADGE_TEXT,
tooltipText: BAS_BADGE_TOOLTIP,
variant: 'info',
},
description: BAS_DESCRIPTION,
name: BAS_NAME,
helpPath: BAS_HELP_PATH,
secondary: {
configurationHelpPath: BAS_DAST_FEATURE_FLAG_HELP_PATH,
description: BAS_DAST_FEATURE_FLAG_DESCRIPTION,
name: BAS_DAST_FEATURE_FLAG_NAME,
},
shortName: BAS_SHORT_NAME,
type: REPORT_TYPE_BREACH_AND_ATTACK_SIMULATION,
},
];
export const complianceFeatures = [

View File

@ -1,7 +1,10 @@
<script>
import { GlButton, GlCard, GlIcon, GlLink } from '@gitlab/ui';
import { __, s__, sprintf } from '~/locale';
import { REPORT_TYPE_SAST_IAC } from '~/vue_shared/security_reports/constants';
import {
REPORT_TYPE_BREACH_AND_ATTACK_SIMULATION,
REPORT_TYPE_SAST_IAC,
} from '~/vue_shared/security_reports/constants';
import ManageViaMr from '~/vue_shared/security_configuration/components/manage_via_mr.vue';
import FeatureCardBadge from './feature_card_badge.vue';
@ -68,8 +71,7 @@ export default {
};
},
hasSecondary() {
const { name, description, configurationText } = this.feature.secondary ?? {};
return Boolean(name && description && configurationText);
return Boolean(this.feature.secondary);
},
// This condition is a temporary hack to not display any wrong information
// until this BE Bug is fixed: https://gitlab.com/gitlab-org/gitlab/-/issues/350307.
@ -78,7 +80,17 @@ export default {
return this.feature.type !== REPORT_TYPE_SAST_IAC;
},
hasBadge() {
return Boolean(this.available && this.feature.badge?.text);
const shouldDisplay = this.available || this.feature.badge?.alwaysDisplay;
return Boolean(shouldDisplay && this.feature.badge?.text);
},
hasEnabledStatus() {
return (
this.isNotSastIACTemporaryHack &&
this.feature.type !== REPORT_TYPE_BREACH_AND_ATTACK_SIMULATION
);
},
showSecondaryConfigurationHelpPath() {
return Boolean(this.available && this.feature.secondary?.configurationHelpPath);
},
},
methods: {
@ -118,19 +130,25 @@ export default {
:badge-href="feature.badge.badgeHref"
/>
<template v-if="enabled">
<span>
<gl-icon name="check-circle-filled" />
<span class="gl-text-green-700">{{ $options.i18n.enabled }}</span>
</span>
<template v-if="hasEnabledStatus">
<template v-if="enabled">
<span>
<gl-icon name="check-circle-filled" />
<span class="gl-text-green-700">{{ $options.i18n.enabled }}</span>
</span>
</template>
<template v-else-if="available">
<span>{{ $options.i18n.notEnabled }}</span>
</template>
<template v-else>
{{ $options.i18n.availableWith }}
</template>
</template>
<template v-else-if="available">
<span>{{ $options.i18n.notEnabled }}</span>
</template>
<template v-else>
{{ $options.i18n.availableWith }}
<template v-else-if="!available">
<span>{{ $options.i18n.availableWith }}</span>
</template>
</div>
</div>
@ -186,6 +204,16 @@ export default {
>
{{ feature.secondary.configurationText }}
</gl-button>
<gl-button
v-else-if="showSecondaryConfigurationHelpPath"
icon="external-link"
:href="feature.secondary.configurationHelpPath"
category="secondary"
class="gl-mt-5"
>
{{ $options.i18n.configurationGuide }}
</gl-button>
</div>
</gl-card>
</template>

View File

@ -1,5 +1,6 @@
export const SCOPED_LABEL_DELIMITER = '::';
export const DEBOUNCE_DROPDOWN_DELAY = 200;
export const DEFAULT_LABEL_COLOR = '#6699cc';
export const DropdownVariant = {
Sidebar: 'sidebar',

View File

@ -13,6 +13,7 @@ import { WORKSPACE_GROUP } from '~/issues/constants';
import { __ } from '~/locale';
import { workspaceLabelsQueries } from '../../../constants';
import createLabelMutation from './graphql/create_label.mutation.graphql';
import { DEFAULT_LABEL_COLOR } from './constants';
const errorMessage = __('Error creating label.');
@ -44,11 +45,16 @@ export default {
type: String,
required: true,
},
searchKey: {
type: String,
required: false,
default: '',
},
},
data() {
return {
labelTitle: '',
selectedColor: '',
labelTitle: this.searchKey,
selectedColor: DEFAULT_LABEL_COLOR,
labelCreateInProgress: false,
error: undefined,
};

View File

@ -20,6 +20,7 @@ export const REPORT_TYPE_SAST = 'sast';
export const REPORT_TYPE_SAST_IAC = 'sast_iac';
export const REPORT_TYPE_DAST = 'dast';
export const REPORT_TYPE_DAST_PROFILES = 'dast_profiles';
export const REPORT_TYPE_BREACH_AND_ATTACK_SIMULATION = 'breach_and_attack_simulation';
export const REPORT_TYPE_SECRET_DETECTION = 'secret_detection';
export const REPORT_TYPE_DEPENDENCY_SCANNING = 'dependency_scanning';
export const REPORT_TYPE_CONTAINER_SCANNING = 'container_scanning';

View File

@ -13,7 +13,7 @@
module Security
class SecurityJobsFinder < JobsFinder
def self.allowed_job_types
[:sast, :sast_iac, :dast, :dependency_scanning, :container_scanning, :secret_detection, :coverage_fuzzing, :api_fuzzing, :cluster_image_scanning]
[:sast, :sast_iac, :breach_and_attack_simulation, :dast, :dependency_scanning, :container_scanning, :secret_detection, :coverage_fuzzing, :api_fuzzing, :cluster_image_scanning]
end
end
end

View File

@ -6,7 +6,8 @@ module Types
graphql_name 'WorkItemPermissions'
description 'Check permissions for the current user on a work item'
abilities :read_work_item, :update_work_item, :delete_work_item, :admin_work_item
abilities :read_work_item, :update_work_item, :delete_work_item,
:admin_work_item, :admin_parent_link
end
end
end

View File

@ -15,6 +15,14 @@ module Ci
scope :for_projects, ->(project_ids) { where(project_id: project_ids) }
delegate :avatar_path, :description, :name, to: :project
def versions
project.releases.order_released_desc
end
def latest_version
versions.first
end
end
end
end

View File

@ -6,6 +6,10 @@
# See Ruby-lang issue https://bugs.ruby-lang.org/issues/17542
# See issue on GitLab https://gitlab.com/gitlab-org/gitlab/-/issues/289836
# This file can be removed once Ruby 3.0 is no longer supported:
# https://gitlab.com/gitlab-org/gitlab/-/issues/396223
return if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new(3.1)
module Net
class HTTP < Protocol
def proxy_user

View File

@ -163,6 +163,7 @@ InitializerConnections.raise_if_new_database_connection do
draw :jira_connect
Gitlab.ee do
draw :remote_development
draw :security
draw :smartcard
draw :trial

View File

@ -0,0 +1,83 @@
# frozen_string_literal: true
class SwapIssueUserMentionsNoteIdToBigintForGitlabDotCom < Gitlab::Database::Migration[2.1]
include Gitlab::Database::MigrationHelpers::ConvertToBigint
disable_ddl_transaction!
TABLE_NAME = 'issue_user_mentions'
def up
return unless should_run?
swap
end
def down
return unless should_run?
swap
add_concurrent_index TABLE_NAME, :note_id_convert_to_bigint, unique: true,
name: 'index_issue_user_mentions_on_note_id_convert_to_bigint',
where: 'note_id_convert_to_bigint IS NOT NULL'
add_concurrent_foreign_key TABLE_NAME, :notes, column: :note_id_convert_to_bigint,
name: 'fk_issue_user_mentions_note_id_convert_to_bigint',
on_delete: :cascade,
validate: false
end
def swap
# This will replace the existing index_issue_user_mentions_on_note_id
add_concurrent_index TABLE_NAME, :note_id_convert_to_bigint, unique: true,
name: 'index_issue_user_mentions_on_note_id_convert_to_bigint',
where: 'note_id_convert_to_bigint IS NOT NULL'
# This will replace the existing issue_user_mentions_on_issue_id_and_note_id_index
add_concurrent_index TABLE_NAME, [:issue_id, :note_id_convert_to_bigint], unique: true,
name: 'tmp_issue_user_mentions_on_issue_id_and_note_id_index'
# This will replace the existing issue_user_mentions_on_issue_id_index
add_concurrent_index TABLE_NAME, :issue_id, unique: true,
name: 'tmp_issue_user_mentions_on_issue_id_index',
where: 'note_id_convert_to_bigint IS NULL'
# This will replace the existing fk_rails_3861d9fefa
add_concurrent_foreign_key TABLE_NAME, :notes, column: :note_id_convert_to_bigint,
name: 'fk_issue_user_mentions_note_id_convert_to_bigint',
on_delete: :cascade
with_lock_retries(raise_on_exhaustion: true) do
execute "LOCK TABLE notes, #{TABLE_NAME} IN ACCESS EXCLUSIVE MODE"
execute "ALTER TABLE #{TABLE_NAME} RENAME COLUMN note_id TO note_id_tmp"
execute "ALTER TABLE #{TABLE_NAME} RENAME COLUMN note_id_convert_to_bigint TO note_id"
execute "ALTER TABLE #{TABLE_NAME} RENAME COLUMN note_id_tmp TO note_id_convert_to_bigint"
function_name = Gitlab::Database::UnidirectionalCopyTrigger
.on_table(TABLE_NAME, connection: connection)
.name(:note_id, :note_id_convert_to_bigint)
execute "ALTER FUNCTION #{quote_table_name(function_name)} RESET ALL"
execute 'DROP INDEX IF EXISTS index_issue_user_mentions_on_note_id'
rename_index TABLE_NAME, 'index_issue_user_mentions_on_note_id_convert_to_bigint',
'index_issue_user_mentions_on_note_id'
execute 'DROP INDEX IF EXISTS issue_user_mentions_on_issue_id_and_note_id_index'
rename_index TABLE_NAME, 'tmp_issue_user_mentions_on_issue_id_and_note_id_index',
'issue_user_mentions_on_issue_id_and_note_id_index'
execute 'DROP INDEX IF EXISTS issue_user_mentions_on_issue_id_index'
rename_index TABLE_NAME, 'tmp_issue_user_mentions_on_issue_id_index',
'issue_user_mentions_on_issue_id_index'
execute "ALTER TABLE #{TABLE_NAME} DROP CONSTRAINT IF EXISTS fk_rails_3861d9fefa"
rename_constraint(TABLE_NAME, 'fk_issue_user_mentions_note_id_convert_to_bigint', 'fk_rails_3861d9fefa')
end
end
def should_run?
com_or_dev_or_test_but_not_jh?
end
end

View File

@ -0,0 +1,15 @@
# frozen_string_literal: true
class AsyncValidateFkProjectsCreatorId < Gitlab::Database::Migration[2.1]
TABLE_NAME = :projects
COLUMN_NAME = :creator_id
FK_NAME = :fk_03ec10b0d3
def up
prepare_async_foreign_key_validation TABLE_NAME, COLUMN_NAME, name: FK_NAME
end
def down
unprepare_async_foreign_key_validation TABLE_NAME, COLUMN_NAME, name: FK_NAME
end
end

View File

@ -0,0 +1 @@
3387abc29b2c499b8c1fafa8543f504d02cbca189b38f26a3776786416fa5820

View File

@ -0,0 +1 @@
4955274e8f504af6e06432bd195e64eb6c520118a50f7da19af2fcf5872459cf

View File

@ -17365,11 +17365,11 @@ ALTER SEQUENCE issue_tracker_data_id_seq OWNED BY issue_tracker_data.id;
CREATE TABLE issue_user_mentions (
id bigint NOT NULL,
issue_id integer NOT NULL,
note_id integer,
note_id_convert_to_bigint integer,
mentioned_users_ids integer[],
mentioned_projects_ids integer[],
mentioned_groups_ids integer[],
note_id_convert_to_bigint bigint
note_id bigint
);
CREATE SEQUENCE issue_user_mentions_id_seq
@ -30802,8 +30802,6 @@ CREATE INDEX index_issue_tracker_data_on_integration_id ON issue_tracker_data US
CREATE UNIQUE INDEX index_issue_user_mentions_on_note_id ON issue_user_mentions USING btree (note_id) WHERE (note_id IS NOT NULL);
CREATE UNIQUE INDEX index_issue_user_mentions_on_note_id_convert_to_bigint ON issue_user_mentions USING btree (note_id_convert_to_bigint) WHERE (note_id_convert_to_bigint IS NOT NULL);
CREATE INDEX index_issues_on_author_id ON issues USING btree (author_id);
CREATE INDEX index_issues_on_author_id_and_id_and_created_at ON issues USING btree (author_id, id, created_at);
@ -35269,9 +35267,6 @@ ALTER TABLE ONLY issues
ALTER TABLE ONLY geo_event_log
ADD CONSTRAINT fk_geo_event_log_on_geo_event_id FOREIGN KEY (geo_event_id) REFERENCES geo_events(id) ON DELETE CASCADE;
ALTER TABLE ONLY issue_user_mentions
ADD CONSTRAINT fk_issue_user_mentions_note_id_convert_to_bigint FOREIGN KEY (note_id_convert_to_bigint) REFERENCES notes(id) ON DELETE CASCADE NOT VALID;
ALTER TABLE ONLY ml_candidate_metrics
ADD CONSTRAINT fk_ml_candidate_metrics_on_candidate_id FOREIGN KEY (candidate_id) REFERENCES ml_candidates(id) ON DELETE CASCADE;

View File

@ -216,6 +216,8 @@ The following actions on groups generate group audit events:
[Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/377877) in GitLab 15.6.
- An environment is protected or unprotected.
[Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/216164) in GitLab 15.8.
- Changes to Code Suggestions.
[Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/405295) in GitLab 15.11.
### Project events

View File

@ -22517,6 +22517,7 @@ Check permissions for the current user on a work item.
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="workitempermissionsadminparentlink"></a>`adminParentLink` | [`Boolean!`](#boolean) | Indicates the user can perform `admin_parent_link` on this resource. |
| <a id="workitempermissionsadminworkitem"></a>`adminWorkItem` | [`Boolean!`](#boolean) | Indicates the user can perform `admin_work_item` on this resource. |
| <a id="workitempermissionsdeleteworkitem"></a>`deleteWorkItem` | [`Boolean!`](#boolean) | Indicates the user can perform `delete_work_item` on this resource. |
| <a id="workitempermissionsreadworkitem"></a>`readWorkItem` | [`Boolean!`](#boolean) | Indicates the user can perform `read_work_item` on this resource. |
@ -24529,6 +24530,7 @@ The status of the security scan.
| Value | Description |
| ----- | ----------- |
| <a id="securityreporttypeenumapi_fuzzing"></a>`API_FUZZING` | API FUZZING scan report. |
| <a id="securityreporttypeenumbreach_and_attack_simulation"></a>`BREACH_AND_ATTACK_SIMULATION` | BREACH AND ATTACK SIMULATION scan report. |
| <a id="securityreporttypeenumcluster_image_scanning"></a>`CLUSTER_IMAGE_SCANNING` | CLUSTER IMAGE SCANNING scan report. |
| <a id="securityreporttypeenumcontainer_scanning"></a>`CONTAINER_SCANNING` | CONTAINER SCANNING scan report. |
| <a id="securityreporttypeenumcoverage_fuzzing"></a>`COVERAGE_FUZZING` | COVERAGE FUZZING scan report. |
@ -24545,6 +24547,7 @@ The type of the security scanner.
| Value | Description |
| ----- | ----------- |
| <a id="securityscannertypeapi_fuzzing"></a>`API_FUZZING` | API Fuzzing scanner. |
| <a id="securityscannertypebreach_and_attack_simulation"></a>`BREACH_AND_ATTACK_SIMULATION` | Breach And Attack Simulation scanner. |
| <a id="securityscannertypecluster_image_scanning"></a>`CLUSTER_IMAGE_SCANNING` | Cluster Image Scanning scanner. |
| <a id="securityscannertypecontainer_scanning"></a>`CONTAINER_SCANNING` | Container Scanning scanner. |
| <a id="securityscannertypecoverage_fuzzing"></a>`COVERAGE_FUZZING` | Coverage Fuzzing scanner. |

View File

@ -216,12 +216,12 @@ sequence diagram.
![GitLab Runner Autoscaling Overview](gitlab-autoscaling-overview.png)
On the diagrams above we see that currently a GitLab Runner Manager runs on a
On the diagrams above we see that currently a runner manager runs on a
machine that has access to a cloud provider's API. It is using Docker Machine
to provision new Virtual Machines with Docker Engine installed and it
configures the Docker daemon there to allow external authenticated requests. It
stores credentials to such ephemeral Docker environments on disk. Once a
machine has been provisioned and made available for GitLab Runner Manager to
machine has been provisioned and made available for the runner manager to
run builds, it is using one of the existing executors to run a user-provided
script. In auto-scaling, this is typically done using the Docker executor.
@ -283,7 +283,7 @@ coupled with the VM lifecycle and job routing logic. Creating idle capacity
happens as a side-effect of calling [`Acquire`](https://gitlab.com/gitlab-org/gitlab-runner/-/blob/267f40d871cd260dd063f7fbd36a921fedc62241/executors/docker/machine/provider.go#L449) on the `machineProvider` while binding a job to a VM.
There is also no current abstraction for in-VM job execution. VM-specific
commands are generated by the Runner Manager using the [`GenerateShellScript`](https://gitlab.com/gitlab-org/gitlab-runner/-/blob/267f40d871cd260dd063f7fbd36a921fedc62241/common/build.go#L336)
commands are generated by the runner manager using the [`GenerateShellScript`](https://gitlab.com/gitlab-org/gitlab-runner/-/blob/267f40d871cd260dd063f7fbd36a921fedc62241/common/build.go#L336)
function and [injected](https://gitlab.com/gitlab-org/gitlab-runner/-/blob/267f40d871cd260dd063f7fbd36a921fedc62241/common/build.go#L373)
into the VM as the manager drives the job execution stages.

View File

@ -67,7 +67,7 @@ is used.
To prevent artifacts from expiring, you can select **Keep** from the job details page.
The option is not available when an artifact has no expiry set.
### With CI/CD variables to define the artifacts name
### With a dynamically defined name
You can use [CI/CD variables](../variables/index.md) to dynamically define the
artifacts file's name.
@ -186,7 +186,7 @@ job:
dependencies: []
```
## View all job artifacts
## View all job artifacts in a project
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/254938) in GitLab 15.11 [with a flag](../../administration/feature_flags.md) named `artifacts_management_page`. Disabled by default.
@ -202,21 +202,18 @@ You can download or delete individual artifacts from this list.
## Download job artifacts
You can download job artifacts by selecting **Download** (**{download}**) from:
You can download job artifacts from:
- Any **Pipelines** list, to the right of the pipeline select **Download artifacts** (**{download}**).
- Any **Jobs** list, to the right of the job select **Download artifacts** (**{download}**).
- A job's detail page, on the right of the page select **Download**.
- A merge request **Overview** page, to the right of the latest pipeline select **Artifacts** (**{download}**).
- The [**Artifacts**](#view-all-job-artifacts) page, to the right of the job select **Download** (**{download}**).
- If the **Browse** (**{folder-open}**) option is available, you can browse the contents of the artifacts
from the UI without downloading the artifact. You can also select **Download artifacts archive**
from the artifacts browser.
- Any **Pipelines** list. On the right of the pipeline, select **Download artifacts** (**{download}**).
- Any **Jobs** list. On the right of the job, select **Download artifacts** (**{download}**).
- A job's detail page. On the right of the page, select **Download**.
- A merge request **Overview** page. On the right of the latest pipeline, select **Artifacts** (**{download}**).
- The [**Artifacts**](#view-all-job-artifacts-in-a-project) page. On the right of the job, select **Download** (**{download}**).
- The [artifacts browser](#browse-the-contents-of-the-artifacts-archive). On the top of the page,
select **Download artifacts archive** (**{download}**).
If [GitLab Pages](../../administration/pages/index.md) is enabled in the project, you can preview
HTML files in the artifacts directly in your browser. If the project is internal or private, you must
enable [GitLab Pages access control](../../administration/pages/index.md#access-control) to preview
HTML files.
[Report artifacts](../yaml/artifacts_reports.md) can only be downloaded from the **Pipelines** list
or **Artifacts** page.
You can download job artifacts from the latest successful pipeline by using [the job artifacts API](../../api/job_artifacts.md).
You cannot download [artifact reports](../yaml/artifacts_reports.md) with the job artifacts API,
@ -245,7 +242,21 @@ Artifacts for [parent and child pipelines](../pipelines/downstream_pipelines.md#
are searched in hierarchical order from parent to child. For example, if both parent and
child pipelines have a job with the same name, the job artifacts from the parent pipeline are returned.
### From a URL with the artifacts browser
## Browse the contents of the artifacts archive
You can browse the contents of the artifacts from the UI without downloading the artifact locally,
from:
- Any **Jobs** list. On the right of the job, select **Browse** (**{folder-open}**).
- A job's detail page. On the right of the page, select **Browse**.
- The **Artifacts** page. On the right of the job, select **Browse** (**{folder-open}**).
If [GitLab Pages](../../administration/pages/index.md) is enabled in the project, you can preview
HTML files in the artifacts directly in your browser. If the project is internal or private, you must
enable [GitLab Pages access control](../../administration/pages/index.md#access-control) to preview
HTML files.
### From a URL
You can browse the job artifacts of the latest successful pipeline for a specific job
with a publicly accessible URL.

View File

@ -803,7 +803,7 @@ variables:
NOTE:
Zip archives are the only supported artifact type. Follow [the issue for details](https://gitlab.com/gitlab-org/gitlab/-/issues/367203).
GitLab Runner can generate and produce attestation metadata for all build artifacts. To enable this feature, you must set the `RUNNER_GENERATE_ARTIFACTS_METADATA` environment variable to `true`. This variable can either be set globally or it can be set for individual jobs. The metadata is in rendered in a plain text `.json` file that's stored with the artifact. The filename is as follows: `{ARTIFACT_NAME}-metadata.json` where `ARTIFACT_NAME` is what was defined as the [name for the artifact](../jobs/job_artifacts.md#with-cicd-variables-to-define-the-artifacts-name) in the CI file. The filename, however, defaults to `artifacts-metadata.json` if no name was given to the build artifacts.
GitLab Runner can generate and produce attestation metadata for all build artifacts. To enable this feature, you must set the `RUNNER_GENERATE_ARTIFACTS_METADATA` environment variable to `true`. This variable can either be set globally or it can be set for individual jobs. The metadata is in rendered in a plain text `.json` file that's stored with the artifact. The filename is as follows: `{ARTIFACT_NAME}-metadata.json` where `ARTIFACT_NAME` is what was defined as the [name for the artifact](../jobs/job_artifacts.md#with-a-dynamically-defined-name) in the CI file. The filename, however, defaults to `artifacts-metadata.json` if no name was given to the build artifacts.
### Attestation format

View File

@ -22,7 +22,7 @@ in your [subscription plan](https://about.gitlab.com/pricing/).
GitLab SaaS runners on Linux and Windows run on Google Compute Platform. The [Google Infrastructure Security Design Overview whitepaper](https://cloud.google.com/docs/security/infrastructure/design/resources/google_infrastructure_whitepaper_fa.pdf) provides an overview of how Google designs security into its technical infrastructure. The GitLab [Trust Center](https://about.gitlab.com/security/) and [GitLab Security Compliance Controls](https://about.staging.gitlab.com/handbook/engineering/security/security-assurance/security-compliance/sec-controls.html) pages provide an overview of the security and compliance controls that govern the GitLab SaaS runners.
The runner that serves as a Runner Manager automatically initiates the creation and deletion of the virtual machines (VMs) used for CI jobs. When the Runner Manager picks up a GitLab SaaS CI job, it automatically executes that job on a new VM. There is no human or manual intervention in this process. The following section provides an overview of the additional built-in layers that harden the security of the GitLab Runner SaaS CI build environment.
The runner that serves as a runner manager automatically initiates the creation and deletion of the virtual machines (VMs) used for CI jobs. When the runner manager picks up a GitLab SaaS CI job, it automatically executes that job on a new VM. There is no human or manual intervention in this process. The following section provides an overview of the additional built-in layers that harden the security of the GitLab Runner SaaS CI build environment.
### Security of CI job execution on GitLab Runner SaaS (Linux, Windows)
@ -39,4 +39,4 @@ GitLab sends the command to remove the temporary runner VM to the Google Compute
- Firewall rules only allow outbound communication from the temporary VM to the public internet.
- Inbound communication from the public internet to the temporary VM is not allowed.
- Firewall rules do not permit communication between VMs.
- The only internal communication allowed to the temporary VMs is from the Runner Manager.
- The only internal communication allowed to the temporary VMs is from the runner manager.

View File

@ -958,7 +958,7 @@ job:
**Related topics**:
- [Use CI/CD variables to define the artifacts name](../jobs/job_artifacts.md#with-cicd-variables-to-define-the-artifacts-name).
- [Use CI/CD variables to define the artifacts name](../jobs/job_artifacts.md#with-a-dynamically-defined-name).
#### `artifacts:public`

View File

@ -64,7 +64,7 @@ The tool ensures that all aspects of swapping a foreign key are covered. This in
- Creating a migration to remove a foreign key.
- Updating `db/structure.sql` with the new migration.
- Updating `lib/gitlab/database/gitlab_loose_foreign_keys.yml` to add the new loose foreign key.
- Updating `config/gitlab_loose_foreign_keys.yml` to add the new loose foreign key.
- Creating or updating a model's specs to ensure that the loose foreign key is properly supported.
The tool is located at `scripts/decomposition/generate-loose-foreign-key`:

View File

@ -135,6 +135,8 @@ To set up your self-managed instance for the GitLab for Jira Cloud app in GitLab
### Link your instance
See [prerequisites](#prerequisites).
To link your self-managed instance to the GitLab for Jira Cloud app:
1. Install the [GitLab for Jira Cloud app](https://marketplace.atlassian.com/apps/1221011/gitlab-com-for-jira-cloud?tab=overview&hosting=cloud).
@ -320,3 +322,34 @@ To resolve this issue on GitLab self-managed, follow one of the solutions below,
- Contact the [Jira Software Cloud support](https://support.atlassian.com/jira-software-cloud/) and ask to trigger a new installed lifecycle event for the GitLab for Jira Cloud app in your namespace.
- In all GitLab versions:
- Re-install the GitLab for Jira Cloud app. This might remove all already synced development panel data.
### `Failed to update GitLab version` error when setting up the GitLab for Jira Cloud app for self-managed instances
When you set up the GitLab for Jira Cloud app, you might get the following message after you enter your
self-managed instance URL:
```plaintext
Failed to update GitLab version. Please try again.
```
To resolve this issue, ensure all prerequisites for your installation method have been met:
- [Prerequisites for connecting the GitLab for Jira Cloud app](#prerequisites)
- [Prerequisites for installing the GitLab for Jira Cloud app manually](#prerequisites-1)
If you're using GitLab 15.8 and earlier and have previously enabled both the `jira_connect_oauth_self_managed`
and the `jira_connect_oauth` feature flags, you must disable the `jira_connect_oauth_self_managed` flag
due to a [known issue](https://gitlab.com/gitlab-org/gitlab/-/issues/388943). To check for these flags:
1. Open a [Rails console](../../administration/operations/rails_console.md#starting-a-rails-console-session).
1. Execute the following code:
```ruby
# Check if both feature flags are enabled.
# If the flags are enabled, these commands return `true`.
Feature.enabled?(:jira_connect_oauth)
Feature.enabled?(:jira_connect_oauth_self_managed)
# If both flags are enabled, disable the `jira_connect_oauth_self_managed` flag.
Feature.disable(:jira_connect_oauth_self_managed)
```

View File

@ -358,6 +358,16 @@ to a larger value in [the NGINX configuration](https://nginx.org/en/docs/http/ng
## Troubleshooting
### Using Google Chrome with Kerberos authentication against Windows AD
When you use Google Chrome to sign in to GitLab with Kerberos, you must enter your full username. For example, `username@domain.com`.
If you do not enter your full username, the sign-in fails. Check the logs to see the following event message as evidence of this sign-in failure:
```plain
"message":"OmniauthKerberosController: failed to process Negotiate/Kerberos authentication: gss_accept_sec_context did not return GSS_S_COMPLETE: An unsupported mechanism was requested\nUnknown error"`.
```
### Test connectivity between the GitLab and Kerberos servers
You can use utilities like [`kinit`](https://web.mit.edu/kerberos/krb5-1.12/doc/user/user_commands/kinit.html) and [`klist`](https://web.mit.edu/kerberos/krb5-1.12/doc/user/user_commands/klist.html) to test connectivity between the GitLab server

View File

@ -59,6 +59,7 @@ Different features are available in different [GitLab tiers](https://about.gitla
| [Configure Secret Detection scanner](#enable-secret-detection) | **{check-circle}** Yes | **{check-circle}** Yes |
| [Customize Secret Detection settings](#configure-scan-settings) | **{check-circle}** Yes | **{check-circle}** Yes |
| Download [JSON Report](../sast/index.md#reports-json-format) | **{check-circle}** Yes | **{check-circle}** Yes |
| [Check text for potential secrets](#warnings-for-potential-leaks-in-text-content) before it's posted | **{check-circle}** Yes | **{check-circle}** Yes |
| See new findings in the merge request widget | **{dotted-circle}** No | **{check-circle}** Yes |
| View identified secrets in the pipelines' **Security** tab | **{dotted-circle}** No | **{check-circle}** Yes |
| [Manage vulnerabilities](../vulnerability_report/index.md) | **{dotted-circle}** No | **{check-circle}** Yes |
@ -535,6 +536,26 @@ variable, or as a CI/CD variable.
- If using a variable, set the value of `ADDITIONAL_CA_CERT_BUNDLE` to the text
representation of the certificate.
## Warnings for potential leaks in text content
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/368434) in GitLab 15.11.
When you create an issue, propose a merge request, or write a comment, you might accidentally post a sensitive value.
For example, you might paste in the details of an API request or an environment variable that contains an authentication token.
GitLab checks if the text of your issue description, merge request description, comment, or reply contains a sensitive token.
If a token is found, a warning message is displayed. You can then edit your message before posting it.
This check happens in your browser before the message is sent to the server.
The check is always on; you don't have to set it up.
Your text is checked for the following secret types:
- GitLab [personal access tokens](../../../security/token_overview.md#personal-access-tokens)
- GitLab [feed tokens](../../../security/token_overview.md#feed-token)
This feature is separate from Secret Detection scanning, which checks your Git repository for leaked secrets.
[Issue 405147](https://gitlab.com/gitlab-org/gitlab/-/issues/405147) tracks efforts to align these two types of protection.
## Troubleshooting
### Set the logging level

View File

@ -39,47 +39,18 @@ Credentials are only post-processed when Secret Detection finds them:
- In public projects, because publicly exposed credentials pose an increased threat. Expansion to private projects is considered in [issue 391379](https://gitlab.com/gitlab-org/gitlab/-/issues/391379).
- In projects with GitLab Ultimate, for technical reasons. Expansion to all tiers is tracked in [issue 391763](https://gitlab.com/gitlab-org/gitlab/-/issues/391763).
## High-level architecture
## Partner program for leaked-credential notifications
This diagram describes how a post-processing hook revokes a secret within the GitLab application:
```mermaid
sequenceDiagram
autonumber
GitLab Rails-->+GitLab Rails: gl-secret-detection-report.json
GitLab Rails->>+Sidekiq: StoreScansService
Sidekiq-->+Sidekiq: ScanSecurityReportSecretsWorker
Sidekiq-->+Token Revocation API: GET revocable keys types
Token Revocation API-->>-Sidekiq: OK
Sidekiq->>+Token Revocation API: POST revoke revocable keys
Token Revocation API-->>-Sidekiq: ACCEPTED
Token Revocation API-->>+Receiver Service: revoke revocable keys
Receiver Service-->>+Token Revocation API: ACCEPTED
```
1. A pipeline with a Secret Detection job completes, producing a scan report (**1**).
1. The report is processed (**2**) by a service class, which schedules an asychronous worker if token revocation is possible.
1. The asynchronous worker (**3**) communicates with an externally deployed HTTP service
(**4** and **5**) to determine which kinds of secrets can be automatically revoked.
1. The worker sends (**6** and **7**) the list of detected secrets which the Token Revocation API is able to
revoke.
1. The Token Revocation API sends (**8** and **9**) each revocable token to their respective vendor's [receiver service](#integrate-your-cloud-provider-service-with-gitlabcom).
See the [Token Revocation API](../../../development/sec/token_revocation_api.md) documentation for more
information.
## Integrate your cloud provider service with GitLab.com
Third-party cloud and SaaS vendors interested in automated token revocation can
[express integration interest by filling out this form](https://forms.gle/wWpvrtLRK21Q2WJL9).
Vendors must [implement a revocation receiver service](#implement-a-revocation-receiver-service)
which will be called by the Token Revocation API.
GitLab notifies partners when credentials they issue are leaked in public repositories on GitLab.com.
If you operate a cloud or SaaS product and you're interested in receiving these notifications, learn more in [epic 4944](https://gitlab.com/groups/gitlab-org/-/epics/4944).
Partners must [implement a revocation receiver service](#implement-a-revocation-receiver-service),
which is called by the Token Revocation API.
### Implement a revocation receiver service
A revocation receiver service integrates with a GitLab instance's Token Revocation API to receive and respond
to leaked token revocation requests. The service should be a publicly accessible HTTP API that is
idempotent and rate-limited. Requests to your service from the Token Revocation API will follow the example
idempotent and rate-limited. Requests to your service from the Token Revocation API look similar to the example
below:
```plaintext
@ -96,3 +67,32 @@ X-Gitlab-Token: MYSECRETTOKEN
In this example, Secret Detection has determined that an instance of `my_api_token` has been leaked. The
value of the token is provided to you, in addition to a publicly accessible URL to the raw content of the
file containing the leaked token.
## High-level architecture
This diagram describes how a post-processing hook revokes a secret in the GitLab application:
```mermaid
sequenceDiagram
autonumber
GitLab Rails-->+GitLab Rails: gl-secret-detection-report.json
GitLab Rails->>+Sidekiq: StoreScansService
Sidekiq-->+Sidekiq: ScanSecurityReportSecretsWorker
Sidekiq-->+Token Revocation API: GET revocable keys types
Token Revocation API-->>-Sidekiq: OK
Sidekiq->>+Token Revocation API: POST revoke revocable keys
Token Revocation API-->>-Sidekiq: ACCEPTED
Token Revocation API-->>+Receiver Service: revoke revocable keys
Receiver Service-->>+Token Revocation API: ACCEPTED
```
1. A pipeline with a Secret Detection job completes, producing a scan report (**1**).
1. The report is processed (**2**) by a service class, which schedules an asynchronous worker if token revocation is possible.
1. The asynchronous worker (**3**) communicates with an externally deployed HTTP service
(**4** and **5**) to determine which kinds of secrets can be automatically revoked.
1. The worker sends (**6** and **7**) the list of detected secrets which the Token Revocation API is able to
revoke.
1. The Token Revocation API sends (**8** and **9**) each revocable token to their respective vendor's [receiver service](#implement-a-revocation-receiver-service).
See the [Token Revocation API](../../../development/sec/token_revocation_api.md) documentation for more
information.

View File

@ -0,0 +1,18 @@
---
stage: Create
group: Editor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
type: reference
---
> Introduced in GitLab 15.11 [with a flag](../../../administration/feature_flags.md) named `remote_development_feature_flag`. Disabled by default.
FLAG:
On self-managed GitLab, by default this feature is not available. To make it available,
ask an administrator to [enable the feature flag](../../../administration/feature_flags.md) named `remote_development_feature_flag`.
On GitLab.com, this feature is not available.
The feature is not ready for production use.
# Tutorial: Create and run your first GitLab Workspace **(ULTIMATE)**
This tutorial shows you how to configure and run your first Remote Development Workspace in GitLab.

View File

@ -6,6 +6,8 @@ module Gitlab
class InstancePath
include Gitlab::Utils::StrongMemoize
LATEST_VERSION_KEYWORD = '~latest'
def self.match?(address)
address.include?('@') && address.start_with?(Settings.gitlab_ci['component_fqdn'])
end
@ -39,9 +41,9 @@ module Gitlab
File.join(component_dir, @content_filename).delete_prefix('/')
end
# TODO: Add support when version is a released tag and "~latest" moving target
def sha
return unless project
return latest_version_sha if version == LATEST_VERSION_KEYWORD
project.commit(version)&.id
end
@ -69,6 +71,12 @@ module Gitlab
::Project.where_full_path_in(possible_paths).take # rubocop: disable CodeReuse/ActiveRecord
end
def latest_version_sha
return unless catalog_resource = project&.catalog_resource
catalog_resource.latest_version&.sha
end
end
end
end

View File

@ -39221,6 +39221,15 @@ msgstr ""
msgid "SecurityConfiguration|Available with Ultimate"
msgstr ""
msgid "SecurityConfiguration|BAS"
msgstr ""
msgid "SecurityConfiguration|Breach and Attack Simulation (BAS)"
msgstr ""
msgid "SecurityConfiguration|Breach and Attack Simulation is an incubating feature extending existing security testing by simulating adversary activity."
msgstr ""
msgid "SecurityConfiguration|By default, all analyzers are applied in order to cover all languages across your project, and only run if the language is detected in the merge request."
msgstr ""
@ -39260,6 +39269,9 @@ msgstr ""
msgid "SecurityConfiguration|Enable Auto DevOps"
msgstr ""
msgid "SecurityConfiguration|Enable incubating Breach and Attack Simulation focused features such as callback attacks in your DAST scans."
msgstr ""
msgid "SecurityConfiguration|Enable security training to help your developers learn how to fix vulnerabilities. Developers can view security training from selected educational providers, relevant to the detected vulnerability."
msgstr ""
@ -39272,6 +39284,9 @@ msgstr ""
msgid "SecurityConfiguration|Immediately begin risk analysis and remediation with application security features. Start with SAST and Secret Detection, available to all plans. Upgrade to Ultimate to get all features, including:"
msgstr ""
msgid "SecurityConfiguration|Incubating feature"
msgstr ""
msgid "SecurityConfiguration|Learn more about vulnerability training"
msgstr ""
@ -39296,6 +39311,9 @@ msgstr ""
msgid "SecurityConfiguration|Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan. An enabled scanner will not be reflected as such until the pipeline has been successfully executed and it has generated valid artifacts."
msgstr ""
msgid "SecurityConfiguration|Out-of-Band Application Security Testing (OAST)"
msgstr ""
msgid "SecurityConfiguration|Quickly enable all continuous testing and compliance tools by enabling %{linkStart}Auto DevOps%{linkEnd}"
msgstr ""
@ -39317,6 +39335,9 @@ msgstr ""
msgid "SecurityConfiguration|Security training"
msgstr ""
msgid "SecurityConfiguration|Simulate breach and attack scenarios against your running application by attempting to detect and exploit known vulnerabilities."
msgstr ""
msgid "SecurityConfiguration|Something went wrong. Please refresh the page, or try again later."
msgstr ""
@ -50034,6 +50055,18 @@ msgstr ""
msgid "WorkItem|You're only seeing %{boldStart}other activity%{boldEnd} in the feed. To add a comment, switch to one of the following options."
msgstr ""
msgid "Workspaces"
msgstr ""
msgid "Workspaces|Develop anywhere"
msgstr ""
msgid "Workspaces|Get started with GitLab Workspaces"
msgstr ""
msgid "Workspaces|GitLab Workspaces is a powerful collaborative platform that provides a comprehensive set of tools for software development teams to manage their entire development lifecycle."
msgstr ""
msgid "Would you like to create a new branch?"
msgstr ""

View File

@ -1,7 +1,8 @@
{
"version": "14.0.0",
"version": "15.0.0",
"vulnerabilities": [
{
"id": "1",
"category": "sast",
"name": "Predictable pseudorandom number generator",
"message": "Predictable pseudorandom number generator",
@ -29,6 +30,7 @@
]
},
{
"id": "2",
"category": "sast",
"name": "Predictable pseudorandom number generator",
"message": "Predictable pseudorandom number generator",
@ -56,6 +58,7 @@
]
},
{
"id": "3",
"category": "sast",
"name": "ECB mode is insecure",
"message": "ECB mode is insecure",
@ -90,6 +93,7 @@
]
},
{
"id": "4",
"category": "sast",
"name": "Hard coded key",
"message": "Hard coded key",
@ -124,6 +128,7 @@
]
},
{
"id": "5",
"category": "sast",
"name": "ECB mode is insecure",
"message": "ECB mode is insecure",
@ -158,8 +163,19 @@
]
}
],
"remediations": [],
"remediations": [
],
"scan": {
"analyzer": {
"id": "find_sec_bugs_analyzer",
"name": "Find Security Bugs Analyzer",
"url": "https://gitlab.com",
"vendor": {
"name": "GitLab"
},
"version": "1.0.0"
},
"scanner": {
"id": "find_sec_bugs",
"name": "Find Security Bugs",
@ -174,4 +190,4 @@
"start_time": "2022-08-10T22:37:00",
"end_time": "2022-08-10T22:38:00"
}
}
}

View File

@ -1,5 +1,33 @@
{
"version": "14.1.2",
"vulnerabilities": [],
"remediations": []
}
"version": "15.0.0",
"vulnerabilities": [
],
"remediations": [
],
"scan": {
"analyzer": {
"id": "secret_detection_analyzer",
"name": "Secret Detection Analyzer",
"url": "https://gitlab.com",
"vendor": {
"name": "GitLab"
},
"version": "1.0.0"
},
"scanner": {
"id": "secret_detection",
"name": "Secret Detection",
"url": "https://gitlab.com",
"vendor": {
"name": "GitLab"
},
"version": "0.1.0"
},
"type": "sast",
"start_time": "2022-03-11T18:48:16",
"end_time": "2022-03-11T18:48:22",
"status": "success"
}
}

View File

@ -1,7 +1,23 @@
{
"version": "14.1.2",
"version": "15.0.0",
"scan": {
"analyzer": {
"id": "sast_analyzer",
"name": "SAST Analyzer",
"url": "https://gitlab.com",
"vendor": {
"name": "GitLab"
},
"version": "1.0.0"
},
"type": "sast",
"start_time": "2022-03-11T18:48:16",
"end_time": "2022-03-11T18:48:22",
"status": "success"
},
"vulnerabilities": [
{
"id": "1",
"category": "sast",
"message": "Probable insecure usage of temp file/directory.",
"cve": "python/hardcoded/hardcoded-tmp.py:52865813c884a507be1f152d654245af34aba8a391626d01f1ab6d3f52ec8779:B108",
@ -26,6 +42,7 @@
"url": "https://docs.openstack.org/bandit/latest/plugins/b108_hardcoded_tmp_directory.html"
},
{
"id": "2",
"category": "sast",
"name": "Predictable pseudorandom number generator",
"message": "Predictable pseudorandom number generator",
@ -53,6 +70,7 @@
"url": "https://find-sec-bugs.github.io/bugs.htm#PREDICTABLE_RANDOM"
},
{
"id": "3",
"category": "sast",
"name": "Predictable pseudorandom number generator",
"message": "Predictable pseudorandom number generator",
@ -80,6 +98,7 @@
"url": "https://find-sec-bugs.github.io/bugs.htm#PREDICTABLE_RANDOM"
},
{
"id": "4",
"category": "sast",
"message": "Use of insecure MD2, MD4, or MD5 hash function.",
"cve": "python/imports/imports-aliases.py:cb203b465dffb0cb3a8e8bd8910b84b93b0a5995a938e4b903dbb0cd6ffa1254:B303",
@ -102,6 +121,7 @@
"line": 11
},
{
"id": "5",
"category": "sast",
"message": "Use of insecure MD2, MD4, or MD5 hash function.",
"cve": "python/imports/imports-aliases.py:a7173c43ae66bd07466632d819d450e0071e02dbf782763640d1092981f9631b:B303",
@ -124,6 +144,7 @@
"line": 12
},
{
"id": "6",
"category": "sast",
"message": "Use of insecure MD2, MD4, or MD5 hash function.",
"cve": "python/imports/imports-aliases.py:017017b77deb0b8369b6065947833eeea752a92ec8a700db590fece3e934cf0d:B303",
@ -146,6 +167,7 @@
"line": 13
},
{
"id": "6",
"category": "sast",
"message": "Use of insecure MD2, MD4, or MD5 hash function.",
"cve": "python/imports/imports-aliases.py:45fc8c53aea7b84f06bc4e590cc667678d6073c4c8a1d471177ca2146fb22db2:B303",
@ -168,6 +190,7 @@
"line": 14
},
{
"id": "7",
"category": "sast",
"message": "Pickle library appears to be in use, possible security issue.",
"cve": "python/imports/imports-aliases.py:5f200d47291e7bbd8352db23019b85453ca048dd98ea0c291260fa7d009963a4:B301",
@ -190,6 +213,7 @@
"line": 15
},
{
"id": "8",
"category": "sast",
"name": "ECB mode is insecure",
"message": "ECB mode is insecure",
@ -217,6 +241,7 @@
"url": "https://find-sec-bugs.github.io/bugs.htm#ECB_MODE"
},
{
"id": "9",
"category": "sast",
"name": "Cipher with no integrity",
"message": "Cipher with no integrity",
@ -244,6 +269,7 @@
"url": "https://find-sec-bugs.github.io/bugs.htm#CIPHER_INTEGRITY"
},
{
"id": "10",
"category": "sast",
"message": "Probable insecure usage of temp file/directory.",
"cve": "python/hardcoded/hardcoded-tmp.py:63dd4d626855555b816985d82c4614a790462a0a3ada89dc58eb97f9c50f3077:B108",
@ -268,6 +294,7 @@
"url": "https://docs.openstack.org/bandit/latest/plugins/b108_hardcoded_tmp_directory.html"
},
{
"id": "11",
"category": "sast",
"message": "Probable insecure usage of temp file/directory.",
"cve": "python/hardcoded/hardcoded-tmp.py:4ad6d4c40a8c263fc265f3384724014e0a4f8dd6200af83e51ff120420038031:B108",
@ -292,6 +319,7 @@
"url": "https://docs.openstack.org/bandit/latest/plugins/b108_hardcoded_tmp_directory.html"
},
{
"id": "12",
"category": "sast",
"message": "Consider possible security implications associated with Popen module.",
"cve": "python/imports/imports-aliases.py:2c3e1fa1e54c3c6646e8bcfaee2518153c6799b77587ff8d9a7b0631f6d34785:B404",
@ -314,6 +342,7 @@
"line": 1
},
{
"id": "13",
"category": "sast",
"message": "Consider possible security implications associated with pickle module.",
"cve": "python/imports/imports.py:af58d07f6ad519ef5287fcae65bf1a6999448a1a3a8bc1ac2a11daa80d0b96bf:B403",
@ -336,6 +365,7 @@
"line": 2
},
{
"id": "14",
"category": "sast",
"message": "Consider possible security implications associated with subprocess module.",
"cve": "python/imports/imports.py:8de9bc98029d212db530785a5f6780cfa663548746ff228ab8fa96c5bb82f089:B404",
@ -358,6 +388,7 @@
"line": 4
},
{
"id": "15",
"category": "sast",
"message": "Possible hardcoded password: 'blerg'",
"cve": "python/hardcoded/hardcoded-passwords.py:97c30f1d76d2a88913e3ce9ae74087874d740f87de8af697a9c455f01119f633:B106",
@ -382,6 +413,7 @@
"url": "https://docs.openstack.org/bandit/latest/plugins/b106_hardcoded_password_funcarg.html"
},
{
"id": "16",
"category": "sast",
"message": "Possible hardcoded password: 'root'",
"cve": "python/hardcoded/hardcoded-passwords.py:7431c73a0bc16d94ece2a2e75ef38f302574d42c37ac0c3c38ad0b3bf8a59f10:B105",
@ -406,6 +438,7 @@
"url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html"
},
{
"id": "17",
"category": "sast",
"message": "Possible hardcoded password: ''",
"cve": "python/hardcoded/hardcoded-passwords.py:d2d1857c27caedd49c57bfbcdc23afcc92bd66a22701fcdc632869aab4ca73ee:B105",
@ -430,6 +463,7 @@
"url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html"
},
{
"id": "18",
"category": "sast",
"message": "Possible hardcoded password: 'ajklawejrkl42348swfgkg'",
"cve": "python/hardcoded/hardcoded-passwords.py:fb3866215a61393a5c9c32a3b60e2058171a23219c353f722cbd3567acab21d2:B105",
@ -454,6 +488,7 @@
"url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html"
},
{
"id": "19",
"category": "sast",
"message": "Possible hardcoded password: 'blerg'",
"cve": "python/hardcoded/hardcoded-passwords.py:63c62a8b7e1e5224439bd26b28030585ac48741e28ca64561a6071080c560a5f:B105",
@ -478,6 +513,7 @@
"url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html"
},
{
"id": "20",
"category": "sast",
"message": "Possible hardcoded password: 'blerg'",
"cve": "python/hardcoded/hardcoded-passwords.py:4311b06d08df8fa58229b341c531da8e1a31ec4520597bdff920cd5c098d86f9:B105",
@ -502,6 +538,7 @@
"url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html"
},
{
"id": "21",
"category": "sast",
"message": "Consider possible security implications associated with subprocess module.",
"cve": "python/imports/imports-function.py:5858400c2f39047787702de44d03361ef8d954c9d14bd54ee1c2bef9e6a7df93:B404",
@ -524,6 +561,7 @@
"line": 4
},
{
"id": "22",
"category": "sast",
"message": "Consider possible security implications associated with pickle module.",
"cve": "python/imports/imports-function.py:dbda3cf4190279d30e0aad7dd137eca11272b0b225e8af4e8bf39682da67d956:B403",
@ -546,6 +584,7 @@
"line": 2
},
{
"id": "23",
"category": "sast",
"message": "Consider possible security implications associated with Popen module.",
"cve": "python/imports/imports-from.py:eb8a0db9cd1a8c1ab39a77e6025021b1261cc2a0b026b2f4a11fca4e0636d8dd:B404",
@ -568,6 +607,7 @@
"line": 7
},
{
"id": "24",
"category": "sast",
"message": "subprocess call with shell=True seems safe, but may be changed in the future, consider rewriting without shell",
"cve": "python/imports/imports-aliases.py:f99f9721e27537fbcb6699a4cf39c6740d6234d2c6f06cfc2d9ea977313c483d:B602",
@ -592,6 +632,7 @@
"url": "https://docs.openstack.org/bandit/latest/plugins/b602_subprocess_popen_with_shell_equals_true.html"
},
{
"id": "25",
"category": "sast",
"message": "Consider possible security implications associated with subprocess module.",
"cve": "python/imports/imports-from.py:332a12ab1146698f614a905ce6a6a5401497a12281aef200e80522711c69dcf4:B404",
@ -614,6 +655,7 @@
"line": 6
},
{
"id": "26",
"category": "sast",
"message": "Consider possible security implications associated with Popen module.",
"cve": "python/imports/imports-from.py:0a48de4a3d5348853a03666cb574697e3982998355e7a095a798bd02a5947276:B404",
@ -636,6 +678,7 @@
"line": 1
},
{
"id": "27",
"category": "sast",
"message": "Consider possible security implications associated with pickle module.",
"cve": "python/imports/imports-aliases.py:51b71661dff994bde3529639a727a678c8f5c4c96f00d300913f6d5be1bbdf26:B403",
@ -658,6 +701,7 @@
"line": 7
},
{
"id": "28",
"category": "sast",
"message": "Consider possible security implications associated with loads module.",
"cve": "python/imports/imports-aliases.py:6ff02aeb3149c01ab68484d794a94f58d5d3e3bb0d58557ef4153644ea68ea54:B403",
@ -680,6 +724,7 @@
"line": 6
},
{
"id": "29",
"category": "sast",
"message": "Statically-sized arrays can be improperly restricted, leading to potential overflows or other issues (CWE-119!/CWE-120)",
"cve": "c/subdir/utils.c:b466873101951fe96e1332f6728eb7010acbbd5dfc3b65d7d53571d091a06d9e:CWE-119!/CWE-120",
@ -713,6 +758,7 @@
"url": "https://cwe.mitre.org/data/definitions/119.html"
},
{
"id": "30",
"category": "sast",
"message": "Check when opening files - can an attacker redirect it (via symlinks), force the opening of special file type (e.g., device files), move things around to create a race condition, control its ancestors, or change its contents? (CWE-362)",
"cve": "c/subdir/utils.c:bab681140fcc8fc3085b6bba74081b44ea145c1c98b5e70cf19ace2417d30770:CWE-362",
@ -739,6 +785,7 @@
"url": "https://cwe.mitre.org/data/definitions/362.html"
},
{
"id": "31",
"category": "sast",
"message": "Statically-sized arrays can be improperly restricted, leading to potential overflows or other issues (CWE-119!/CWE-120)",
"cve": "cplusplus/src/hello.cpp:c8c6dd0afdae6814194cf0930b719f757ab7b379cf8f261e7f4f9f2f323a818a:CWE-119!/CWE-120",
@ -772,6 +819,7 @@
"url": "https://cwe.mitre.org/data/definitions/119.html"
},
{
"id": "32",
"category": "sast",
"message": "Does not check for buffer overflows when copying to destination [MS-banned] (CWE-120)",
"cve": "cplusplus/src/hello.cpp:331c04062c4fe0c7c486f66f59e82ad146ab33cdd76ae757ca41f392d568cbd0:CWE-120",
@ -799,4 +847,4 @@
"url": "https://cwe.mitre.org/data/definitions/120.html"
}
]
}
}

View File

@ -1,5 +1,5 @@
{
"version": "14.0.4",
"version": "15.0.4",
"vulnerabilities": [
{
"id": "985a5666dcae22adef5ac12f8a8a2dacf9b9b481ae5d87cd0ac1712b0fd64864",
@ -26,6 +26,15 @@
}
],
"scan": {
"analyzer": {
"id": "find_sec_bugs_analyzer",
"name": "Find Security Bugs Analyzer",
"url": "https://gitlab.com",
"vendor": {
"name": "GitLab"
},
"version": "1.0.0"
},
"scanner": {
"id": "bandit",
"name": "Bandit",
@ -40,4 +49,4 @@
"end_time": "2022-03-11T00:21:50",
"status": "success"
}
}
}

View File

@ -1,5 +1,5 @@
{
"version": "14.0.4",
"version": "15.0.4",
"vulnerabilities": [
{
"id": "2e5656ff30e2e7cc93c36b4845c8a689ddc47fdbccf45d834c67442fbaa89be0",
@ -51,6 +51,15 @@
}
],
"scan": {
"analyzer": {
"id": "find_sec_bugs_analyzer",
"name": "Find Security Bugs Analyzer",
"url": "https://gitlab.com",
"vendor": {
"name": "GitLab"
},
"version": "1.0.0"
},
"scanner": {
"id": "gosec",
"name": "Gosec",
@ -65,4 +74,4 @@
"end_time": "2022-03-15T20:33:17",
"status": "success"
}
}
}

View File

@ -1,7 +1,8 @@
{
"version": "14.0.0",
"version": "15.0.0",
"vulnerabilities": [
{
"id": "1",
"category": "sast",
"name": "Cipher with no integrity",
"message": "Cipher with no integrity",
@ -49,8 +50,19 @@
}
}
],
"remediations": [],
"remediations": [
],
"scan": {
"analyzer": {
"id": "find_sec_bugs_analyzer",
"name": "Find Security Bugs Analyzer",
"url": "https://gitlab.com",
"vendor": {
"name": "GitLab"
},
"version": "1.0.0"
},
"scanner": {
"id": "find_sec_bugs",
"name": "Find Security Bugs",
@ -65,4 +77,4 @@
"start_time": "2022-08-10T21:37:00",
"end_time": "2022-08-10T21:38:00"
}
}
}

View File

@ -1,5 +1,5 @@
{
"version": "14.0.4",
"version": "15.0.4",
"vulnerabilities": [
{
"id": "985a5666dcae22adef5ac12f8a8a2dacf9b9b481ae5d87cd0ac1712b0fd64864",
@ -54,6 +54,15 @@
}
],
"scan": {
"analyzer": {
"id": "find_sec_bugs_analyzer",
"name": "Find Security Bugs Analyzer",
"url": "https://gitlab.com",
"vendor": {
"name": "GitLab"
},
"version": "1.0.0"
},
"scanner": {
"id": "semgrep",
"name": "Semgrep",
@ -68,4 +77,4 @@
"end_time": "2022-03-11T18:48:22",
"status": "success"
}
}
}

View File

@ -1,5 +1,5 @@
{
"version": "14.0.4",
"version": "15.0.4",
"vulnerabilities": [
{
"id": "79f6537b7ec83c7717f5bd1a4f12645916caafefe2e4359148d889855505aa67",
@ -53,6 +53,15 @@
}
],
"scan": {
"analyzer": {
"id": "find_sec_bugs_analyzer",
"name": "Find Security Bugs Analyzer",
"url": "https://gitlab.com",
"vendor": {
"name": "GitLab"
},
"version": "1.0.0"
},
"scanner": {
"id": "semgrep",
"name": "Semgrep",
@ -74,4 +83,4 @@
"end_time": "2022-03-15T20:37:05",
"status": "success"
}
}
}

View File

@ -1,5 +1,5 @@
{
"version": "14.0.4",
"version": "15.0.4",
"vulnerabilities": [
{
"id": "985a5666dcae22adef5ac12f8a8a2dacf9b9b481ae5d87cd0ac1712b0fd64864",
@ -104,6 +104,15 @@
}
],
"scan": {
"analyzer": {
"id": "semgrep_analyzer",
"name": "Semgrep Analyzer",
"url": "https://gitlab.com/",
"vendor": {
"name": "GitLab"
},
"version": "1.0.0"
},
"scanner": {
"id": "semgrep",
"name": "Semgrep",
@ -131,4 +140,4 @@
"end_time": "2022-03-15T20:37:05",
"status": "success"
}
}
}

View File

@ -1,7 +1,8 @@
{
"version": "14.0.0",
"version": "15.0.0",
"vulnerabilities": [
{
"id": "1_481ae5d87cd0ac1712b0fd64864",
"category": "sast",
"name": "Predictable pseudorandom number generator",
"message": "Predictable pseudorandom number generator",
@ -39,6 +40,7 @@
]
},
{
"id": "2_481ae5d87cd0ac1712b0fd64864",
"category": "sast",
"name": "Predictable pseudorandom number generator",
"message": "Predictable pseudorandom number generator",
@ -66,6 +68,7 @@
]
},
{
"id": "3_481ae5d87cd0ac1712b0fd64864",
"category": "sast",
"name": "ECB mode is insecure",
"message": "ECB mode is insecure",
@ -100,6 +103,7 @@
]
},
{
"id": "4_481ae5d87cd0ac1712b0fd64864",
"category": "sast",
"name": "Hard coded key",
"message": "Hard coded key",
@ -134,6 +138,7 @@
]
},
{
"id": "5_481ae5d87cd0ac1712b0fd64864",
"category": "sast",
"name": "Cipher with no integrity",
"message": "Cipher with no integrity",
@ -181,8 +186,19 @@
}
}
],
"remediations": [],
"remediations": [
],
"scan": {
"analyzer": {
"id": "find_sec_bugs_analyzer",
"name": "Find Security Bugs Analyzer",
"url": "https://gitlab.com",
"vendor": {
"name": "GitLab"
},
"version": "1.0.0"
},
"scanner": {
"id": "find_sec_bugs",
"name": "Find Security Bugs",
@ -197,4 +213,4 @@
"start_time": "2022-08-10T21:37:00",
"end_time": "2022-08-10T21:38:00"
}
}
}

View File

@ -1,5 +1,29 @@
{
"version": "14.1.2",
"version": "15.0.0",
"scan": {
"analyzer": {
"id": "secret_detection_analyzer",
"name": "Secret Detection Analyzer",
"url": "https://gitlab.com",
"vendor": {
"name": "GitLab"
},
"version": "1.0.0"
},
"scanner": {
"id": "secret_detection",
"name": "Secret Detection",
"url": "https://gitlab.com",
"vendor": {
"name": "GitLab"
},
"version": "0.1.0"
},
"type": "sast",
"start_time": "2022-03-11T18:48:16",
"end_time": "2022-03-11T18:48:22",
"status": "success"
},
"vulnerabilities": [
{
"id": "27d2322d519c94f803ffed1cf6d14e455df97e5a0668e229eb853fdb0d277d2c",
@ -17,7 +41,8 @@
"location": {
"file": "aws-key.py",
"dependency": {
"package": {}
"package": {
}
},
"commit": {
"sha": "e9c3a56590d5bed4155c0d128f1552d52fdcc7ae"
@ -32,5 +57,7 @@
]
}
],
"remediations": []
}
"remediations": [
]
}

View File

@ -19,7 +19,11 @@ import {
getIssueDetailsResponse,
projectWorkItemTypesQueryResponse,
} from 'jest/work_items/mock_data';
import { descriptionProps as initialProps, descriptionHtmlWithList } from '../mock_data/mock_data';
import {
descriptionProps as initialProps,
descriptionHtmlWithList,
descriptionHtmlWithDetailsTag,
} from '../mock_data/mock_data';
jest.mock('~/alert');
jest.mock('~/task_list');
@ -111,6 +115,19 @@ describe('Description component', () => {
expect(findGfmContent().classes()).toContain('issue-realtime-trigger-pulse');
});
it('doesnt animate expand/collapse of details elements', async () => {
createComponent();
await wrapper.setProps({ descriptionHtml: descriptionHtmlWithDetailsTag.collapsed });
expect(findGfmContent().classes()).not.toContain('issue-realtime-pre-pulse');
await wrapper.setProps({ descriptionHtml: descriptionHtmlWithDetailsTag.expanded });
expect(findGfmContent().classes()).not.toContain('issue-realtime-pre-pulse');
await wrapper.setProps({ descriptionHtml: descriptionHtmlWithDetailsTag.collapsed });
expect(findGfmContent().classes()).not.toContain('issue-realtime-pre-pulse');
});
it('applies syntax highlighting and math when description changed', async () => {
createComponent();

View File

@ -79,3 +79,16 @@ export const descriptionHtmlWithList = `
<li data-sourcepos="3:1-3:8">todo 3</li>
</ul>
`;
export const descriptionHtmlWithDetailsTag = {
expanded: `
<details open="true">
<summary>Section 1</summary>
<p>Data</p>
</details>'`,
collapsed: `
<details>
<summary>Section 1</summary>
<p>Data</p>
</details>'`,
};

View File

@ -1,10 +1,15 @@
import { GlIcon } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import { securityFeatures } from '~/security_configuration/components/constants';
import FeatureCard from '~/security_configuration/components/feature_card.vue';
import FeatureCardBadge from '~/security_configuration/components/feature_card_badge.vue';
import ManageViaMr from '~/vue_shared/security_configuration/components/manage_via_mr.vue';
import { REPORT_TYPE_SAST } from '~/vue_shared/security_reports/constants';
import {
REPORT_TYPE_BREACH_AND_ATTACK_SIMULATION,
REPORT_TYPE_SAST,
REPORT_TYPE_SAST_IAC,
} from '~/vue_shared/security_reports/constants';
import { manageViaMRErrorMessage } from '../constants';
import { makeFeature } from './utils';
@ -265,6 +270,56 @@ describe('FeatureCard component', () => {
expect(links.exists()).toBe(false);
});
});
describe('given an available secondary with a configuration guide', () => {
beforeEach(() => {
feature = makeFeature({
available: true,
configurationHelpPath: null,
secondary: {
name: 'secondary name',
description: 'secondary description',
configurationHelpPath: '/secondary',
configurationText: null,
},
});
createComponent({ feature });
});
it('shows the secondary action', () => {
const links = findLinks({
text: 'Configuration guide',
href: feature.secondary.configurationHelpPath,
});
expect(links.exists()).toBe(true);
expect(links).toHaveLength(1);
});
});
describe('given an unavailable secondary with a configuration guide', () => {
beforeEach(() => {
feature = makeFeature({
available: false,
configurationHelpPath: null,
secondary: {
name: 'secondary name',
description: 'secondary description',
configurationHelpPath: '/secondary',
configurationText: null,
},
});
createComponent({ feature });
});
it('does not show the secondary action', () => {
const links = findLinks({
text: 'Configuration guide',
href: feature.secondary.configurationHelpPath,
});
expect(links.exists()).toBe(false);
expect(links).toHaveLength(0);
});
});
});
describe('information badge', () => {
@ -290,4 +345,48 @@ describe('FeatureCard component', () => {
});
});
});
describe('status and badge', () => {
describe.each`
context | available | configured | expectedStatus
${'configured BAS feature'} | ${true} | ${true} | ${null}
${'unavailable BAS feature'} | ${false} | ${false} | ${'Available with Ultimate'}
${'unconfigured BAS feature'} | ${true} | ${false} | ${null}
`('given $context', ({ available, configured, expectedStatus }) => {
beforeEach(() => {
const securityFeature = securityFeatures.find(
({ type }) => REPORT_TYPE_BREACH_AND_ATTACK_SIMULATION === type,
);
feature = { ...securityFeature, available, configured };
createComponent({ feature });
});
it('should show an incubating feature badge', () => {
expect(findBadge().exists()).toBe(true);
});
if (expectedStatus) {
it(`should show the status "${expectedStatus}"`, () => {
expect(wrapper.findByTestId('feature-status').text()).toBe(expectedStatus);
});
}
});
describe.each`
context | available | configured
${'configured SAST IaC feature'} | ${true} | ${true}
${'unavailable SAST IaC feature'} | ${false} | ${false}
${'unconfigured SAST IaC feature'} | ${true} | ${false}
`('given $context', ({ available, configured }) => {
beforeEach(() => {
const securityFeature = securityFeatures.find(({ type }) => REPORT_TYPE_SAST_IAC === type);
feature = { ...securityFeature, available, configured };
createComponent({ feature });
});
it(`should not show a status`, () => {
expect(wrapper.findByTestId('feature-status').exists()).toBe(false);
});
});
});
});

View File

@ -8,11 +8,13 @@ import { createAlert } from '~/alert';
import { workspaceLabelsQueries } from '~/sidebar/constants';
import DropdownContentsCreateView from '~/sidebar/components/labels/labels_select_widget/dropdown_contents_create_view.vue';
import createLabelMutation from '~/sidebar/components/labels/labels_select_widget/graphql/create_label.mutation.graphql';
import { DEFAULT_LABEL_COLOR } from '~/sidebar/components/labels/labels_select_widget/constants';
import {
mockRegularLabel,
mockSuggestedColors,
createLabelSuccessfulResponse,
workspaceLabelsQueryResponse,
workspaceLabelsQueryEmptyResponse,
} from './mock_data';
jest.mock('~/alert');
@ -61,14 +63,16 @@ describe('DropdownContentsCreateView', () => {
mutationHandler = createLabelSuccessHandler,
labelCreateType = 'project',
workspaceType = 'project',
labelsResponse = workspaceLabelsQueryResponse,
searchTerm = '',
} = {}) => {
const mockApollo = createMockApollo([[createLabelMutation, mutationHandler]]);
mockApollo.clients.defaultClient.cache.writeQuery({
query: workspaceLabelsQueries[workspaceType].query,
data: workspaceLabelsQueryResponse.data,
data: labelsResponse.data,
variables: {
fullPath: '',
searchTerm: '',
searchTerm,
},
});
@ -94,7 +98,7 @@ describe('DropdownContentsCreateView', () => {
it('selects a color after clicking on colored block', async () => {
createComponent();
expect(findSelectedColor().attributes('style')).toBeUndefined();
expect(findSelectedColorText().attributes('value')).toBe(DEFAULT_LABEL_COLOR);
findAllColors().at(0).vm.$emit('click', new Event('mouseclick'));
await nextTick();
@ -104,7 +108,7 @@ describe('DropdownContentsCreateView', () => {
it('shows correct color hex code after selecting a color', async () => {
createComponent();
expect(findSelectedColorText().attributes('value')).toBe('');
expect(findSelectedColorText().attributes('value')).toBe(DEFAULT_LABEL_COLOR);
findAllColors().at(0).vm.$emit('click', new Event('mouseclick'));
await nextTick();
@ -123,6 +127,7 @@ describe('DropdownContentsCreateView', () => {
it('disables a Create button if color is not set', async () => {
createComponent();
findLabelTitleInput().vm.$emit('input', 'Test title');
findSelectedColorText().vm.$emit('input', '');
await nextTick();
expect(findCreateButton().props('disabled')).toBe(true);
@ -232,4 +237,21 @@ describe('DropdownContentsCreateView', () => {
titleTakenError.data.labelCreate.errors[0],
);
});
describe('when empty labels response', () => {
it('is able to create label with searched text when empty response', async () => {
createComponent({ searchTerm: '', labelsResponse: workspaceLabelsQueryEmptyResponse });
findLabelTitleInput().vm.$emit('input', 'random');
findCreateButton().vm.$emit('click');
await waitForPromises();
expect(createLabelSuccessHandler).toHaveBeenCalledWith({
color: DEFAULT_LABEL_COLOR,
projectPath: '',
title: 'random',
});
});
});
});

View File

@ -117,6 +117,17 @@ export const workspaceLabelsQueryResponse = {
},
};
export const workspaceLabelsQueryEmptyResponse = {
data: {
workspace: {
id: 'gid://gitlab/Project/126',
labels: {
nodes: [],
},
},
},
};
export const issuableLabelsQueryResponse = {
data: {
workspace: {

View File

@ -5,7 +5,8 @@ require 'spec_helper'
RSpec.describe Types::PermissionTypes::WorkItem do
it do
expected_permissions = [
:read_work_item, :update_work_item, :delete_work_item, :admin_work_item
:read_work_item, :update_work_item, :delete_work_item, :admin_work_item,
:admin_parent_link
]
expected_permissions.each do |permission|

View File

@ -8,6 +8,12 @@ require_relative '../../config/initializers/net_http_patch'
RSpec.describe 'Net::HTTP patch proxy user and password encoding' do
let(:net_http) { Net::HTTP.new('hostname.example') }
before do
# This file can be removed once Ruby 3.0 is no longer supported:
# https://gitlab.com/gitlab-org/gitlab/-/issues/396223
skip if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new(3.1)
end
describe '#proxy_user' do
subject { net_http.proxy_user }

View File

@ -98,6 +98,37 @@ RSpec.describe Gitlab::Ci::Components::InstancePath, feature_category: :pipeline
end
end
context 'when version is `~latest`' do
let(:version) { '~latest' }
context 'when project is a catalog resource' do
before do
create(:catalog_resource, project: existing_project)
end
context 'when project has releases' do
let_it_be(:releases) do
[
create(:release, project: existing_project, sha: 'sha-1', released_at: Time.zone.now - 1.day),
create(:release, project: existing_project, sha: 'sha-2', released_at: Time.zone.now)
]
end
it 'returns the sha of the latest release' do
expect(path.sha).to eq(releases.last.sha)
end
end
context 'when project does not have releases' do
it { expect(path.sha).to be_nil }
end
end
context 'when project is not a catalog resource' do
it { expect(path.sha).to be_nil }
end
end
context 'when project does not exist' do
let(:project_path) { 'non-existent/project' }

View File

@ -13,8 +13,8 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Sast do
context "when passing valid report" do
# rubocop: disable Layout/LineLength
where(:report_format, :report_version, :scanner_length, :finding_length, :identifier_length, :file_path, :start_line, :end_line, :primary_identifiers_length) do
:sast | '14.0.0' | 1 | 5 | 6 | 'groovy/src/main/java/com/gitlab/security_products/tests/App.groovy' | 47 | 47 | nil
:sast_semgrep_for_multiple_findings | '14.0.4' | 1 | 2 | 6 | 'app/app.py' | 39 | nil | 2
:sast | '15.0.0' | 1 | 5 | 6 | 'groovy/src/main/java/com/gitlab/security_products/tests/App.groovy' | 47 | 47 | nil
:sast_semgrep_for_multiple_findings | '15.0.4' | 1 | 2 | 6 | 'app/app.py' | 39 | nil | 2
end
# rubocop: enable Layout/LineLength

View File

@ -39,7 +39,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::SecretDetection do
end
it "generates expected metadata_version" do
expect(report.findings.first.metadata_version).to eq('14.1.2')
expect(report.findings.first.metadata_version).to eq('15.0.0')
end
end
end

View File

@ -0,0 +1,66 @@
# frozen_string_literal: true
require 'spec_helper'
require_migration!
RSpec.describe SwapIssueUserMentionsNoteIdToBigintForGitlabDotCom, feature_category: :database do
describe '#up' do
before do
# A we call `schema_migrate_down!` before each example, and for this migration
# `#down` is same as `#up`, we need to ensure we start from the expected state.
connection = described_class.new.connection
connection.execute('ALTER TABLE issue_user_mentions ALTER COLUMN note_id TYPE integer')
connection.execute('ALTER TABLE issue_user_mentions ALTER COLUMN note_id_convert_to_bigint TYPE bigint')
end
# rubocop: disable RSpec/AnyInstanceOf
it 'swaps the integer and bigint columns for GitLab.com, dev, or test' do
allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
user_mentions = table(:issue_user_mentions)
disable_migrations_output do
reversible_migration do |migration|
migration.before -> {
user_mentions.reset_column_information
expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
}
migration.after -> {
user_mentions.reset_column_information
expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('integer')
}
end
end
end
it 'is a no-op for other instances' do
allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
user_mentions = table(:issue_user_mentions)
disable_migrations_output do
reversible_migration do |migration|
migration.before -> {
user_mentions.reset_column_information
expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
}
migration.after -> {
user_mentions.reset_column_information
expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
}
end
end
end
# rubocop: enable RSpec/AnyInstanceOf
end
end

View File

@ -3,6 +3,17 @@
require 'spec_helper'
RSpec.describe Ci::Catalog::Resource, feature_category: :pipeline_composition do
let_it_be(:project) { create(:project) }
let_it_be(:resource) { create(:catalog_resource, project: project) }
let_it_be(:releases) do
[
create(:release, project: project, released_at: Time.zone.now - 2.days),
create(:release, project: project, released_at: Time.zone.now - 1.day),
create(:release, project: project, released_at: Time.zone.now)
]
end
it { is_expected.to belong_to(:project) }
it { is_expected.to delegate_method(:avatar_path).to(:project) }
@ -11,12 +22,21 @@ RSpec.describe Ci::Catalog::Resource, feature_category: :pipeline_composition do
describe '.for_projects' do
it 'returns catalog resources for the given project IDs' do
project = create(:project)
resource = create(:catalog_resource, project: project)
resources_for_projects = described_class.for_projects(project.id)
expect(resources_for_projects).to contain_exactly(resource)
end
end
describe '#versions' do
it 'returns releases ordered by released date descending' do
expect(resource.versions).to eq(releases.reverse)
end
end
describe '#latest_version' do
it 'returns the latest release' do
expect(resource.latest_version).to eq(releases.last)
end
end
end

View File

@ -59,7 +59,8 @@ RSpec.describe 'Query.work_item(id)', feature_category: :team_planning do
'readWorkItem' => true,
'updateWorkItem' => true,
'deleteWorkItem' => false,
'adminWorkItem' => true
'adminWorkItem' => true,
'adminParentLink' => true
},
'project' => hash_including('id' => project.to_gid.to_s, 'fullPath' => project.full_path)
)