Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
		
							parent
							
								
									f26a600a69
								
							
						
					
					
						commit
						c726131474
					
				|  | @ -247,7 +247,7 @@ coverage-frontend: | ||||||
|   extends: |   extends: | ||||||
|     - .default-retry |     - .default-retry | ||||||
|     - .yarn-cache |     - .yarn-cache | ||||||
|     - .frontend:rules:ee-mr-and-default-branch-only |     - .frontend:rules:coverage-frontend | ||||||
|   needs: |   needs: | ||||||
|     - job: "jest" |     - job: "jest" | ||||||
|       optional: true |       optional: true | ||||||
|  |  | ||||||
|  | @ -839,13 +839,14 @@ | ||||||
|     - <<: *if-merge-request |     - <<: *if-merge-request | ||||||
|       changes: *frontend-patterns-for-as-if-foss |       changes: *frontend-patterns-for-as-if-foss | ||||||
| 
 | 
 | ||||||
| .frontend:rules:ee-mr-and-default-branch-only: | .frontend:rules:coverage-frontend: | ||||||
|   rules: |   rules: | ||||||
|     - <<: *if-not-ee |     - <<: *if-not-ee | ||||||
|       when: never |       when: never | ||||||
|  |     - <<: *if-merge-request-labels-pipeline-revert | ||||||
|  |       when: never | ||||||
|     - <<: *if-merge-request |     - <<: *if-merge-request | ||||||
|       changes: *code-backstage-patterns |       changes: *code-backstage-patterns | ||||||
|       when: always |  | ||||||
|     - <<: *if-default-branch-refs |     - <<: *if-default-branch-refs | ||||||
|       changes: *code-backstage-patterns |       changes: *code-backstage-patterns | ||||||
| 
 | 
 | ||||||
|  | @ -1374,12 +1375,12 @@ | ||||||
|   rules: |   rules: | ||||||
|     - <<: *if-not-ee |     - <<: *if-not-ee | ||||||
|       when: never |       when: never | ||||||
|  |     - <<: *if-merge-request-labels-pipeline-revert | ||||||
|  |       when: never | ||||||
|     - <<: *if-merge-request |     - <<: *if-merge-request | ||||||
|       changes: *code-backstage-patterns |       changes: *code-backstage-patterns | ||||||
|       when: always |  | ||||||
|     - <<: *if-default-branch-schedule-maintenance |     - <<: *if-default-branch-schedule-maintenance | ||||||
|     - <<: *if-merge-request-labels-run-all-rspec |     - <<: *if-merge-request-labels-run-all-rspec | ||||||
|       when: always |  | ||||||
| 
 | 
 | ||||||
| .rails:rules:rspec-undercoverage: | .rails:rules:rspec-undercoverage: | ||||||
|   rules: |   rules: | ||||||
|  | @ -1419,6 +1420,8 @@ | ||||||
|   rules: |   rules: | ||||||
|     - <<: *if-not-ee |     - <<: *if-not-ee | ||||||
|       when: never |       when: never | ||||||
|  |     - <<: *if-merge-request-labels-pipeline-revert | ||||||
|  |       when: never | ||||||
|     - if: '$SKIP_FLAKY_TESTS_AUTOMATICALLY == "true" || $RETRY_FAILED_TESTS_IN_NEW_PROCESS == "true"' |     - if: '$SKIP_FLAKY_TESTS_AUTOMATICALLY == "true" || $RETRY_FAILED_TESTS_IN_NEW_PROCESS == "true"' | ||||||
|       changes: *code-backstage-patterns |       changes: *code-backstage-patterns | ||||||
|       when: always |       when: always | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								Gemfile
								
								
								
								
							
							
						
						
									
										2
									
								
								Gemfile
								
								
								
								
							|  | @ -349,7 +349,7 @@ group :development do | ||||||
|   gem 'solargraph', '~> 0.46.0', require: false |   gem 'solargraph', '~> 0.46.0', require: false | ||||||
| 
 | 
 | ||||||
|   gem 'letter_opener_web', '~> 2.0.0' |   gem 'letter_opener_web', '~> 2.0.0' | ||||||
|   gem 'lookbook' |   gem 'lookbook', '~> 1.0' | ||||||
| 
 | 
 | ||||||
|   # Better errors handler |   # Better errors handler | ||||||
|   gem 'better_errors', '~> 2.9.1' |   gem 'better_errors', '~> 2.9.1' | ||||||
|  |  | ||||||
|  | @ -815,9 +815,11 @@ GEM | ||||||
|     loofah (2.18.0) |     loofah (2.18.0) | ||||||
|       crass (~> 1.0.2) |       crass (~> 1.0.2) | ||||||
|       nokogiri (>= 1.5.9) |       nokogiri (>= 1.5.9) | ||||||
|     lookbook (0.9.3) |     lookbook (1.0.3) | ||||||
|       actioncable |       actioncable | ||||||
|  |       css_parser | ||||||
|       htmlbeautifier (~> 1.3) |       htmlbeautifier (~> 1.3) | ||||||
|  |       htmlentities (~> 4.3.4) | ||||||
|       listen (~> 3.0) |       listen (~> 3.0) | ||||||
|       railties (>= 5.0) |       railties (>= 5.0) | ||||||
|       redcarpet (~> 3.5) |       redcarpet (~> 3.5) | ||||||
|  | @ -1095,7 +1097,7 @@ GEM | ||||||
|     randexp (0.1.7) |     randexp (0.1.7) | ||||||
|     rash_alt (0.4.12) |     rash_alt (0.4.12) | ||||||
|       hashie (>= 3.4) |       hashie (>= 3.4) | ||||||
|     rb-fsevent (0.11.1) |     rb-fsevent (0.11.2) | ||||||
|     rb-inotify (0.10.1) |     rb-inotify (0.10.1) | ||||||
|       ffi (~> 1.0) |       ffi (~> 1.0) | ||||||
|     rbtrace (0.4.14) |     rbtrace (0.4.14) | ||||||
|  | @ -1648,7 +1650,7 @@ DEPENDENCIES | ||||||
|   lockbox (~> 0.6.2) |   lockbox (~> 0.6.2) | ||||||
|   lograge (~> 0.5) |   lograge (~> 0.5) | ||||||
|   loofah (~> 2.18.0) |   loofah (~> 2.18.0) | ||||||
|   lookbook |   lookbook (~> 1.0) | ||||||
|   lru_redux |   lru_redux | ||||||
|   mail (= 2.7.1) |   mail (= 2.7.1) | ||||||
|   mail-smtp_pool (~> 0.1.0)! |   mail-smtp_pool (~> 0.1.0)! | ||||||
|  |  | ||||||
|  | @ -1,14 +1,18 @@ | ||||||
| <script> | <script> | ||||||
| import { GlNav, GlNavItemDropdown, GlDropdownForm } from '@gitlab/ui'; | import { GlNav, GlIcon, GlNavItemDropdown, GlDropdownForm, GlTooltipDirective } from '@gitlab/ui'; | ||||||
| import TopNavDropdownMenu from './top_nav_dropdown_menu.vue'; | import TopNavDropdownMenu from './top_nav_dropdown_menu.vue'; | ||||||
| 
 | 
 | ||||||
