From 3c3db9066b4a7505807de3ba2aeae317ef129585 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Wed, 25 Jun 2025 21:10:09 +0000 Subject: [PATCH] Add latest changes from gitlab-org/gitlab@master --- app/assets/javascripts/notes/index.js | 2 +- .../ref/components/ref_selector.vue | 12 + .../repository/components/header_area.vue | 1 + .../vue_shared/components/markdown/field.vue | 6 + .../vue_shared/components/markdown/header.vue | 31 ++- .../components/markdown/markdown_editor.vue | 6 + .../components/work_item_description.vue | 33 ++- .../ai_permissions_for_project.query.graphql | 8 + app/models/ci/build.rb | 2 +- app/models/ci/slsa/provenance_statement.rb | 44 +++- app/models/concerns/ci/metadatable.rb | 8 + config/routes/admin.rb | 6 +- db/docs/ci_runner_machines.yml | 1 + db/docs/ci_runners.yml | 1 + doc/solutions/components/_index.md | 2 +- doc/solutions/components/guide_on_sod.md | 2 +- .../static_reachability.md | 222 +++++++----------- .../set_up_gitlab_agent_and_proxies.md | 2 +- locale/gitlab.pot | 21 +- scripts/frontend/quarantined_vue3_specs.txt | 1 - .../workspaces_kubernetes_setup.sh | 2 +- .../factories/ci/slsa/provenance_statement.rb | 3 +- .../default_branch_selector_spec.js | 1 + .../ref/components/ref_selector_spec.js | 19 ++ .../repository/components/header_area_spec.js | 8 +- .../snippet_description_edit_spec.js.snap | 87 ------- .../snippet_description_edit_spec.js | 4 - .../components/work_item_description_spec.js | 118 ++++++++++ spec/models/ci/build_spec.rb | 15 +- .../ci/slsa/provenance_statement_spec.rb | 67 +++++- spec/routing/admin_routing_spec.rb | 8 + 31 files changed, 477 insertions(+), 266 deletions(-) create mode 100644 app/assets/javascripts/work_items/graphql/ai_permissions_for_project.query.graphql delete mode 100644 spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap diff --git a/app/assets/javascripts/notes/index.js b/app/assets/javascripts/notes/index.js index d064e3b59a6..c2dd846065b 100644 --- a/app/assets/javascripts/notes/index.js +++ b/app/assets/javascripts/notes/index.js @@ -66,7 +66,7 @@ export default ({ editorAiActions = [] } = {}) => { reportAbusePath: notesDataset.reportAbusePath, newCommentTemplatePaths: JSON.parse(notesDataset.newCommentTemplatePaths), resourceGlobalId: convertToGraphQLId(noteableData.noteableType, noteableData.id), - editorAiActions: editorAiActions.map((factory) => factory(noteableData)), + legacyEditorAiActions: editorAiActions.map((factory) => factory(noteableData)), newCustomEmojiPath: notesDataset.newCustomEmojiPath, }, data() { diff --git a/app/assets/javascripts/ref/components/ref_selector.vue b/app/assets/javascripts/ref/components/ref_selector.vue index 22decb35567..2e1d6e6b0ec 100644 --- a/app/assets/javascripts/ref/components/ref_selector.vue +++ b/app/assets/javascripts/ref/components/ref_selector.vue @@ -96,6 +96,11 @@ export default { required: false, default: null, }, + defaultBranch: { + type: String, + required: false, + default: null, + }, }, data() { return { @@ -131,6 +136,13 @@ export default { selectedRefFallback; } + const defaultBranchData = branches.find((branch) => branch.name === this.defaultBranch); + // since the API for getting list of branches is paginated, we might not have a + // default branch available, so in that case we add it to the list + if (this.defaultBranch && !defaultBranchData) { + branches.push({ name: this.defaultBranch, value: this.defaultBranch, default: true }); + } + return formatListBoxItems({ branches, tags, commits, selectedRef }); }, branches() { diff --git a/app/assets/javascripts/repository/components/header_area.vue b/app/assets/javascripts/repository/components/header_area.vue index 21bc1f8328e..845722a764e 100644 --- a/app/assets/javascripts/repository/components/header_area.vue +++ b/app/assets/javascripts/repository/components/header_area.vue @@ -223,6 +223,7 @@ export default { data-testid="ref-dropdown-container" :project-id="projectId" :value="refSelectorValue" + :default-branch="rootRef" use-symbolic-ref-names :query-params="refSelectorQueryParams" @input="onInput" diff --git a/app/assets/javascripts/vue_shared/components/markdown/field.vue b/app/assets/javascripts/vue_shared/components/markdown/field.vue index 51cf065186e..33c4d02a31e 100644 --- a/app/assets/javascripts/vue_shared/components/markdown/field.vue +++ b/app/assets/javascripts/vue_shared/components/markdown/field.vue @@ -139,6 +139,11 @@ export default { required: false, default: false, }, + editorAiActions: { + type: Array, + required: false, + default: () => [], + }, }, data() { return { @@ -362,6 +367,7 @@ export default { :data-uploads-path="uploadsPath" > [], }, - editorAiActions: { default: () => [] }, mrGeneratedContent: { default: null }, canSummarizeChanges: { default: false }, canUseComposer: { default: false }, + legacyEditorAiActions: { default: () => [] }, }, props: { + editorAiActions: { + type: Array, + required: false, + default: () => [], + }, previewMarkdown: { type: Boolean, required: true, @@ -123,6 +128,7 @@ export default { }, data() { const modifierKey = getModifierKey(); + return { tag: '> ', suggestPopoverVisible: false, @@ -138,6 +144,12 @@ export default { }; }, computed: { + aiActions() { + if (this.editorAiActions.length > 0) { + return this.editorAiActions; + } + return this.legacyEditorAiActions; + }, commentTemplatePaths() { return this.newCommentTemplatePaths.length > 0 ? this.newCommentTemplatePaths @@ -181,6 +193,17 @@ export default { totalHighlights: this.findAndReplace.totalMatchCount, }); }, + previewToggleTooltip() { + return sprintf( + this.previewMarkdown + ? s__('MarkdownEditor|Continue editing (%{shiftKey}%{modifierKey}P)') + : s__('MarkdownEditor|Preview (%{shiftKey}%{modifierKey}P)'), + { + shiftKey: this.shiftKey, + modifierKey: this.modifierKey, + }, + ); + }, }, watch: { showSuggestPopover() { @@ -518,8 +541,10 @@ export default { >
-
+
diff --git a/app/assets/javascripts/vue_shared/components/markdown/markdown_editor.vue b/app/assets/javascripts/vue_shared/components/markdown/markdown_editor.vue index 23b45f8a787..f043f125fce 100644 --- a/app/assets/javascripts/vue_shared/components/markdown/markdown_editor.vue +++ b/app/assets/javascripts/vue_shared/components/markdown/markdown_editor.vue @@ -143,6 +143,11 @@ export default { required: false, default: () => [], }, + editorAiActions: { + type: Array, + required: false, + default: () => [], + }, }, data() { let editingMode; @@ -399,6 +404,7 @@ export default { :new-comment-template-paths="newCommentTemplatePaths" :can-attach-file="!disableAttachments" :can-suggest="codeSuggestionsConfig.canSuggest" + :editor-ai-actions="editorAiActions" :line="codeSuggestionsConfig.line" :lines="codeSuggestionsConfig.lines" :show-suggest-popover="codeSuggestionsConfig.showPopover" diff --git a/app/assets/javascripts/work_items/components/work_item_description.vue b/app/assets/javascripts/work_items/components/work_item_description.vue index cf2d0727cc6..acdc1415613 100644 --- a/app/assets/javascripts/work_items/components/work_item_description.vue +++ b/app/assets/javascripts/work_items/components/work_item_description.vue @@ -17,6 +17,7 @@ import { autocompleteDataSources, markdownPreviewPath, } from '~/work_items/utils'; +import projectPermissionsQuery from '../graphql/ai_permissions_for_project.query.graphql'; import workItemByIidQuery from '../graphql/work_item_by_iid.query.graphql'; import workItemDescriptionTemplateQuery from '../graphql/work_item_description_template.query.graphql'; import { i18n, NEW_WORK_ITEM_IID, TRACKING_CATEGORY_SHOW, ROUTES } from '../constants'; @@ -39,11 +40,6 @@ export default { WorkItemDescriptionTemplateListbox, }, mixins: [Tracking.mixin()], - provide: { - editorAiActions: window.gon?.licensed_features?.generateDescription - ? [generateDescriptionAction()] - : [], - }, inject: ['isGroup'], props: { description: { @@ -137,12 +133,19 @@ export default { descriptionTemplate: null, appliedTemplate: '', showTemplateApplyWarning: false, + workspacePermissions: {}, }; }, computed: { createFlow() { return this.workItemId === newWorkItemId(this.newWorkItemType); }, + editorAiActions() { + const { id, userPermissions } = this.workspacePermissions; + return userPermissions?.generateDescription + ? [generateDescriptionAction({ resourceId: id })] + : []; + }, workItemFullPath() { return this.createFlow ? newWorkItemFullPath(this.fullPath, this.newWorkItemType) @@ -343,6 +346,25 @@ export default { this.$emit('error', s__('WorkItem|Unable to find selected template.')); }, }, + workspacePermissions: { + query() { + return projectPermissionsQuery; + }, + variables() { + return { + fullPath: this.fullPath, + }; + }, + update(data) { + return data.workspace || {}; + }, + skip() { + return this.isGroup; + }, + error(error) { + Sentry.captureException(error); + }, + }, }, methods: { checkForConflicts() { @@ -545,6 +567,7 @@ export default { :autocomplete-data-sources="autocompleteDataSources" :restricted-tool-bar-items="restrictedToolBarItems" :uploads-path="uploadsPath" + :editor-ai-actions="editorAiActions" enable-autocomplete supports-quick-actions :autofocus="autofocus" diff --git a/app/assets/javascripts/work_items/graphql/ai_permissions_for_project.query.graphql b/app/assets/javascripts/work_items/graphql/ai_permissions_for_project.query.graphql new file mode 100644 index 00000000000..d9aadfa03b6 --- /dev/null +++ b/app/assets/javascripts/work_items/graphql/ai_permissions_for_project.query.graphql @@ -0,0 +1,8 @@ +query projectGenerateDescriptionPermissions($fullPath: ID!) { + workspace: project(fullPath: $fullPath) { + id + userPermissions { + generateDescription + } + } +} diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index bdc41442b55..53fb4176185 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -1097,7 +1097,7 @@ module Ci def debug_mode? # perform the check on both sides in case the runner version is old - metadata&.debug_trace_enabled? || + debug_trace_enabled? || Gitlab::Utils.to_boolean(variables['CI_DEBUG_SERVICES']&.value, default: false) || Gitlab::Utils.to_boolean(variables['CI_DEBUG_TRACE']&.value, default: false) end diff --git a/app/models/ci/slsa/provenance_statement.rb b/app/models/ci/slsa/provenance_statement.rb index 90c8abf81e6..bfbb1f87189 100644 --- a/app/models/ci/slsa/provenance_statement.rb +++ b/app/models/ci/slsa/provenance_statement.rb @@ -30,14 +30,22 @@ module Ci @predicate_type = "https://slsa.dev/provenance/v1" end - def as_json(options = nil) - json = super - exceptions = ["_type"] - json.deep_transform_keys do |k| - next k if exceptions.include?(k) + def deep_change_case(json) + exceptions = %w[_type variables] - k.camelize(:lower) + new_json = {} + json.each do |key, value| + key = key.camelize(:lower) if exceptions.exclude?(key) + value = deep_change_case(value) if value.is_a?(Hash) && exceptions.exclude?(key) + + new_json[key] = value end + + new_json + end + + def as_json(options = nil) + deep_change_case(super) end def attributes @@ -52,7 +60,7 @@ module Ci def self.from_build(build) # TODO: update buildType as part of https://gitlab.com/gitlab-org/gitlab/-/issues/426764 build_type = "https://gitlab.com/gitlab-org/gitlab/-/issues/546150" - external_parameters = { variables: build.variables.map(&:key) } + external_parameters = ExternalParameters.from_build(build) internal_parameters = { architecture: build.runner_manager.architecture, executor: build.runner_manager.executor_type, @@ -94,6 +102,28 @@ module Ci end end + class ExternalParameters + include ActiveModel::Model + + attr_accessor :source, :entry_point, :variables + + def self.from_build(build) + source = Gitlab::Routing.url_helpers.project_url(build.project) + entry_point = build.name + + variables = {} + build.variables.each do |variable| + variables[variable.key] = if variable.masked? + '[MASKED]' + else + variable.value + end + end + + ExternalParameters.new(source: source, entry_point: entry_point, variables: variables) + end + end + class Builder include ActiveModel::Model diff --git a/app/models/concerns/ci/metadatable.rb b/app/models/concerns/ci/metadatable.rb index 740795a901a..1852718755f 100644 --- a/app/models/concerns/ci/metadatable.rb +++ b/app/models/concerns/ci/metadatable.rb @@ -107,6 +107,14 @@ module Ci end end + # TODO: Update this logic when column `p_ci_builds.debug_trace_enabled` is added. + # See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/194954#note_2574776849. + def debug_trace_enabled? + return true if degenerated? + + metadata&.debug_trace_enabled? + end + private def read_metadata_attribute(legacy_key, metadata_key, default_value = nil) diff --git a/config/routes/admin.rb b/config/routes/admin.rb index 9d089383b88..7b74b6609e5 100644 --- a/config/routes/admin.rb +++ b/config/routes/admin.rb @@ -123,7 +123,11 @@ namespace :admin do resource :system_info, controller: 'system_info', only: [:show] - resources :projects, only: [:index] + resources :projects, only: [:index] do + collection do + get :active, :inactive, to: 'projects#index' + end + end resources :usage_trends, only: :index resource :dev_ops_reports, controller: 'dev_ops_report', only: :show diff --git a/db/docs/ci_runner_machines.yml b/db/docs/ci_runner_machines.yml index bd009b318b9..3c72f54622b 100644 --- a/db/docs/ci_runner_machines.yml +++ b/db/docs/ci_runner_machines.yml @@ -10,4 +10,5 @@ description: Routing table for CI runner managers introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/168131 milestone: '17.6' gitlab_schema: gitlab_ci_cell_local +sharding_key_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/460084 table_size: small diff --git a/db/docs/ci_runners.yml b/db/docs/ci_runners.yml index 1d00b816212..c014108ccf5 100644 --- a/db/docs/ci_runners.yml +++ b/db/docs/ci_runners.yml @@ -10,4 +10,5 @@ description: Routing table for CI runners introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/166308 milestone: '17.6' gitlab_schema: gitlab_ci_cell_local +sharding_key_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/442395 table_size: small diff --git a/doc/solutions/components/_index.md b/doc/solutions/components/_index.md index bee6a497c55..266de76ffe1 100644 --- a/doc/solutions/components/_index.md +++ b/doc/solutions/components/_index.md @@ -50,6 +50,6 @@ Automatically sync Jira issues to GitLab to unlock VSA metrics tracking. Real-ti [Agentic Workflow: Apply Coding Style Guide](duo_workflow/duo_workflow_codestyle.md) -## Compliance and Best Practice +## Compliance and Best Practices [Guide on Separation of Duties](guide_on_sod.md) diff --git a/doc/solutions/components/guide_on_sod.md b/doc/solutions/components/guide_on_sod.md index 63a6c0818ef..39f3094f250 100644 --- a/doc/solutions/components/guide_on_sod.md +++ b/doc/solutions/components/guide_on_sod.md @@ -37,7 +37,7 @@ The GitLab approach to implementing SoD through Role-Based Access Control (RBAC) ### Role-Based Access Control (RBAC) -TRBAC forms the framework for implementing and enforcing SoD. It governs permissions and responsibilities across the platform, ensuring compliance with the principles of least privilege. Through RBAC, organizations can: +RBAC forms the framework for implementing and enforcing SoD. It governs permissions and responsibilities across the platform, ensuring compliance with the principles of least privilege. Through RBAC, organizations can: - Implement holistic user management with granular role-based controls - Assign roles with the least privileged access principles diff --git a/doc/user/application_security/dependency_scanning/static_reachability.md b/doc/user/application_security/dependency_scanning/static_reachability.md index 87cd7a021eb..23cadcca6f8 100644 --- a/doc/user/application_security/dependency_scanning/static_reachability.md +++ b/doc/user/application_security/dependency_scanning/static_reachability.md @@ -20,20 +20,88 @@ title: Static reachability analysis {{< /history >}} -Static reachability analysis (SRA) helps you prioritize remediation of vulnerabilities in dependencies. +Static reachability analysis (SRA) helps you prioritize remediation of vulnerabilities in +dependencies. SRA identifies which dependencies your application actually uses. While dependency +scanning finds all vulnerable dependencies, SRA focuses on those that are reachable and pose higher +security risks, helping you prioritize remediation based on actual threat exposure. -An application is generally deployed with many dependencies. Dependency scanning identifies which of -those dependencies have vulnerabilities. However, not all dependencies are used by an application. -Static reachability analysis identifies those dependencies that are used, in other words reachable, -and so are a higher security risk than others. Use this information to help prioritize remediation -of vulnerabilities according to risk. +## Getting started + +If you are new to static reachability analysis, the following steps show how to enable it for your +project. + +Prerequisites: + +- Only Python projects are supported. +- [Dependency Scanning analyzer](https://gitlab.com/gitlab-org/security-products/analyzers/dependency-scanning) + version 0.23.0 and later. +- Enable [Dependency Scanning by using SBOM](dependency_scanning_sbom/_index.md#configuration). + [Gemnasium](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium) analyzers are not + supported. + + Follow the [pip](dependency_scanning_sbom/_index.md#pip) or + [pipenv](dependency_scanning_sbom/_index.md#pipenv) + related instructions for dependency scanning using SBOM. You can also use any other Python package + manager that is + [supported](https://gitlab.com/gitlab-org/security-products/analyzers/dependency-scanning#supported-files) + by the DS analyzer. + +Exclusions: + +- SRA cannot be used together with either a scan execution policy or pipeline execution policy. + +To enable SRA: + +- On the left sidebar, select **Search or go to** and find your project. +- Edit the `.gitlab-ci.yml` file, and add one of the following. + + If you're using the CI/CD template, add the following (ensure there is only one `variables:` + line): + + ```yaml + variables: + DS_STATIC_REACHABILITY_ENABLED: true + ``` + + If you're using the [Dependency Scanning component](https://gitlab.com/components/dependency-scanning), + add the following (ensuring there is only one `include:` line.): + + ```yaml + include: + - component: ${CI_SERVER_FQDN}/components/dependency-scanning/main@0 + inputs: + enable_static_reachability: true + rules: + - if: $CI_SERVER_HOST == "gitlab.com" + ``` + +At this point, SRA is enabled in your pipeline. When dependency scanning runs and outputs an SBOM, +the results are supplemented by static reachability analysis. + +## Understanding the results To identify vulnerable dependencies that are reachable, either: -- Hover over the **Severity** value of a vulnerability in the vulnerability report. -- Check the `Reachable` value in the vulnerability page. +- In the vulnerability report, hover over the **Severity** value of a vulnerability. +- In a vulnerability's details page, check the **Reachable** value. - Use a GraphQL query to list those vulnerabilities that are reachable. +A dependency can have one of the following reachability values: + +Yes +: The package linked to this vulnerability is confirmed reachable in code. + +Not Found +: SRA ran successfully but did not detect usage of the vulnerable package. If a vulnerable +dependency's reachability value is shown as **Not Found** exercise caution rather than completely +dismissing it, because the beta version of SRA may produce false negatives. + +Not Available +: SRA was not executed, so no reachability data exists. + +When a direct dependency is marked as **in use**, all its transitive dependencies are also marked as +**in use**. + ## Supported languages and package managers Static reachability analysis is available only for Python projects. SRA uses the new dependency @@ -43,140 +111,20 @@ scanning analyzer to generate SBOMs and so supports the same package managers as |----------|----------------------------| | Python | `pip`, `pipenv`, `poetry`, `uv` | -## Enable static reachability analysis +## Running SRA in an offline environment -Enable static reachability analysis to identify high-risk dependencies. - -Prerequisites: - -- Enable [Dependency Scanning by using SBOM](dependency_scanning_sbom/_index.md#getting-started). - - Make sure you follow the [pip](dependency_scanning_sbom/_index.md#pip) or [pipenv](dependency_scanning_sbom/_index.md#pipenv) - related instructions for dependency scanning using SBOM. You can also use any other Python package manager that is [supported](https://gitlab.com/gitlab-org/security-products/analyzers/dependency-scanning#supported-files) by the DS analyzer. - -To enable static reachability analysis from GitLab 18.0 and later: - -- Set the CI/CD variable `DS_STATIC_REACHABILITY_ENABLED` to `true` - -Static reachability is integrated into the `dependency-scanning` job of the latest Dependency-Scanning template. -Alternatively you can enable Static Reachability by including the [Dependency Scanning component](https://gitlab.com/components/dependency-scanning) rather than using the standard Dependency-Scanning template. - -```yaml -include: - - component: ${CI_SERVER_FQDN}/components/dependency-scanning/main@0 - inputs: - enable_static_reachability: true - rules: - - if: $CI_SERVER_HOST == "gitlab.com" -``` - -Please notice that to use GitLab.com components on a GitLab Self-Managed instance, you [must mirror](../../../ci/components/_index.md#use-a-gitlabcom-component-on-gitlab-self-managed) the component project. - -Static reachability analysis functionality is supported in [Dependency Scanning analyzer](https://gitlab.com/gitlab-org/security-products/analyzers/dependency-scanning) version `0.23.0` and all subsequent versions. - -
If you are using GitLab 17.11 follow these instructions to enable Static Reachability Analysis - -- Make sure you extend `dependency-scanning-with-reachability` needs section to depend on the build job that creates the artifact required by the DS analyzer. - -```yaml -stages: - - build - - test - -include: - - template: Jobs/Dependency-Scanning.latest.gitlab-ci.yml - -variables: - DS_STATIC_REACHABILITY_ENABLED: true - DS_ENFORCE_NEW_ANALYZER: true - -# create job required by the DS analyzer to create pipdeptree.json -# https://docs.gitlab.com/user/application_security/dependency_scanning/dependency_scanning_sbom/#pip -create: - stage: build - image: "python:latest" - script: - - "pip install -r requirements.txt" - - "pip install pipdeptree" - - "pipdeptree --json > pipdeptree.json" - artifacts: - when: on_success - access: developer - paths: ["**/pipdeptree.json"] - -dependency-scanning-with-reachability: - needs: - - job: gitlab-static-reachability - optional: true - artifacts: true - - job: create - optional: true - artifacts: true -``` - -Static reachability in 17.11 introduces two key jobs: - -- `gitlab-static-reachability`: Performs Static Reachability Analysis (SRA) on your Python files. -- `dependency-scanning-with-reachability`: Executes dependency scanning and generates an SBOM report enriched with reachability data. This job requires the artifact output from the `gitlab-static-reachability` job. - -{{< alert type="note" >}} - -When you enable static reachability feature for non-Python projects, the -`gitlab-static-reachability` job will fail but won't break your pipeline, because it's configured to -allow failures. In such cases, the `dependency-scanning-with-reachability` job will perform standard -dependency scanning without adding reachability data to the SBOM. - -{{< /alert >}} - -
+To use the dependency scanning component in an offline environment, you must first +[mirror the component project](../../../ci/components/_index.md#use-a-gitlabcom-component-on-gitlab-self-managed). ## How static reachability analysis works -SRA (Static reachability analysis) identifies dependencies used in a project's code and marks them and their dependencies as reachable. +Dependency scanning generates an SBOM report that identifies all components and their transitive +dependencies. Static reachability analysis checks each dependency in the SBOM report and adds a +reachability value to the SBOM report. The enriched SBOM is then ingested by the GitLab instance. The following are marked as not found: - Dependencies that are found in the project's lock files but are not imported in the code. -- Tools that are included in the project's lock files for local usage but are not imported in the code. - For example, tools such as coverage testing or linting packages are marked as not found even if used locally. - -SRA requires two key components: - -- Dependency scanning (DS): Generates an SBOM report that identifies all components and their transitive dependencies. -- GitLab Advanced SAST (GLAS): Performs static reachability analysis to provide a report showing direct dependencies usage in the codebase. - -SRA adds reachability data to the SBOM output by dependency scanning. The enriched SBOM is then ingested by the GitLab instance. - -Reachability data in the UI can have one of the following values: - -| Reachability values | Description | -|---------------------|---------------------------------------------------------------------------| -| Yes | The package linked to this vulnerability is confirmed reachable in code | -| Not Found | SRA ran successfully but did not detect usage of the vulnerable package | -| Not Available | SRA was not executed, therefore no reachability data exists | - -## Where to find the reachability data - -The reachability data is available in the vulnerability report - -![Reachability on the vulnerability report](img/sr_vulnerability_report_v17_11.png) - -and the vulnerability page - -![Reachability on the vulnerability page](img/sr_vulnerability_page_v17_11.png) - -Finally reachability data can be reached using GraphQL. - -{{< alert type="warning" >}} - -When a vulnerability reachability value shows as "Not Found," exercise caution rather than completely dismissing it, because the beta version of SRA may produce false negatives. - -{{< /alert >}} - -## Restrictions - -Static reachability analysis has the following limitations: - -- When a direct dependency is marked as `in use`, all its transitive dependencies are also marked as `in use`. -- Requires the new [dependency scanning analyzer](https://gitlab.com/gitlab-org/security-products/analyzers/dependency-scanning). [Gemnasium](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium) analyzers are not supported. -- SRA on beta is not supported in combination with Scan and Pipeline execution policies +- Tools that are included in the project's lock files for local usage but are not imported in the + code. For example, tools such as coverage testing or linting packages are marked as not found even + if used locally. diff --git a/doc/user/workspace/set_up_gitlab_agent_and_proxies.md b/doc/user/workspace/set_up_gitlab_agent_and_proxies.md index 369d484b8c0..9cf4ceba31b 100644 --- a/doc/user/workspace/set_up_gitlab_agent_and_proxies.md +++ b/doc/user/workspace/set_up_gitlab_agent_and_proxies.md @@ -317,7 +317,7 @@ To install the Helm chart for the GitLab workspaces proxy: helm upgrade --install gitlab-workspaces-proxy \ gitlab-workspaces-proxy/gitlab-workspaces-proxy \ - --version=0.1.19 \ + --version=0.1.20 \ --namespace="gitlab-workspaces" \ --set="ingress.enabled=true" \ --set="ingress.hosts[0].host=${GITLAB_WORKSPACES_PROXY_DOMAIN}" \ diff --git a/locale/gitlab.pot b/locale/gitlab.pot index c6691f820a7..6aa3352be8d 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -4471,6 +4471,9 @@ msgstr "" msgid "AdminSelfHostedModels|There was an error saving the self-hosted model. Please try again." msgstr "" +msgid "AdminSelfHostedModels|This model cannot be applied to all %{mainFeature} sub-features" +msgstr "" + msgid "AdminSelfHostedModels|This self-hosted model cannot be deleted" msgstr "" @@ -8187,6 +8190,9 @@ msgstr "" msgid "Apply this approval rule to all branches or a specific protected branch." msgstr "" +msgid "Apply to all button" +msgstr "" + msgid "Applying" msgstr "" @@ -23358,6 +23364,9 @@ msgstr "" msgid "DuoAgenticChat|GitLab Duo Agentic Chat" msgstr "" +msgid "DuoAgentsPlatform|Agent Flow" +msgstr "" + msgid "DuoAgentsPlatform|Agents" msgstr "" @@ -23397,9 +23406,6 @@ msgstr "" msgid "DuoAgentsPlatform|Prompt" msgstr "" -msgid "DuoAgentsPlatform|Prompt is unavailable" -msgstr "" - msgid "DuoAgentsPlatform|Run an Agent Flow" msgstr "" @@ -37381,6 +37387,9 @@ msgstr "" msgid "MarkdownEditor|Close find and replace bar" msgstr "" +msgid "MarkdownEditor|Continue editing (%{shiftKey}%{modifierKey}P)" +msgstr "" + msgid "MarkdownEditor|Find and replace" msgstr "" @@ -37405,6 +37414,9 @@ msgstr "" msgid "MarkdownEditor|Outdent line (%{modifier_key}[)" msgstr "" +msgid "MarkdownEditor|Preview (%{shiftKey}%{modifierKey}P)" +msgstr "" + msgid "MarkdownEditor|header" msgstr "" @@ -40011,6 +40023,9 @@ msgstr "" msgid "ModelSelection|Successfully updated %{mainFeature} / %{title}" msgstr "" +msgid "ModelSelection|Successfully updated all %{mainFeature} features" +msgstr "" + msgid "Modified" msgstr "" diff --git a/scripts/frontend/quarantined_vue3_specs.txt b/scripts/frontend/quarantined_vue3_specs.txt index 907f1e73dee..5e60be3e3dd 100644 --- a/scripts/frontend/quarantined_vue3_specs.txt +++ b/scripts/frontend/quarantined_vue3_specs.txt @@ -114,7 +114,6 @@ spec/frontend/sidebar/components/confidential/confidentiality_dropdown_spec.js spec/frontend/sidebar/components/confidential/sidebar_confidentiality_widget_spec.js spec/frontend/sidebar/components/milestone/milestone_dropdown_spec.js spec/frontend/sidebar/components/subscriptions/subscriptions_dropdown_spec.js -spec/frontend/snippets/components/snippet_description_edit_spec.js spec/frontend/super_sidebar/components/sidebar_portal_spec.js spec/frontend/super_sidebar/components/user_menu_spec.js spec/frontend/tooltips/index_spec.js diff --git a/scripts/remote_development/workspaces_kubernetes_setup.sh b/scripts/remote_development/workspaces_kubernetes_setup.sh index 8da457d8178..b4da7899b67 100755 --- a/scripts/remote_development/workspaces_kubernetes_setup.sh +++ b/scripts/remote_development/workspaces_kubernetes_setup.sh @@ -60,7 +60,7 @@ fi if [ -z "${GITLAB_WORKSPACES_PROXY_HELM_CHART_VERSION}" ]; then echo "GITLAB_WORKSPACES_PROXY_HELM_CHART_VERSION is not explicitly set. Using default." - GITLAB_WORKSPACES_PROXY_HELM_CHART_VERSION="0.1.19" + GITLAB_WORKSPACES_PROXY_HELM_CHART_VERSION="0.1.20" fi if [ -z "${GITLAB_WORKSPACES_PROXY_HELM_RELEASE_NAMESPACE}" ]; then diff --git a/spec/factories/ci/slsa/provenance_statement.rb b/spec/factories/ci/slsa/provenance_statement.rb index 5ba9f12c686..92cdab45065 100644 --- a/spec/factories/ci/slsa/provenance_statement.rb +++ b/spec/factories/ci/slsa/provenance_statement.rb @@ -36,7 +36,8 @@ FactoryBot.define do external_parameters do { repository: "https://gitlab.com/tanuki/hello-world", - ref: "refs/heads/main" + ref: "refs/heads/main", + variables: { CI_PIPELINE: "test", ANOTHER_UPPERCASED_VAR: "test" } } end diff --git a/spec/frontend/projects/settings/components/default_branch_selector_spec.js b/spec/frontend/projects/settings/components/default_branch_selector_spec.js index aa50683b185..6769e28dec8 100644 --- a/spec/frontend/projects/settings/components/default_branch_selector_spec.js +++ b/spec/frontend/projects/settings/components/default_branch_selector_spec.js @@ -28,6 +28,7 @@ describe('projects/settings/components/default_branch_selector', () => { it('displays a RefSelector component', () => { expect(findRefSelector().props()).toEqual({ disabled, + defaultBranch: null, value: persistedDefaultBranch, enabledRefTypes: [REF_TYPE_BRANCHES], projectId, diff --git a/spec/frontend/ref/components/ref_selector_spec.js b/spec/frontend/ref/components/ref_selector_spec.js index 1d775968beb..eb3a7a120d7 100644 --- a/spec/frontend/ref/components/ref_selector_spec.js +++ b/spec/frontend/ref/components/ref_selector_spec.js @@ -886,4 +886,23 @@ describe('Ref selector component', () => { }); }); }); + + describe('default branch handling', () => { + const defaultBranchName = 'my-branch'; + + beforeEach(() => { + branchesApiCallSpy = jest.fn().mockReturnValue([HTTP_STATUS_OK, []]); // Mock branches API without the default branch + }); + + it('adds default branch to dropdown when not in initial API response', async () => { + createComponent({ propsData: { defaultBranch: defaultBranchName } }); + await waitForRequests(); + + const defaultBranchItem = findBranchDropdownItems().filter( + (item) => item.text().includes(defaultBranchName) && item.text().includes('default'), + ); + + expect(defaultBranchItem.length).toBe(1); + }); + }); }); diff --git a/spec/frontend/repository/components/header_area_spec.js b/spec/frontend/repository/components/header_area_spec.js index 887009843a7..6f8c512a91e 100644 --- a/spec/frontend/repository/components/header_area_spec.js +++ b/spec/frontend/repository/components/header_area_spec.js @@ -27,6 +27,8 @@ const defaultMockRoute = { }, }; +const mockRootRef = 'root-ref'; + describe('HeaderArea', () => { let wrapper; @@ -50,7 +52,9 @@ describe('HeaderArea', () => { const createComponent = ({ props = {}, route = { name: 'blobPathDecoded' }, - provided = {}, + provided = { + rootRef: mockRootRef, + }, } = {}) => { return shallowMountExtended(HeaderArea, { provide: { @@ -92,7 +96,7 @@ describe('HeaderArea', () => { describe('Ref selector', () => { it('renders correctly', () => { - expect(findRefSelector().exists()).toBe(true); + expect(findRefSelector().props('defaultBranch')).toBe(mockRootRef); }); it('renders correctly when branch names ending with .json', () => { diff --git a/spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap b/spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap deleted file mode 100644 index 90c2457e998..00000000000 --- a/spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap +++ /dev/null @@ -1,87 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Snippet Description Edit component rendering matches the snapshot 1`] = ` -
- -
- -
-
-
-