| export default { | export default { | ||||||
|   components: { |   components: { | ||||||
|  |     GlIcon, | ||||||
|     GlNav, |     GlNav, | ||||||
|     GlNavItemDropdown, |     GlNavItemDropdown, | ||||||
|     GlDropdownForm, |     GlDropdownForm, | ||||||
|     TopNavDropdownMenu, |     TopNavDropdownMenu, | ||||||
|   }, |   }, | ||||||
|  |   directives: { | ||||||
|  |     GlTooltip: GlTooltipDirective, | ||||||
|  |   }, | ||||||
|   props: { |   props: { | ||||||
|     navData: { |     navData: { | ||||||
|       type: Object, |       type: Object, | ||||||
|  | @ -21,15 +25,20 @@ export default { | ||||||
| <template> | <template> | ||||||
|   <gl-nav class="navbar-sub-nav"> |   <gl-nav class="navbar-sub-nav"> | ||||||
|     <gl-nav-item-dropdown |     <gl-nav-item-dropdown | ||||||
|       :text="navData.activeTitle" |       v-gl-tooltip.bottom="navData.menuTooltip" | ||||||
|       data-qa-selector="navbar_dropdown" |       data-qa-selector="navbar_dropdown" | ||||||
|       :data-qa-title="navData.activeTitle" |       data-qa-title="Menu" | ||||||
|       icon="hamburger" |  | ||||||
|       menu-class="gl-mt-3! gl-max-w-none! gl-max-h-none! gl-sm-w-auto! js-top-nav-dropdown-menu" |       menu-class="gl-mt-3! gl-max-w-none! gl-max-h-none! gl-sm-w-auto! js-top-nav-dropdown-menu" | ||||||
|       toggle-class="top-nav-toggle js-top-nav-dropdown-toggle gl-px-3!" |       toggle-class="top-nav-toggle js-top-nav-dropdown-toggle gl-px-3!" | ||||||
|       no-flip |       no-flip | ||||||
|       no-caret |       no-caret | ||||||
|     > |     > | ||||||
|  |       <template #button-content> | ||||||
|  |         <gl-icon name="hamburger" /> | ||||||
|  |         <span v-if="navData.menuTitle" class="gl-ml-3"> | ||||||
|  |           {{ navData.menuTitle }} | ||||||
|  |         </span> | ||||||
|  |       </template> | ||||||
|       <gl-dropdown-form> |       <gl-dropdown-form> | ||||||
|         <top-nav-dropdown-menu |         <top-nav-dropdown-menu | ||||||
|           :primary="navData.primary" |           :primary="navData.primary" | ||||||
|  |  | ||||||
|  | @ -10,6 +10,7 @@ import { mapActions } from 'vuex'; | ||||||
| import { __, s__ } from '~/locale'; | import { __, s__ } from '~/locale'; | ||||||
| import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; | import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; | ||||||
| import UserNameWithStatus from '~/sidebar/components/assignees/user_name_with_status.vue'; | import UserNameWithStatus from '~/sidebar/components/assignees/user_name_with_status.vue'; | ||||||
|  | import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; | ||||||
| 
 | 
 | ||||||
| export default { | export default { | ||||||
|   safeHtmlConfig: { ADD_TAGS: ['gl-emoji'] }, |   safeHtmlConfig: { ADD_TAGS: ['gl-emoji'] }, | ||||||
|  | @ -26,6 +27,7 @@ export default { | ||||||
|     SafeHtml, |     SafeHtml, | ||||||
|     GlTooltip: GlTooltipDirective, |     GlTooltip: GlTooltipDirective, | ||||||
|   }, |   }, | ||||||
|  |   mixins: [glFeatureFlagsMixin()], | ||||||
|   props: { |   props: { | ||||||
|     author: { |     author: { | ||||||
|       type: Object, |       type: Object, | ||||||
|  | @ -183,21 +185,28 @@ export default { | ||||||
|         :data-user-id="author.id" |         :data-user-id="author.id" | ||||||
|         :data-username="author.username" |         :data-username="author.username" | ||||||
|       > |       > | ||||||
|  |         <span | ||||||
|  |           v-if="glFeatures.removeUserAttributes" | ||||||
|  |           class="note-header-author-name gl-font-weight-bold" | ||||||
|  |         > | ||||||
|  |           {{ authorName }} | ||||||
|  |         </span> | ||||||
|         <user-name-with-status |         <user-name-with-status | ||||||
|  |           v-if="!glFeatures.removeUserAttributes" | ||||||
|           :name="authorName" |           :name="authorName" | ||||||
|           :availability="userAvailability(author)" |           :availability="userAvailability(author)" | ||||||
|           container-classes="note-header-author-name gl-font-weight-bold" |           container-classes="note-header-author-name gl-font-weight-bold" | ||||||
|         /> |         /> | ||||||
|       </a> |       </a> | ||||||
|       <span |       <span | ||||||
|         v-if="authorStatus" |         v-if="authorStatus && !glFeatures.removeUserAttributes" | ||||||
|         ref="authorStatus" |         ref="authorStatus" | ||||||
|         v-safe-html:[$options.safeHtmlConfig]="authorStatus" |         v-safe-html:[$options.safeHtmlConfig]="authorStatus" | ||||||
|         v-on=" |         v-on=" | ||||||
|           authorStatusHasTooltip ? { mouseenter: removeEmojiTitle, mouseleave: addEmojiTitle } : {} |           authorStatusHasTooltip ? { mouseenter: removeEmojiTitle, mouseleave: addEmojiTitle } : {} | ||||||
|         " |         " | ||||||
|       ></span> |       ></span> | ||||||
|       <span class="text-nowrap author-username"> |       <span v-if="!glFeatures.removeUserAttributes" class="text-nowrap author-username"> | ||||||
|         <a |         <a | ||||||
|           ref="authorUsernameLink" |           ref="authorUsernameLink" | ||||||
|           class="author-username-link" |           class="author-username-link" | ||||||
|  |  | ||||||
|  | @ -565,10 +565,6 @@ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .top-nav-toggle { | .top-nav-toggle { | ||||||
|   .dropdown-icon { |  | ||||||
|     @include gl-mr-3; |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   .dropdown-chevron { |   .dropdown-chevron { | ||||||
|     top: 0; |     top: 0; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | @ -1001,9 +1001,6 @@ kbd { | ||||||
|   visibility: hidden; |   visibility: hidden; | ||||||
|   top: 3px; |   top: 3px; | ||||||
| } | } | ||||||
| .top-nav-toggle .dropdown-icon { |  | ||||||
|   margin-right: 0.5rem; |  | ||||||
| } |  | ||||||
| .tanuki-logo .tanuki { | .tanuki-logo .tanuki { | ||||||
|   fill: #e24329; |   fill: #e24329; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -982,9 +982,6 @@ kbd { | ||||||
|   visibility: hidden; |   visibility: hidden; | ||||||
|   top: 3px; |   top: 3px; | ||||||
| } | } | ||||||
| .top-nav-toggle .dropdown-icon { |  | ||||||
|   margin-right: 0.5rem; |  | ||||||
| } |  | ||||||
| .tanuki-logo .tanuki { | .tanuki-logo .tanuki { | ||||||
|   fill: #e24329; |   fill: #e24329; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -11,6 +11,7 @@ class Projects::IncidentsController < Projects::ApplicationController | ||||||
|     push_force_frontend_feature_flag(:work_items, @project&.work_items_feature_flag_enabled?) |     push_force_frontend_feature_flag(:work_items, @project&.work_items_feature_flag_enabled?) | ||||||
|     push_force_frontend_feature_flag(:work_items_mvc_2, @project&.work_items_mvc_2_feature_flag_enabled?) |     push_force_frontend_feature_flag(:work_items_mvc_2, @project&.work_items_mvc_2_feature_flag_enabled?) | ||||||
|     push_frontend_feature_flag(:work_items_hierarchy, @project) |     push_frontend_feature_flag(:work_items_hierarchy, @project) | ||||||
|  |     push_frontend_feature_flag(:remove_user_attributes, @group) | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   feature_category :incident_management |   feature_category :incident_management | ||||||
|  |  | ||||||
|  | @ -42,6 +42,7 @@ class Projects::IssuesController < Projects::ApplicationController | ||||||
| 
 | 
 | ||||||
|   before_action do |   before_action do | ||||||
|     push_frontend_feature_flag(:incident_timeline, project) |     push_frontend_feature_flag(:incident_timeline, project) | ||||||
|  |     push_frontend_feature_flag(:remove_user_attributes, @group) | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   before_action only: [:index, :show] do |   before_action only: [:index, :show] do | ||||||
|  |  | ||||||
|  | @ -45,6 +45,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo | ||||||
|     push_frontend_feature_flag(:paginated_mr_discussions, project) |     push_frontend_feature_flag(:paginated_mr_discussions, project) | ||||||
|     push_frontend_feature_flag(:mr_review_submit_comment, project) |     push_frontend_feature_flag(:mr_review_submit_comment, project) | ||||||
|     push_frontend_feature_flag(:mr_experience_survey, project) |     push_frontend_feature_flag(:mr_experience_survey, project) | ||||||
|  |     push_frontend_feature_flag(:remove_user_attributes, @group) | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   before_action do |   before_action do | ||||||
|  |  | ||||||
|  | @ -1,9 +1,10 @@ | ||||||
| - view_model = top_nav_view_model(project: @project, group: @group) | - view_model = top_nav_view_model(project: @project, group: @group) | ||||||
| %ul.list-unstyled.navbar-sub-nav#js-top-nav{ data: { view_model: view_model.to_json } } | %ul.list-unstyled.nav.navbar-sub-nav#js-top-nav{ data: { view_model: view_model.to_json } } | ||||||
|   %li |   %li | ||||||
|     %a.top-nav-toggle{ href: '#', type: 'button', data: { toggle: "dropdown" } } |     %a.top-nav-toggle{ href: '#', type: 'button', data: { toggle: "dropdown" } } | ||||||
|       = sprite_icon('hamburger', css_class: "dropdown-icon") |       = sprite_icon('hamburger') | ||||||
|       = view_model[:activeTitle] |       - if view_model[:menuTitle] | ||||||
|  |         .gl-ml-3= view_model[:menuTitle] | ||||||
| 
 | 
 | ||||||
| .hidden | .hidden | ||||||
|   - view_model[:shortcuts].each do |shortcut| |   - view_model[:shortcuts].each do |shortcut| | ||||||
|  |  | ||||||
|  | @ -264,6 +264,7 @@ module Gitlab | ||||||
|     config.assets.precompile << "page_bundles/cycle_analytics.css" |     config.assets.precompile << "page_bundles/cycle_analytics.css" | ||||||
|     config.assets.precompile << "page_bundles/dashboard_projects.css" |     config.assets.precompile << "page_bundles/dashboard_projects.css" | ||||||
|     config.assets.precompile << "page_bundles/dev_ops_reports.css" |     config.assets.precompile << "page_bundles/dev_ops_reports.css" | ||||||
|  |     config.assets.precompile << "page_bundles/environments.css" | ||||||
|     config.assets.precompile << "page_bundles/epics.css" |     config.assets.precompile << "page_bundles/epics.css" | ||||||
|     config.assets.precompile << "page_bundles/error_tracking_details.css" |     config.assets.precompile << "page_bundles/error_tracking_details.css" | ||||||
|     config.assets.precompile << "page_bundles/error_tracking_index.css" |     config.assets.precompile << "page_bundles/error_tracking_index.css" | ||||||
|  |  | ||||||
|  | @ -50,6 +50,8 @@ Rails.application.configure do | ||||||
|   # Push preview path now to prevent FrozenError during view_component's initialzer |   # Push preview path now to prevent FrozenError during view_component's initialzer | ||||||
|   config.autoload_paths.push("#{config.root}/spec/components/previews") |   config.autoload_paths.push("#{config.root}/spec/components/previews") | ||||||
| 
 | 
 | ||||||
|  |   config.lookbook.page_paths = ["#{config.root}/spec/components/docs"] | ||||||
|  | 
 | ||||||
|   # Adds additional error checking when serving assets at runtime. |   # Adds additional error checking when serving assets at runtime. | ||||||
|   # Checks for improperly declared sprockets dependencies. |   # Checks for improperly declared sprockets dependencies. | ||||||
|   # Raises helpful error messages. |   # Raises helpful error messages. | ||||||
|  |  | ||||||
|  | @ -0,0 +1,8 @@ | ||||||
|  | --- | ||||||
|  | name: new_navbar_layout | ||||||
|  | introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96853 | ||||||
|  | rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/366082 | ||||||
|  | milestone: '15.4' | ||||||
|  | type: development | ||||||
|  | group: group::foundations | ||||||
|  | default_enabled: false | ||||||
|  | @ -0,0 +1,8 @@ | ||||||
|  | --- | ||||||
|  | name: remove_user_attributes | ||||||
|  | introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96447 | ||||||
|  | rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/372047 | ||||||
|  | milestone: '15.4' | ||||||
|  | type: development | ||||||
|  | group: group::code review | ||||||
|  | default_enabled: false | ||||||
|  | @ -1,14 +0,0 @@ | ||||||
| # frozen_string_literal: true |  | ||||||
| 
 |  | ||||||
| if Rails.env.development? |  | ||||||
|   # :nocov: Lookbook is only available in development |  | ||||||
|   Lookbook::ApplicationController.class_eval do |  | ||||||
|     content_security_policy false |  | ||||||
|   end |  | ||||||
| 
 |  | ||||||
|   Rails.application.configure do |  | ||||||
|     config.lookbook.experimental_features = [:pages] |  | ||||||
|     config.lookbook.page_paths = ["#{config.root}/spec/components/docs"] |  | ||||||
|   end |  | ||||||
|   # :nocov: |  | ||||||
| end |  | ||||||
|  | @ -251,3 +251,13 @@ You must specify that Git should use OpenSSL: | ||||||
| ```shell | ```shell | ||||||
| git config --system http.sslbackend openssl | git config --system http.sslbackend openssl | ||||||
| ``` | ``` | ||||||
|  | 
 | ||||||
|  | Alternatively, you can ignore SSL verification by running: | ||||||
|  | 
 | ||||||
|  | WARNING: | ||||||
|  | Proceed with caution when [ignoring SSL](https://git-scm.com/docs/git-config#Documentation/git-config.txt-httpsslVerify) | ||||||
|  | due to the potential security issues associated with disabling this option at global level. Use this option _only_ when troubleshooting, and reinstate SSL verification immediately after. | ||||||
|  | 
 | ||||||
|  | ```shell | ||||||
|  | git config --global http.sslVerify false | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | @ -47,6 +47,7 @@ staging: | ||||||
|   script: |   script: | ||||||
|     - gem install dpl |     - gem install dpl | ||||||
|     - dpl --provider=heroku --app=my-app-staging --api_key=$HEROKU_STAGING_API_KEY |     - dpl --provider=heroku --app=my-app-staging --api_key=$HEROKU_STAGING_API_KEY | ||||||
|  |   environment: staging | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| In the above example we use Dpl to deploy `my-app-staging` to Heroku server with API key stored in `HEROKU_STAGING_API_KEY` secure variable. | In the above example we use Dpl to deploy `my-app-staging` to Heroku server with API key stored in `HEROKU_STAGING_API_KEY` secure variable. | ||||||
|  | @ -70,6 +71,7 @@ staging: | ||||||
|     - dpl --provider=heroku --app=my-app-staging --api_key=$HEROKU_STAGING_API_KEY |     - dpl --provider=heroku --app=my-app-staging --api_key=$HEROKU_STAGING_API_KEY | ||||||
|   only: |   only: | ||||||
|     - main |     - main | ||||||
|  |   environment: staging | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| The first line `apt-get update -yq` updates the list of available packages, | The first line `apt-get update -yq` updates the list of available packages, | ||||||
|  | @ -93,6 +95,7 @@ staging: | ||||||
|     - dpl --provider=heroku --app=my-app-staging --api_key=$HEROKU_STAGING_API_KEY |     - dpl --provider=heroku --app=my-app-staging --api_key=$HEROKU_STAGING_API_KEY | ||||||
|   only: |   only: | ||||||
|     - main |     - main | ||||||
|  |   environment: staging | ||||||
| 
 | 
 | ||||||
| production: | production: | ||||||
|   stage: deploy |   stage: deploy | ||||||
|  | @ -101,6 +104,7 @@ production: | ||||||
|     - dpl --provider=heroku --app=my-app-production --api_key=$HEROKU_PRODUCTION_API_KEY |     - dpl --provider=heroku --app=my-app-production --api_key=$HEROKU_PRODUCTION_API_KEY | ||||||
|   only: |   only: | ||||||
|     - tags |     - tags | ||||||
|  |   environment: production | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| We created two deploy jobs that are executed on different events: | We created two deploy jobs that are executed on different events: | ||||||
|  |  | ||||||
|  | @ -228,6 +228,7 @@ deploy_terraform: | ||||||
|   script: |   script: | ||||||
|     # Your Review App deployment scripts - for a working example please check https://gitlab.com/Flockademic/Flockademic/blob/5a45f1c2412e93810fab50e2dab8949e2d0633c7/.gitlab-ci.yml#L315 |     # Your Review App deployment scripts - for a working example please check https://gitlab.com/Flockademic/Flockademic/blob/5a45f1c2412e93810fab50e2dab8949e2d0633c7/.gitlab-ci.yml#L315 | ||||||
|     - echo |     - echo | ||||||
|  |   environment: production | ||||||
| e2e:firefox: | e2e:firefox: | ||||||
|   stage: confidence-check |   stage: confidence-check | ||||||
|   services: |   services: | ||||||
|  |  | ||||||
|  | @ -592,6 +592,7 @@ deploy: | ||||||
|     BUILD_VARIABLE: value_from_deploy_job |     BUILD_VARIABLE: value_from_deploy_job | ||||||
|   script: |   script: | ||||||
|     - echo "$BUILD_VARIABLE"  # Output is: 'value_from_build_job' due to precedence |     - echo "$BUILD_VARIABLE"  # Output is: 'value_from_build_job' due to precedence | ||||||
|  |   environment: production | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| The [`dependencies`](../yaml/index.md#dependencies) or | The [`dependencies`](../yaml/index.md#dependencies) or | ||||||
|  | @ -616,12 +617,19 @@ deploy_one: | ||||||
|     - echo "$BUILD_VERSION"  # Output is: 'hello' |     - echo "$BUILD_VERSION"  # Output is: 'hello' | ||||||
|   dependencies: |   dependencies: | ||||||
|     - build |     - build | ||||||
|  |   environment: | ||||||
|  |     name: customer1 | ||||||
|  |     deployment_tier: production | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| deploy_two: | deploy_two: | ||||||
|   stage: deploy |   stage: deploy | ||||||
|   script: |   script: | ||||||
|     - echo "$BUILD_VERSION"  # Output is empty |     - echo "$BUILD_VERSION"  # Output is empty | ||||||
|   dependencies: [] |   dependencies: [] | ||||||
|  |   environment: | ||||||
|  |     name: customer2 | ||||||
|  |     deployment_tier: production | ||||||
| 
 | 
 | ||||||
| deploy_three: | deploy_three: | ||||||
|   stage: deploy |   stage: deploy | ||||||
|  | @ -629,6 +637,10 @@ deploy_three: | ||||||
|     - echo "$BUILD_VERSION"  # Output is: 'hello' |     - echo "$BUILD_VERSION"  # Output is: 'hello' | ||||||
|   needs: |   needs: | ||||||
|     - build |     - build | ||||||
|  |   environment: | ||||||
|  |     name: customer3 | ||||||
|  |     deployment_tier: production | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| deploy_four: | deploy_four: | ||||||
|   stage: deploy |   stage: deploy | ||||||
|  | @ -637,6 +649,9 @@ deploy_four: | ||||||
|   needs: |   needs: | ||||||
|     job: build |     job: build | ||||||
|     artifacts: true |     artifacts: true | ||||||
|  |   environment: | ||||||
|  |     name: customer4 | ||||||
|  |     deployment_tier: production | ||||||
| 
 | 
 | ||||||
| deploy_five: | deploy_five: | ||||||
|   stage: deploy |   stage: deploy | ||||||
|  | @ -645,6 +660,9 @@ deploy_five: | ||||||
|   needs: |   needs: | ||||||
|     job: build |     job: build | ||||||
|     artifacts: false |     artifacts: false | ||||||
|  |   environment: | ||||||
|  |     name: customer5 | ||||||
|  |     deployment_tier: production | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| [Multi-project pipelines](../pipelines/downstream_pipelines.md#pass-dotenv-variables-created-in-a-job) | [Multi-project pipelines](../pipelines/downstream_pipelines.md#pass-dotenv-variables-created-in-a-job) | ||||||
|  |  | ||||||
|  | @ -1069,21 +1069,21 @@ This example excludes the `/auth` resource. This does not exclude child resource | ||||||
| 
 | 
 | ||||||
| ```yaml | ```yaml | ||||||
| variables: | variables: | ||||||
|   FUZZAPI_EXCLUDE_PATHS=/auth |   FUZZAPI_EXCLUDE_PATHS: /auth | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| To exclude `/auth`, and child resources (`/auth/child`), we use a wildcard. | To exclude `/auth`, and child resources (`/auth/child`), we use a wildcard. | ||||||
| 
 | 
 | ||||||
| ```yaml | ```yaml | ||||||
| variables: | variables: | ||||||
|   FUZZAPI_EXCLUDE_PATHS=/auth* |   FUZZAPI_EXCLUDE_PATHS: /auth* | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| To exclude multiple paths we can use the `;` character. In this example we exclude `/auth*` and `/v1/*`. | To exclude multiple paths we can use the `;` character. In this example we exclude `/auth*` and `/v1/*`. | ||||||
| 
 | 
 | ||||||
| ```yaml | ```yaml | ||||||
| variables: | variables: | ||||||
|   FUZZAPI_EXCLUDE_PATHS=/auth*;/v1/* |   FUZZAPI_EXCLUDE_PATHS: /auth*;/v1/* | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| ### Exclude parameters | ### Exclude parameters | ||||||
|  | @ -1343,7 +1343,15 @@ Each value in `FUZZAPI_EXCLUDE_URLS` is a regular expression. Characters such as | ||||||
| The following example excludes the URL `http://target/api/auth` and its child resources. | The following example excludes the URL `http://target/api/auth` and its child resources. | ||||||
| 
 | 
 | ||||||
| ```yaml | ```yaml | ||||||
|  | stages: | ||||||
|  |   - fuzz | ||||||
|  | 
 | ||||||
|  | include: | ||||||
|  |   - template: API-Fuzzing.gitlab-ci.yml | ||||||
|  | 
 | ||||||
| variables: | variables: | ||||||
|  |   FUZZAPI_TARGET_URL: http://target/ | ||||||
|  |   FUZZAPI_OPENAPI: test-api-specification.json | ||||||
|   FUZZAPI_EXCLUDE_URLS: http://target/api/auth |   FUZZAPI_EXCLUDE_URLS: http://target/api/auth | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
|  | @ -1352,7 +1360,15 @@ variables: | ||||||
| To exclude the URLs `http://target/api/buy` and `http://target/api/sell` but allowing to scan their child resources, for instance: `http://target/api/buy/toy` or `http://target/api/sell/chair`. You could use the value `http://target/api/buy/$,http://target/api/sell/$`. This value is using two regular expressions, each of them separated by a `,` character. Hence, it contains `http://target/api/buy$` and `http://target/api/sell$`. In each regular expression, the trailing `$` character points out where the matching URL should end. | To exclude the URLs `http://target/api/buy` and `http://target/api/sell` but allowing to scan their child resources, for instance: `http://target/api/buy/toy` or `http://target/api/sell/chair`. You could use the value `http://target/api/buy/$,http://target/api/sell/$`. This value is using two regular expressions, each of them separated by a `,` character. Hence, it contains `http://target/api/buy$` and `http://target/api/sell$`. In each regular expression, the trailing `$` character points out where the matching URL should end. | ||||||
| 
 | 
 | ||||||
| ```yaml | ```yaml | ||||||
|  | stages: | ||||||
|  |   - fuzz | ||||||
|  | 
 | ||||||
|  | include: | ||||||
|  |   - template: API-Fuzzing.gitlab-ci.yml | ||||||
|  | 
 | ||||||
| variables: | variables: | ||||||
|  |   FUZZAPI_TARGET_URL: http://target/ | ||||||
|  |   FUZZAPI_OPENAPI: test-api-specification.json | ||||||
|   FUZZAPI_EXCLUDE_URLS: http://target/api/buy/$,http://target/api/sell/$ |   FUZZAPI_EXCLUDE_URLS: http://target/api/buy/$,http://target/api/sell/$ | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
|  | @ -1361,7 +1377,15 @@ variables: | ||||||
| In order to exclude the URLs: `http://target/api/buy` and `http://target/api/sell`, and their child resources. To provide multiple URLs we use the `,` character as follows: | In order to exclude the URLs: `http://target/api/buy` and `http://target/api/sell`, and their child resources. To provide multiple URLs we use the `,` character as follows: | ||||||
| 
 | 
 | ||||||
| ```yaml | ```yaml | ||||||
|  | stages: | ||||||
|  |   - fuzz | ||||||
|  | 
 | ||||||
|  | include: | ||||||
|  |   - template: API-Fuzzing.gitlab-ci.yml | ||||||
|  | 
 | ||||||
| variables: | variables: | ||||||
|  |   FUZZAPI_TARGET_URL: http://target/ | ||||||
|  |   FUZZAPI_OPENAPI: test-api-specification.json | ||||||
|   FUZZAPI_EXCLUDE_URLS: http://target/api/buy,http://target/api/sell |   FUZZAPI_EXCLUDE_URLS: http://target/api/buy,http://target/api/sell | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
|  | @ -1370,7 +1394,15 @@ variables: | ||||||
| In order to exclude exactly `https://target/api/v1/user/create` and `https://target/api/v2/user/create` or any other version (`v3`,`v4`, and more). We could use `https://target/api/v.*/user/create$`, in the previous regular expression `.` indicates any character and `*` indicates zero or more times, additionally `$` indicates that the URL should end there. | In order to exclude exactly `https://target/api/v1/user/create` and `https://target/api/v2/user/create` or any other version (`v3`,`v4`, and more). We could use `https://target/api/v.*/user/create$`, in the previous regular expression `.` indicates any character and `*` indicates zero or more times, additionally `$` indicates that the URL should end there. | ||||||
| 
 | 
 | ||||||
| ```yaml | ```yaml | ||||||
|  | stages: | ||||||
|  |   - fuzz | ||||||
|  | 
 | ||||||
|  | include: | ||||||
|  |   - template: API-Fuzzing.gitlab-ci.yml | ||||||
|  | 
 | ||||||
| variables: | variables: | ||||||
|  |   FUZZAPI_TARGET_URL: http://target/ | ||||||
|  |   FUZZAPI_OPENAPI: test-api-specification.json | ||||||
|   FUZZAPI_EXCLUDE_URLS: https://target/api/v.*/user/create$ |   FUZZAPI_EXCLUDE_URLS: https://target/api/v.*/user/create$ | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
|  | @ -1757,12 +1789,15 @@ This solution is for pipelines in which the target API URL doesn't change (is st | ||||||
| For environments where the target API remains the same, we recommend you specify the target URL by using the `FUZZAPI_TARGET_URL` environment variable. In your `.gitlab-ci.yml` file, add a variable `FUZZAPI_TARGET_URL`. The variable must be set to the base URL of API testing target. For example: | For environments where the target API remains the same, we recommend you specify the target URL by using the `FUZZAPI_TARGET_URL` environment variable. In your `.gitlab-ci.yml` file, add a variable `FUZZAPI_TARGET_URL`. The variable must be set to the base URL of API testing target. For example: | ||||||
| 
 | 
 | ||||||
| ```yaml | ```yaml | ||||||
| include: | stages: | ||||||
|     - template: API-Fuzzing.gitlab-ci.yml |   - fuzz | ||||||
| 
 | 
 | ||||||
|   variables: | include: | ||||||
|     FUZZAPI_TARGET_URL: http://test-deployment/ |   - template: API-Fuzzing.gitlab-ci.yml | ||||||
|     FUZZAPI_OPENAPI: test-api-specification.json | 
 | ||||||
|  | variables: | ||||||
|  |   FUZZAPI_TARGET_URL: http://test-deployment/ | ||||||
|  |   FUZZAPI_OPENAPI: test-api-specification.json | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| #### Dynamic environment solutions | #### Dynamic environment solutions | ||||||
|  | @ -1820,17 +1855,17 @@ Relaxed validation is meant for cases when the OpenAPI document cannot meet Open | ||||||
| API Security can still try to consume an OpenAPI document that does not fully comply with OpenAPI specifications. To instruct API Security to perform a relaxed validation, set the variable `FUZZAPI_OPENAPI_RELAXED_VALIDATION` to any value, for example: | API Security can still try to consume an OpenAPI document that does not fully comply with OpenAPI specifications. To instruct API Security to perform a relaxed validation, set the variable `FUZZAPI_OPENAPI_RELAXED_VALIDATION` to any value, for example: | ||||||
| 
 | 
 | ||||||
| ```yaml | ```yaml | ||||||
|    stages: | stages: | ||||||
|      - fuzz |   - fuzz | ||||||
| 
 | 
 | ||||||
|    include: | include: | ||||||
|      - template: API-Fuzzing.gitlab-ci.yml |   - template: API-Fuzzing.gitlab-ci.yml | ||||||
| 
 | 
 | ||||||
|    variables: | variables: | ||||||
|      FUZZAPI_PROFILE: Quick-10 |   FUZZAPI_PROFILE: Quick-10 | ||||||
|      FUZZAPI_TARGET_URL: http://test-deployment/ |   FUZZAPI_TARGET_URL: http://test-deployment/ | ||||||
|      FUZZAPI_OPENAPI: test-api-specification.json |   FUZZAPI_OPENAPI: test-api-specification.json | ||||||
|      FUZZAPI_OPENAPI_RELAXED_VALIDATION: On |   FUZZAPI_OPENAPI_RELAXED_VALIDATION: 'On' | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| ### `No operation in the OpenAPI document is consuming any supported media type` | ### `No operation in the OpenAPI document is consuming any supported media type` | ||||||
|  |  | ||||||
|  | @ -1017,21 +1017,21 @@ This example excludes the `/auth` resource. This does not exclude child resource | ||||||
| 
 | 
 | ||||||
| ```yaml | ```yaml | ||||||
| variables: | variables: | ||||||
|   DAST_API_EXCLUDE_PATHS=/auth |   DAST_API_EXCLUDE_PATHS: /auth | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| To exclude `/auth`, and child resources (`/auth/child`), we use a wildcard. | To exclude `/auth`, and child resources (`/auth/child`), we use a wildcard. | ||||||
| 
 | 
 | ||||||
| ```yaml | ```yaml | ||||||
| variables: | variables: | ||||||
|   DAST_API_EXCLUDE_PATHS=/auth* |   DAST_API_EXCLUDE_PATHS: /auth* | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| To exclude multiple paths we use the `;` character. In this example we exclude `/auth*` and `/v1/*`. | To exclude multiple paths we use the `;` character. In this example we exclude `/auth*` and `/v1/*`. | ||||||
| 
 | 
 | ||||||
| ```yaml | ```yaml | ||||||
| variables: | variables: | ||||||
|   DAST_API_EXCLUDE_PATHS=/auth*;/v1/* |   DAST_API_EXCLUDE_PATHS: /auth*;/v1/* | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| To exclude one or more nested levels within a path we use `**`. In this example we are testing API endpoints. We are testing `/api/v1/` and `/api/v2/` of a data query requesting `mass`, `brightness` and `coordinates` data for `planet`, `moon`, `star`, and `satellite` objects. Example paths that could be scanned include, but are not limited to: | To exclude one or more nested levels within a path we use `**`. In this example we are testing API endpoints. We are testing `/api/v1/` and `/api/v2/` of a data query requesting `mass`, `brightness` and `coordinates` data for `planet`, `moon`, `star`, and `satellite` objects. Example paths that could be scanned include, but are not limited to: | ||||||
|  | @ -1044,7 +1044,7 @@ In this example we test the `brightness` endpoint only: | ||||||
| 
 | 
 | ||||||
| ```yaml | ```yaml | ||||||
| variables: | variables: | ||||||
|   DAST_API_EXCLUDE_PATHS=/api/**/mass;/api/**/coordinates |   DAST_API_EXCLUDE_PATHS: /api/**/mass;/api/**/coordinates | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| ### Exclude parameters | ### Exclude parameters | ||||||
|  | @ -1304,7 +1304,15 @@ Each value in `DAST_API_EXCLUDE_URLS` is a regular expression. Characters such a | ||||||
| The following example excludes the URL `http://target/api/auth` and its child resources. | The following example excludes the URL `http://target/api/auth` and its child resources. | ||||||
| 
 | 
 | ||||||
| ```yaml | ```yaml | ||||||
|  | stages: | ||||||
|  |   - dast | ||||||
|  | 
 | ||||||
|  | include: | ||||||
|  |   - template: DAST-API.gitlab-ci.yml | ||||||
|  | 
 | ||||||
| variables: | variables: | ||||||
|  |   DAST_API_TARGET_URL: http://target/ | ||||||
|  |   DAST_API_OPENAPI: test-api-specification.json | ||||||
|   DAST_API_EXCLUDE_URLS: http://target/api/auth |   DAST_API_EXCLUDE_URLS: http://target/api/auth | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
|  | @ -1313,7 +1321,15 @@ variables: | ||||||
| To exclude the URLs `http://target/api/buy` and `http://target/api/sell` but allowing to scan their child resources, for instance: `http://target/api/buy/toy` or `http://target/api/sell/chair`. You could use the value `http://target/api/buy/$,http://target/api/sell/$`. This value is using two regular expressions, each of them separated by a `,` character. Hence, it contains `http://target/api/buy$` and `http://target/api/sell$`. In each regular expression, the trailing `$` character points out where the matching URL should end. | To exclude the URLs `http://target/api/buy` and `http://target/api/sell` but allowing to scan their child resources, for instance: `http://target/api/buy/toy` or `http://target/api/sell/chair`. You could use the value `http://target/api/buy/$,http://target/api/sell/$`. This value is using two regular expressions, each of them separated by a `,` character. Hence, it contains `http://target/api/buy$` and `http://target/api/sell$`. In each regular expression, the trailing `$` character points out where the matching URL should end. | ||||||
| 
 | 
 | ||||||
| ```yaml | ```yaml | ||||||
|  | stages: | ||||||
|  |   - dast | ||||||
|  | 
 | ||||||
|  | include: | ||||||
|  |   - template: DAST-API.gitlab-ci.yml | ||||||
|  | 
 | ||||||
| variables: | variables: | ||||||
|  |   DAST_API_TARGET_URL: http://target/ | ||||||
|  |   DAST_API_OPENAPI: test-api-specification.json | ||||||
|   DAST_API_EXCLUDE_URLS: http://target/api/buy/$,http://target/api/sell/$ |   DAST_API_EXCLUDE_URLS: http://target/api/buy/$,http://target/api/sell/$ | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
|  | @ -1322,7 +1338,15 @@ variables: | ||||||
| In order to exclude the URLs: `http://target/api/buy` and `http://target/api/sell`, and their child resources. To provide multiple URLs we use the `,` character as follows: | In order to exclude the URLs: `http://target/api/buy` and `http://target/api/sell`, and their child resources. To provide multiple URLs we use the `,` character as follows: | ||||||
| 
 | 
 | ||||||
| ```yaml | ```yaml | ||||||
|  | stages: | ||||||
|  |   - dast | ||||||
|  | 
 | ||||||
|  | include: | ||||||
|  |   - template: DAST-API.gitlab-ci.yml | ||||||
|  | 
 | ||||||
| variables: | variables: | ||||||
|  |   DAST_API_TARGET_URL: http://target/ | ||||||
|  |   DAST_API_OPENAPI: test-api-specification.json | ||||||
|   DAST_API_EXCLUDE_URLS: http://target/api/buy,http://target/api/sell |   DAST_API_EXCLUDE_URLS: http://target/api/buy,http://target/api/sell | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
|  | @ -1331,7 +1355,15 @@ variables: | ||||||
| In order to exclude exactly `https://target/api/v1/user/create` and `https://target/api/v2/user/create` or any other version (`v3`,`v4`, and more). We could use `https://target/api/v.*/user/create$`, in the previous regular expression `.` indicates any character and `*` indicates zero or more times, additionally `$` indicates that the URL should end there. | In order to exclude exactly `https://target/api/v1/user/create` and `https://target/api/v2/user/create` or any other version (`v3`,`v4`, and more). We could use `https://target/api/v.*/user/create$`, in the previous regular expression `.` indicates any character and `*` indicates zero or more times, additionally `$` indicates that the URL should end there. | ||||||
| 
 | 
 | ||||||
| ```yaml | ```yaml | ||||||
|  | stages: | ||||||
|  |   - dast | ||||||
|  | 
 | ||||||
|  | include: | ||||||
|  |   - template: DAST-API.gitlab-ci.yml | ||||||
|  | 
 | ||||||
| variables: | variables: | ||||||
|  |   DAST_API_TARGET_URL: http://target/ | ||||||
|  |   DAST_API_OPENAPI: test-api-specification.json | ||||||
|   DAST_API_EXCLUDE_URLS: https://target/api/v.*/user/create$ |   DAST_API_EXCLUDE_URLS: https://target/api/v.*/user/create$ | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
|  | @ -1575,12 +1607,15 @@ This solution is for pipelines in which the target API URL doesn't change (is st | ||||||
| For environments where the target API remains the same, we recommend you specify the target URL by using the `DAST_API_TARGET_URL` environment variable. In your `.gitlab-ci.yml`, add a variable `DAST_API_TARGET_URL`. The variable must be set to the base URL of API testing target. For example: | For environments where the target API remains the same, we recommend you specify the target URL by using the `DAST_API_TARGET_URL` environment variable. In your `.gitlab-ci.yml`, add a variable `DAST_API_TARGET_URL`. The variable must be set to the base URL of API testing target. For example: | ||||||
| 
 | 
 | ||||||
| ```yaml | ```yaml | ||||||
| include: | stages: | ||||||
|     - template: DAST-API.gitlab-ci.yml |   - dast | ||||||
| 
 | 
 | ||||||
|   variables: | include: | ||||||
|     DAST_API_TARGET_URL: http://test-deployment/ |   - template: DAST-API.gitlab-ci.yml | ||||||
|     DAST_API_OPENAPI: test-api-specification.json | 
 | ||||||
|  | variables: | ||||||
|  |   DAST_API_TARGET_URL: http://test-deployment/ | ||||||
|  |   DAST_API_OPENAPI: test-api-specification.json | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| #### Dynamic environment solutions | #### Dynamic environment solutions | ||||||
|  | @ -1630,17 +1665,17 @@ Relaxed validation is meant for cases when the OpenAPI document cannot meet Open | ||||||
| API Security can still try to consume an OpenAPI document that does not fully comply with OpenAPI specifications. To instruct API Security to perform a relaxed validation, set the variable `DAST_API_OPENAPI_RELAXED_VALIDATION` to any value, for example: | API Security can still try to consume an OpenAPI document that does not fully comply with OpenAPI specifications. To instruct API Security to perform a relaxed validation, set the variable `DAST_API_OPENAPI_RELAXED_VALIDATION` to any value, for example: | ||||||
| 
 | 
 | ||||||
| ```yaml | ```yaml | ||||||
|    stages: | stages: | ||||||
|      - dast |   - dast | ||||||
| 
 | 
 | ||||||
|    include: | include: | ||||||
|      - template: DAST-API.gitlab-ci.yml |   - template: DAST-API.gitlab-ci.yml | ||||||
| 
 | 
 | ||||||
|    variables: | variables: | ||||||
|      DAST_API_PROFILE: Quick |   DAST_API_PROFILE: Quick | ||||||
|      DAST_API_TARGET_URL: http://test-deployment/ |   DAST_API_TARGET_URL: http://test-deployment/ | ||||||
|      DAST_API_OPENAPI: test-api-specification.json |   DAST_API_OPENAPI: test-api-specification.json | ||||||
|      DAST_API_OPENAPI_RELAXED_VALIDATION: On |   DAST_API_OPENAPI_RELAXED_VALIDATION: 'On' | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| ### `No operation in the OpenAPI document is consuming any supported media type` | ### `No operation in the OpenAPI document is consuming any supported media type` | ||||||
|  |  | ||||||
|  | @ -890,3 +890,17 @@ root@6abb70e9f193:~# | ||||||
| 
 | 
 | ||||||
| NOTE: | NOTE: | ||||||
| Selecting a custom version of [Mono](https://www.mono-project.com/) or [.NET Core](https://dotnet.microsoft.com/download/dotnet) is currently not supported. | Selecting a custom version of [Mono](https://www.mono-project.com/) or [.NET Core](https://dotnet.microsoft.com/download/dotnet) is currently not supported. | ||||||
|  | 
 | ||||||
|  | ### LicenseFinder::Maven: is not installed error | ||||||
|  | 
 | ||||||
|  | If your project contains a `mvnw` or `mvnw.cmd` file, then the license scanning job may fail with the `LicenseFinder::Maven: is not installed error` error. To resolve this, modify the license scanning job to remove the files in the `before_script` section. Example: | ||||||
|  | 
 | ||||||
|  | ```yaml | ||||||
|  | include: | ||||||
|  |   - template: License-Scanning.gitlab-ci.yml | ||||||
|  | 
 | ||||||
|  | license_scanning: | ||||||
|  |   before_script: | ||||||
|  |     - rm mvnw | ||||||
|  |     - rm mvnw.cmd | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | @ -42,11 +42,14 @@ module Gitlab | ||||||
|       def build |       def build | ||||||
|         menu = @menu_builder.build |         menu = @menu_builder.build | ||||||
| 
 | 
 | ||||||
|  |         hide_menu_text = Feature.enabled?(:new_navbar_layout) | ||||||
|  | 
 | ||||||
|         menu.merge({ |         menu.merge({ | ||||||
|           views: @views, |           views: @views, | ||||||
|           shortcuts: @shortcuts, |           shortcuts: @shortcuts, | ||||||
|           activeTitle: _('Menu') |           menuTitle: (_('Menu') unless hide_menu_text), | ||||||
|         }) |           menuTooltip: (_('Main menu') if hide_menu_text) | ||||||
|  |         }.compact) | ||||||
|       end |       end | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
|  |  | ||||||
|  | @ -24046,6 +24046,9 @@ msgstr "" | ||||||
| msgid "Mailgun events" | msgid "Mailgun events" | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
|  | msgid "Main menu" | ||||||
|  | msgstr "" | ||||||
|  | 
 | ||||||
| msgid "Maintenance mode" | msgid "Maintenance mode" | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -53,12 +53,11 @@ module QA | ||||||
|           project.api_client = api_client |           project.api_client = api_client | ||||||
|         end |         end | ||||||
| 
 | 
 | ||||||
|         Resource::Repository::ProjectPush.fabricate! do |push| |         Resource::Repository::Commit.fabricate_via_api! do |commit| | ||||||
|           push.project = project |           commit.project = project | ||||||
|           push.file_name = 'README.md' |           commit.add_files([{ file_path: 'README.md', content: '# This is a test project' }]) | ||||||
|           push.file_content = '# This is a test project' |           commit.commit_message = 'Add README.md' | ||||||
|           push.commit_message = 'Add README.md' |           commit.api_client = api_client | ||||||
|           push.user = user |  | ||||||
|         end |         end | ||||||
| 
 | 
 | ||||||
|         project |         project | ||||||
|  |  | ||||||
|  | @ -8,6 +8,7 @@ RSpec.describe 'Thread Comments Issue', :js do | ||||||
|   let(:issue) { create(:issue, project: project) } |   let(:issue) { create(:issue, project: project) } | ||||||
| 
 | 
 | ||||||
|   before do |   before do | ||||||
|  |     stub_feature_flags(remove_user_attributes: false) | ||||||
|     project.add_maintainer(user) |     project.add_maintainer(user) | ||||||
|     sign_in(user) |     sign_in(user) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -8,6 +8,7 @@ RSpec.describe 'Thread Comments Merge Request', :js do | ||||||
|   let(:merge_request) { create(:merge_request, source_project: project) } |   let(:merge_request) { create(:merge_request, source_project: project) } | ||||||
| 
 | 
 | ||||||
|   before do |   before do | ||||||
|  |     stub_feature_flags(remove_user_attributes: false) | ||||||
|     project.add_maintainer(user) |     project.add_maintainer(user) | ||||||
|     sign_in(user) |     sign_in(user) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -15,6 +15,8 @@ RSpec.describe "Jira", :js do | ||||||
|     before do |     before do | ||||||
|       remotelink = double(:remotelink, all: [], build: double(save!: true)) |       remotelink = double(:remotelink, all: [], build: double(save!: true)) | ||||||
| 
 | 
 | ||||||
|  |       stub_feature_flags(remove_user_attributes: false) | ||||||
|  | 
 | ||||||
|       stub_request(:get, "https://jira.example.com/rest/api/2/issue/JIRA-5") |       stub_request(:get, "https://jira.example.com/rest/api/2/issue/JIRA-5") | ||||||
|       stub_request(:post, "https://jira.example.com/rest/api/2/issue/JIRA-5/comment") |       stub_request(:post, "https://jira.example.com/rest/api/2/issue/JIRA-5/comment") | ||||||
|       allow_next_instance_of(JIRA::Resource::Issue) do |instance| |       allow_next_instance_of(JIRA::Resource::Issue) do |instance| | ||||||
|  |  | ||||||
|  | @ -14,6 +14,7 @@ RSpec.describe 'List issue resource label events', :js do | ||||||
|     let!(:event)    { create(:resource_label_event, user: user, issue: issue, label: label) } |     let!(:event)    { create(:resource_label_event, user: user, issue: issue, label: label) } | ||||||
| 
 | 
 | ||||||
|     before do |     before do | ||||||
|  |       stub_feature_flags(remove_user_attributes: false) | ||||||
|       visit project_issue_path(project, issue) |       visit project_issue_path(project, issue) | ||||||
|       wait_for_requests |       wait_for_requests | ||||||
|     end |     end | ||||||
|  |  | ||||||
|  | @ -14,6 +14,7 @@ RSpec.describe 'User comments on a diff', :js do | ||||||
|   let(:user) { create(:user) } |   let(:user) { create(:user) } | ||||||
| 
 | 
 | ||||||
|   before do |   before do | ||||||
|  |     stub_feature_flags(remove_user_attributes: false) | ||||||
|     project.add_maintainer(user) |     project.add_maintainer(user) | ||||||
|     sign_in(user) |     sign_in(user) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -10,6 +10,7 @@ RSpec.describe 'User comments on a merge request', :js do | ||||||
|   let(:user) { create(:user) } |   let(:user) { create(:user) } | ||||||
| 
 | 
 | ||||||
|   before do |   before do | ||||||
|  |     stub_feature_flags(remove_user_attributes: false) | ||||||
|     project.add_maintainer(user) |     project.add_maintainer(user) | ||||||
|     sign_in(user) |     sign_in(user) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -8,6 +8,10 @@ RSpec.describe 'Project > Merge request > View user status' do | ||||||
|     create(:merge_request, source_project: project, target_project: project, author: create(:user)) |     create(:merge_request, source_project: project, target_project: project, author: create(:user)) | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|  |   before do | ||||||
|  |     stub_feature_flags(remove_user_attributes: false) | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|   subject { visit merge_request_path(merge_request) } |   subject { visit merge_request_path(merge_request) } | ||||||
| 
 | 
 | ||||||
|   context 'for notes', :js do |   context 'for notes', :js do | ||||||
|  |  | ||||||
|  | @ -8,6 +8,7 @@ RSpec.describe 'User edit profile' do | ||||||
|   let(:user) { create(:user) } |   let(:user) { create(:user) } | ||||||
| 
 | 
 | ||||||
|   before do |   before do | ||||||
|  |     stub_feature_flags(remove_user_attributes: false) | ||||||
|     sign_in(user) |     sign_in(user) | ||||||
|     visit(profile_path) |     visit(profile_path) | ||||||
|   end |   end | ||||||
|  |  | ||||||
|  | @ -30,9 +30,10 @@ describe('~/nav/components/top_nav_app.vue', () => { | ||||||
|     it('renders nav item dropdown', () => { |     it('renders nav item dropdown', () => { | ||||||
|       expect(findNavItemDropdown().attributes('href')).toBeUndefined(); |       expect(findNavItemDropdown().attributes('href')).toBeUndefined(); | ||||||
|       expect(findNavItemDropdown().attributes()).toMatchObject({ |       expect(findNavItemDropdown().attributes()).toMatchObject({ | ||||||
|         icon: 'hamburger', |         icon: '', | ||||||
|         text: TEST_NAV_DATA.activeTitle, |         text: '', | ||||||
|         'no-flip': '', |         'no-flip': '', | ||||||
|  |         'no-caret': '', | ||||||
|       }); |       }); | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| import { range } from 'lodash'; | import { range } from 'lodash'; | ||||||
| 
 | 
 | ||||||
| export const TEST_NAV_DATA = { | export const TEST_NAV_DATA = { | ||||||
|   activeTitle: 'Test Active Title', |   menuTitle: 'Test Menu Title', | ||||||
|   primary: [ |   primary: [ | ||||||
|     ...['projects', 'groups'].map((view) => ({ |     ...['projects', 'groups'].map((view) => ({ | ||||||
|       id: view, |       id: view, | ||||||
|  |  | ||||||
|  | @ -40,13 +40,18 @@ describe('NoteHeader component', () => { | ||||||
|     availability: '', |     availability: '', | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   const createComponent = (props) => { |   const createComponent = (props, userAttributes = false) => { | ||||||
|     wrapper = shallowMountExtended(NoteHeader, { |     wrapper = shallowMountExtended(NoteHeader, { | ||||||
|       store: new Vuex.Store({ |       store: new Vuex.Store({ | ||||||
|         actions, |         actions, | ||||||
|       }), |       }), | ||||||
|       propsData: { ...props }, |       propsData: { ...props }, | ||||||
|       stubs: { GlSprintf, UserNameWithStatus }, |       stubs: { GlSprintf, UserNameWithStatus }, | ||||||
|  |       provide: { | ||||||
|  |         glFeatures: { | ||||||
|  |           removeUserAttributes: userAttributes, | ||||||
|  |         }, | ||||||
|  |       }, | ||||||
|     }); |     }); | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|  | @ -55,6 +60,26 @@ describe('NoteHeader component', () => { | ||||||
|     wrapper = null; |     wrapper = null; | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
|  |   describe('when removeUserAttributes feature flag is enabled', () => { | ||||||
|  |     it('does not render busy status', () => { | ||||||
|  |       createComponent({ author: { ...author, availability: AVAILABILITY_STATUS.BUSY } }, true); | ||||||
|  | 
 | ||||||
|  |       expect(wrapper.find('.note-header-info').text()).not.toContain('(Busy)'); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     it('does not render author status', () => { | ||||||
|  |       createComponent({ author }, true); | ||||||
|  | 
 | ||||||
|  |       expect(findAuthorStatus().exists()).toBe(false); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     it('does not render username', () => { | ||||||
|  |       createComponent({ author }, true); | ||||||
|  | 
 | ||||||
|  |       expect(wrapper.find('.note-header-info').text()).not.toContain('@'); | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|   it('does not render discussion actions when includeToggle is false', () => { |   it('does not render discussion actions when includeToggle is false', () => { | ||||||
|     createComponent({ |     createComponent({ | ||||||
|       includeToggle: false, |       includeToggle: false, | ||||||
|  |  | ||||||
|  | @ -27,9 +27,11 @@ RSpec.describe Nav::TopNavHelper do | ||||||
| 
 | 
 | ||||||
|     let(:subject) { helper.top_nav_view_model(project: current_project, group: current_group) } |     let(:subject) { helper.top_nav_view_model(project: current_project, group: current_group) } | ||||||
| 
 | 
 | ||||||
|     let(:active_title) { 'Menu' } |     let(:menu_title) { 'Menu' } | ||||||
| 
 | 
 | ||||||
|     before do |     before do | ||||||
|  |       stub_feature_flags(new_navbar_layout: false) | ||||||
|  | 
 | ||||||
|       allow(Gitlab::CurrentSettings).to receive(:admin_mode) { with_current_settings_admin_mode } |       allow(Gitlab::CurrentSettings).to receive(:admin_mode) { with_current_settings_admin_mode } | ||||||
|       allow(helper).to receive(:header_link?).with(:admin_mode) { with_header_link_admin_mode } |       allow(helper).to receive(:header_link?).with(:admin_mode) { with_header_link_admin_mode } | ||||||
| 
 | 
 | ||||||
|  | @ -44,8 +46,8 @@ RSpec.describe Nav::TopNavHelper do | ||||||
|       allow(helper).to receive(:dashboard_nav_link?).with(:activity) { with_activity } |       allow(helper).to receive(:dashboard_nav_link?).with(:activity) { with_activity } | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     it 'has :activeTitle' do |     it 'has :menuTitle' do | ||||||
|       expect(subject[:activeTitle]).to eq(active_title) |       expect(subject[:menuTitle]).to eq(menu_title) | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     context 'when current_user is nil (anonymous)' do |     context 'when current_user is nil (anonymous)' do | ||||||
|  | @ -103,7 +105,7 @@ RSpec.describe Nav::TopNavHelper do | ||||||
|       let(:current_user) { user } |       let(:current_user) { user } | ||||||
| 
 | 
 | ||||||
|       it 'has no menu items or views by default' do |       it 'has no menu items or views by default' do | ||||||
|         expect(subject).to eq({ activeTitle: active_title, |         expect(subject).to eq({ menuTitle: menu_title, | ||||||
|                                 primary: [], |                                 primary: [], | ||||||
|                                 secondary: [], |                                 secondary: [], | ||||||
|                                 shortcuts: [], |                                 shortcuts: [], | ||||||
|  |  | ||||||
|  | @ -1,6 +1,10 @@ | ||||||
| # frozen_string_literal: true | # frozen_string_literal: true | ||||||
| 
 | 
 | ||||||
| RSpec.shared_examples 'comment on merge request file' do | RSpec.shared_examples 'comment on merge request file' do | ||||||
|  |   before do | ||||||
|  |     stub_feature_flags(remove_user_attributes: false) | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|   it 'adds a comment' do |   it 'adds a comment' do | ||||||
|     click_diff_line(find_by_scrolling("[id='#{sample_commit.line_code}']")) |     click_diff_line(find_by_scrolling("[id='#{sample_commit.line_code}']")) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -10,6 +10,10 @@ RSpec.shared_examples 'thread comments for commit and snippet' do |resource_name | ||||||
|   let(:comments_selector) { '.timeline > .note.timeline-entry:not(.being-posted)' } |   let(:comments_selector) { '.timeline > .note.timeline-entry:not(.being-posted)' } | ||||||
|   let(:comment) { 'My comment' } |   let(:comment) { 'My comment' } | ||||||
| 
 | 
 | ||||||
|  |   before do | ||||||
|  |     stub_feature_flags(remove_user_attributes: false) | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|   it 'clicking "Comment" will post a comment' do |   it 'clicking "Comment" will post a comment' do | ||||||
|     wait_for_all_requests |     wait_for_all_requests | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue