diff --git a/Gemfile b/Gemfile index 37de8156871..e73172d34a5 100644 --- a/Gemfile +++ b/Gemfile @@ -386,7 +386,7 @@ end group :development, :test do gem 'deprecation_toolkit', '~> 1.5.1', require: false gem 'bullet', '~> 7.0.2' - gem 'parser', '~> 3.2' + gem 'parser', '~> 3.2', '>= 3.2.2.3' gem 'pry-byebug' gem 'pry-rails', '~> 0.3.9' gem 'pry-shell', '~> 0.6.1' diff --git a/Gemfile.checksum b/Gemfile.checksum index feda758a12a..216acff381b 100644 --- a/Gemfile.checksum +++ b/Gemfile.checksum @@ -438,7 +438,7 @@ {"name":"pact-mock_service","version":"3.10.0","platform":"ruby","checksum":"898ec3b8d96f1934d15941c701ca7d5fef5ccff32022d9a196fb82073cd95e27"}, {"name":"pact-support","version":"1.18.1","platform":"ruby","checksum":"4a25961c8b1c4132e433a8eaa838b1e6914c6d3aae48eee705b9860a5e8b0476"}, {"name":"parallel","version":"1.22.1","platform":"ruby","checksum":"ebdf1f0c51f182df38522f70ba770214940bef998cdb6e00f36492b29699761f"}, -{"name":"parser","version":"3.2.2.1","platform":"ruby","checksum":"1d6542b6d3c5e15bedb500fa68eb937aa0eaae644eb0eda43e9a1fa9b54dc821"}, +{"name":"parser","version":"3.2.2.3","platform":"ruby","checksum":"10685f358ab36ffea2252dc4952e5b8fad3a297a8152a85f59adc982747b91eb"}, {"name":"parslet","version":"1.8.2","platform":"ruby","checksum":"08d1ab3721cd3f175bfbee8788b2ddff71f92038f2d69bd65454c22bb9fbd98a"}, {"name":"pastel","version":"0.8.0","platform":"ruby","checksum":"481da9fb7d2f6e6b1a08faf11fa10363172dc40fd47848f096ae21209f805a75"}, {"name":"peek","version":"1.1.0","platform":"ruby","checksum":"d6501ead8cde46d8d8ed0d59eb6f0ba713d0a41c11a2c4a81447b2dce37b3ecc"}, @@ -453,11 +453,11 @@ {"name":"premailer","version":"1.16.0","platform":"ruby","checksum":"03e4402c448e6bae13fb5f6301a8bde4f3508e1bff90ae7c0972c7be94694786"}, {"name":"premailer-rails","version":"1.10.3","platform":"ruby","checksum":"7cdcb97027866f7a81c490c6d15ada7f39666b5f6375f0821b7e97e0483b112f"}, {"name":"proc_to_ast","version":"0.1.0","platform":"ruby","checksum":"92a73fa66e2250a83f8589f818b0751bcf227c68f85916202df7af85082f8691"}, -{"name":"prometheus-client-mmap","version":"0.24.4","platform":"aarch64-linux","checksum":"c23da204864167d6f43e8a1e925702ddfeb802cfaaa7b240ec4ee7996c97de92"}, -{"name":"prometheus-client-mmap","version":"0.24.4","platform":"arm64-darwin","checksum":"d18e9a2f4ff960c8ab833ba8f4c2581f106346b81452b3bd02ba8d5637c11d71"}, -{"name":"prometheus-client-mmap","version":"0.24.4","platform":"ruby","checksum":"8a0da7f4e5ff3e27e0df0223ce5e5945b60cf78fcf015f772b89f69b72b7b0a0"}, -{"name":"prometheus-client-mmap","version":"0.24.4","platform":"x86_64-darwin","checksum":"065f890b08b07d60080df7803f9a78c6362a3e0fc78f0de38be77856ff721d19"}, -{"name":"prometheus-client-mmap","version":"0.24.4","platform":"x86_64-linux","checksum":"645b59fa89a2f8433beea4a5316516aa117406674454040efad8c608b1d09944"}, +{"name":"prometheus-client-mmap","version":"0.24.5","platform":"aarch64-linux","checksum":"20977bd3dff89e2e4b5d7eb3420a1ea8a002a601390a08a1c0e5065a05c4a36c"}, +{"name":"prometheus-client-mmap","version":"0.24.5","platform":"arm64-darwin","checksum":"15d7e86d4595d24f2c5aa41a0b6d8564d78a1219bd01cba09ef721f304f64ebc"}, +{"name":"prometheus-client-mmap","version":"0.24.5","platform":"ruby","checksum":"a288fb5bd7551fb0008d77eb923e64ad4f583d56fec90de68efd75369d152676"}, +{"name":"prometheus-client-mmap","version":"0.24.5","platform":"x86_64-darwin","checksum":"7e3d1a79c3a1083e5f427399c5afc5316c207fd785c4b8a13134f7af50f0fd84"}, +{"name":"prometheus-client-mmap","version":"0.24.5","platform":"x86_64-linux","checksum":"09d9a3e5598886ff6ad34562745b79823a0bbf6ea59c22535d819ec32275f207"}, {"name":"pry","version":"0.14.2","platform":"java","checksum":"fd780670977ba04ff7ee32dabd4d02fe4bf02e977afe8809832d5dca1412862e"}, {"name":"pry","version":"0.14.2","platform":"ruby","checksum":"c4fe54efedaca1d351280b45b8849af363184696fcac1c72e0415f9bdac4334d"}, {"name":"pry-byebug","version":"3.10.1","platform":"ruby","checksum":"c8f975c32255bfdb29e151f5532130be64ff3d0042dc858d0907e849125581f8"}, diff --git a/Gemfile.lock b/Gemfile.lock index ce4b76f08bc..dfddd61fdc1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1128,8 +1128,9 @@ GEM expgen (~> 0.1) rainbow (~> 3.1.1) parallel (1.22.1) - parser (3.2.2.1) + parser (3.2.2.3) ast (~> 2.4.1) + racc parslet (1.8.2) pastel (0.8.0) tty-color (~> 0.5) @@ -1153,7 +1154,7 @@ GEM coderay parser unparser - prometheus-client-mmap (0.24.4) + prometheus-client-mmap (0.24.5) rb_sys (~> 0.9) pry (0.14.2) coderay (~> 1.1) @@ -1866,7 +1867,7 @@ DEPENDENCIES org-ruby (~> 0.9.12) pact (~> 1.63) parallel (~> 1.19) - parser (~> 3.2) + parser (~> 3.2, >= 3.2.2.3) parslet (~> 1.8) peek (~> 1.1) pg (~> 1.5.3) diff --git a/app/assets/javascripts/editor/schema/ci.json b/app/assets/javascripts/editor/schema/ci.json index 82a8cfaa3eb..8e307bc1f19 100644 --- a/app/assets/javascripts/editor/schema/ci.json +++ b/app/assets/javascripts/editor/schema/ci.json @@ -359,7 +359,7 @@ "pattern": "\\.ya?ml$" }, "rules": { - "$ref": "#/definitions/rules" + "$ref": "#/definitions/includeRules" }, "inputs": { "$ref": "#/definitions/inputs" @@ -399,6 +399,9 @@ } ] }, + "rules": { + "$ref": "#/definitions/includeRules" + }, "inputs": { "$ref": "#/definitions/inputs" } @@ -418,6 +421,9 @@ "format": "uri-reference", "pattern": "\\.ya?ml$" }, + "rules": { + "$ref": "#/definitions/includeRules" + }, "inputs": { "$ref": "#/definitions/inputs" } @@ -435,6 +441,9 @@ "type": "string", "format": "uri-reference" }, + "rules": { + "$ref": "#/definitions/includeRules" + }, "inputs": { "$ref": "#/definitions/inputs" } @@ -453,6 +462,9 @@ "format": "uri-reference", "pattern": "^https?://.+\\.ya?ml$" }, + "rules": { + "$ref": "#/definitions/includeRules" + }, "inputs": { "$ref": "#/definitions/inputs" } @@ -794,6 +806,54 @@ ] } }, + "includeRules": { + "type": [ + "array", + "null" + ], + "markdownDescription": "You can use rules to conditionally include other configuration files. [Learn More](https://docs.gitlab.com/ee/ci/yaml/includes.html#use-rules-with-include).", + "items": { + "anyOf": [ + { + "type": "object", + "additionalProperties": false, + "properties": { + "if": { + "$ref": "#/definitions/if" + }, + "exists": { + "$ref": "#/definitions/exists" + }, + "when": { + "markdownDescription": "Use `when: never` to exclude the configuration file if the condition matches. [Learn More](https://docs.gitlab.com/ee/ci/yaml/includes.html#include-with-rulesif).", + "oneOf": [ + { + "type": "string", + "enum": [ + "never" + ] + }, + { + "type": "null" + } + ] + } + } + }, + { + "type": "string", + "minLength": 1 + }, + { + "type": "array", + "minLength": 1, + "items": { + "type": "string" + } + } + ] + } + }, "workflowName": { "type": "string", "markdownDescription": "Defines the pipeline name. [Learn More](https://docs.gitlab.com/ee/ci/yaml/#workflowname).", diff --git a/app/models/organizations/organization.rb b/app/models/organizations/organization.rb index adaa022bef4..ce89f57a73b 100644 --- a/app/models/organizations/organization.rb +++ b/app/models/organizations/organization.rb @@ -17,6 +17,10 @@ module Organizations 'organizations/path': true, length: { minimum: 2, maximum: 255 } + def self.default_organization + find_by(id: DEFAULT_ORGANIZATION_ID) + end + def default? id == DEFAULT_ORGANIZATION_ID end diff --git a/config/feature_flags/development/ci_support_include_rules_when_never.yml b/config/feature_flags/development/ci_support_include_rules_when_never.yml new file mode 100644 index 00000000000..594da30ec97 --- /dev/null +++ b/config/feature_flags/development/ci_support_include_rules_when_never.yml @@ -0,0 +1,8 @@ +--- +name: ci_support_include_rules_when_never +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/122810 +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/414517 +milestone: '16.1' +type: development +group: group::pipeline authoring +default_enabled: false diff --git a/db/fixtures/development/002_default_organization.rb b/db/fixtures/development/002_default_organization.rb new file mode 100644 index 00000000000..774e3742c8b --- /dev/null +++ b/db/fixtures/development/002_default_organization.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +Gitlab::Seeder.quiet do + Gitlab::DatabaseImporters::DefaultOrganizationImporter.create_default_organization +end diff --git a/db/fixtures/production/030_default_organization.rb b/db/fixtures/production/030_default_organization.rb new file mode 100644 index 00000000000..774e3742c8b --- /dev/null +++ b/db/fixtures/production/030_default_organization.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +Gitlab::Seeder.quiet do + Gitlab::DatabaseImporters::DefaultOrganizationImporter.create_default_organization +end diff --git a/db/migrate/20230605095810_ensure_default_organization.rb b/db/migrate/20230605095810_ensure_default_organization.rb new file mode 100644 index 00000000000..526e12077df --- /dev/null +++ b/db/migrate/20230605095810_ensure_default_organization.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +class EnsureDefaultOrganization < Gitlab::Database::Migration[2.1] + restrict_gitlab_migration gitlab_schema: :gitlab_main + + disable_ddl_transaction! + + class Organization < MigrationRecord + end + + def up + return if Organization.exists?(id: 1) + + path = 'default' + + retries = 0 + + begin + Organization.create(id: 1, name: 'Default', path: path) + rescue ActiveRecord::RecordNotUnique + retries += 1 + path = "default-#{SecureRandom.hex(3)}" + retry if retries < 10_000 + end + end + + def down + Organization.where(id: 1).delete_all + end +end diff --git a/db/post_migrate/20230524135750_replace_ci_job_artifacts_foreign_key.rb b/db/post_migrate/20230524135750_replace_ci_job_artifacts_foreign_key.rb index 8bd4dadc891..48c07bceb6a 100644 --- a/db/post_migrate/20230524135750_replace_ci_job_artifacts_foreign_key.rb +++ b/db/post_migrate/20230524135750_replace_ci_job_artifacts_foreign_key.rb @@ -1,24 +1,13 @@ # frozen_string_literal: true class ReplaceCiJobArtifactsForeignKey < Gitlab::Database::Migration[2.1] - disable_ddl_transaction! - def up - add_concurrent_foreign_key :ci_job_artifacts, :p_ci_builds, - name: 'temp_fk_rails_c5137cb2c1_p', - column: [:partition_id, :job_id], - target_column: [:partition_id, :id], - on_update: :cascade, - on_delete: :cascade, - validate: false, - reverse_lock_order: true - - prepare_async_foreign_key_validation :ci_job_artifacts, - name: 'temp_fk_rails_c5137cb2c1_p' + # This migration was skipped in the ci database on gitlab.com as part of + # https://gitlab.com/gitlab-com/gl-infra/production/-/issues/14888 end def down - unprepare_async_foreign_key_validation :ci_job_artifacts, name: 'temp_fk_rails_c5137cb2c1_p' - remove_foreign_key :ci_job_artifacts, name: 'temp_fk_rails_c5137cb2c1_p' + # This migration was skipped in the ci database on gitlab.com as part of + # https://gitlab.com/gitlab-com/gl-infra/production/-/issues/14888 end end diff --git a/db/post_migrate/20230524135803_replace_ci_running_builds_foreign_key.rb b/db/post_migrate/20230524135803_replace_ci_running_builds_foreign_key.rb index 0e2d2bd34d0..5d3807242ef 100644 --- a/db/post_migrate/20230524135803_replace_ci_running_builds_foreign_key.rb +++ b/db/post_migrate/20230524135803_replace_ci_running_builds_foreign_key.rb @@ -1,24 +1,13 @@ # frozen_string_literal: true class ReplaceCiRunningBuildsForeignKey < Gitlab::Database::Migration[2.1] - disable_ddl_transaction! - def up - add_concurrent_foreign_key :ci_running_builds, :p_ci_builds, - name: 'temp_fk_rails_da45cfa165_p', - column: [:partition_id, :build_id], - target_column: [:partition_id, :id], - on_update: :cascade, - on_delete: :cascade, - validate: false, - reverse_lock_order: true - - prepare_async_foreign_key_validation :ci_running_builds, - name: 'temp_fk_rails_da45cfa165_p' + # This migration was skipped in the ci database on gitlab.com as part of + # https://gitlab.com/gitlab-com/gl-infra/production/-/issues/14888 end def down - unprepare_async_foreign_key_validation :ci_running_builds, name: 'temp_fk_rails_da45cfa165_p' - remove_foreign_key :ci_running_builds, name: 'temp_fk_rails_da45cfa165_p' + # This migration was skipped in the ci database on gitlab.com as part of + # https://gitlab.com/gitlab-com/gl-infra/production/-/issues/14888 end end diff --git a/db/post_migrate/20230524135815_replace_ci_job_variables_foreign_key.rb b/db/post_migrate/20230524135815_replace_ci_job_variables_foreign_key.rb index c846c7f437c..baac0d495a7 100644 --- a/db/post_migrate/20230524135815_replace_ci_job_variables_foreign_key.rb +++ b/db/post_migrate/20230524135815_replace_ci_job_variables_foreign_key.rb @@ -1,24 +1,13 @@ # frozen_string_literal: true class ReplaceCiJobVariablesForeignKey < Gitlab::Database::Migration[2.1] - disable_ddl_transaction! - def up - add_concurrent_foreign_key :ci_job_variables, :p_ci_builds, - name: 'temp_fk_rails_fbf3b34792_p', - column: [:partition_id, :job_id], - target_column: [:partition_id, :id], - on_update: :cascade, - on_delete: :cascade, - validate: false, - reverse_lock_order: true - - prepare_async_foreign_key_validation :ci_job_variables, - name: 'temp_fk_rails_fbf3b34792_p' + # This migration was skipped in the ci database on gitlab.com as part of + # https://gitlab.com/gitlab-com/gl-infra/production/-/issues/14888 end def down - unprepare_async_foreign_key_validation :ci_job_variables, name: 'temp_fk_rails_fbf3b34792_p' - remove_foreign_key :ci_job_variables, name: 'temp_fk_rails_fbf3b34792_p' + # This migration was skipped in the ci database on gitlab.com as part of + # https://gitlab.com/gitlab-com/gl-infra/production/-/issues/14888 end end diff --git a/db/post_migrate/20230524135828_replace_p_ci_builds_metadata_foreign_key.rb b/db/post_migrate/20230524135828_replace_p_ci_builds_metadata_foreign_key.rb index 6ad2a932a3a..c398b457978 100644 --- a/db/post_migrate/20230524135828_replace_p_ci_builds_metadata_foreign_key.rb +++ b/db/post_migrate/20230524135828_replace_p_ci_builds_metadata_foreign_key.rb @@ -1,29 +1,13 @@ # frozen_string_literal: true class ReplacePCiBuildsMetadataForeignKey < Gitlab::Database::Migration[2.1] - include Gitlab::Database::PartitioningMigrationHelpers - - disable_ddl_transaction! - def up - add_concurrent_partitioned_foreign_key :p_ci_builds_metadata, :p_ci_builds, - name: 'temp_fk_e20479742e_p', - column: [:partition_id, :build_id], - target_column: [:partition_id, :id], - on_update: :cascade, - on_delete: :cascade, - validate: false, - reverse_lock_order: true - - prepare_partitioned_async_foreign_key_validation :p_ci_builds_metadata, - name: 'temp_fk_e20479742e_p' + # This migration was skipped in the ci database on gitlab.com as part of + # https://gitlab.com/gitlab-com/gl-infra/production/-/issues/14888 end def down - unprepare_partitioned_async_foreign_key_validation :p_ci_builds_metadata, name: 'temp_fk_e20479742e_p' - - Gitlab::Database::PostgresPartitionedTable.each_partition(:p_ci_builds_metadata) do |partition| - execute "ALTER TABLE #{partition.identifier} DROP CONSTRAINT IF EXISTS temp_fk_e20479742e_p" - end + # This migration was skipped in the ci database on gitlab.com as part of + # https://gitlab.com/gitlab-com/gl-infra/production/-/issues/14888 end end diff --git a/db/post_migrate/20230524135840_replace_p_ci_runner_machine_builds_foreign_key.rb b/db/post_migrate/20230524135840_replace_p_ci_runner_machine_builds_foreign_key.rb index 7ac4b79d0db..bc9d534ec1f 100644 --- a/db/post_migrate/20230524135840_replace_p_ci_runner_machine_builds_foreign_key.rb +++ b/db/post_migrate/20230524135840_replace_p_ci_runner_machine_builds_foreign_key.rb @@ -1,29 +1,13 @@ # frozen_string_literal: true class ReplacePCiRunnerMachineBuildsForeignKey < Gitlab::Database::Migration[2.1] - include Gitlab::Database::PartitioningMigrationHelpers - - disable_ddl_transaction! - def up - add_concurrent_partitioned_foreign_key :p_ci_runner_machine_builds, :p_ci_builds, - name: 'temp_fk_bb490f12fe_p', - column: [:partition_id, :build_id], - target_column: [:partition_id, :id], - on_update: :cascade, - on_delete: :cascade, - validate: false, - reverse_lock_order: true - - prepare_partitioned_async_foreign_key_validation :p_ci_runner_machine_builds, - name: 'temp_fk_bb490f12fe_p' + # This migration was skipped in the ci database on gitlab.com as part of + # https://gitlab.com/gitlab-com/gl-infra/production/-/issues/14888 end def down - unprepare_partitioned_async_foreign_key_validation :p_ci_runner_machine_builds, name: 'temp_fk_bb490f12fe_p' - - Gitlab::Database::PostgresPartitionedTable.each_partition(:p_ci_runner_machine_builds) do |partition| - execute "ALTER TABLE #{partition.identifier} DROP CONSTRAINT IF EXISTS temp_fk_bb490f12fe_p" - end + # This migration was skipped in the ci database on gitlab.com as part of + # https://gitlab.com/gitlab-com/gl-infra/production/-/issues/14888 end end diff --git a/db/schema_migrations/20230605095810 b/db/schema_migrations/20230605095810 new file mode 100644 index 00000000000..7d8d7bb7fd5 --- /dev/null +++ b/db/schema_migrations/20230605095810 @@ -0,0 +1 @@ +8703eac92c20c68dc7ff20a94b788e1c5115c2e5b6b665ada428cfa24a5958db \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index a4bbe2033d0..49f27281036 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -37975,9 +37975,6 @@ ALTER TABLE ONLY ci_sources_pipelines ALTER TABLE ONLY ci_resources ADD CONSTRAINT temp_fk_e169a8e3d5_p FOREIGN KEY (partition_id, build_id) REFERENCES p_ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE SET NULL; -ALTER TABLE ONLY ci_builds_metadata - ADD CONSTRAINT temp_fk_e20479742e_p FOREIGN KEY (partition_id, build_id) REFERENCES p_ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE NOT VALID; - ALTER TABLE ONLY ci_build_report_results ADD CONSTRAINT temp_fk_rails_16cb1ff064_p FOREIGN KEY (partition_id, build_id) REFERENCES p_ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE; @@ -37993,15 +37990,6 @@ ALTER TABLE ONLY ci_pending_builds ALTER TABLE ONLY ci_build_trace_metadata ADD CONSTRAINT temp_fk_rails_aebc78111f_p FOREIGN KEY (partition_id, build_id) REFERENCES p_ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE; -ALTER TABLE ONLY ci_job_artifacts - ADD CONSTRAINT temp_fk_rails_c5137cb2c1_p FOREIGN KEY (partition_id, job_id) REFERENCES p_ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE NOT VALID; - -ALTER TABLE ONLY ci_running_builds - ADD CONSTRAINT temp_fk_rails_da45cfa165_p FOREIGN KEY (partition_id, build_id) REFERENCES p_ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE NOT VALID; - -ALTER TABLE ONLY ci_job_variables - ADD CONSTRAINT temp_fk_rails_fbf3b34792_p FOREIGN KEY (partition_id, job_id) REFERENCES p_ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE NOT VALID; - ALTER TABLE ONLY user_follow_users ADD CONSTRAINT user_follow_users_followee_id_fkey FOREIGN KEY (followee_id) REFERENCES users(id) ON DELETE CASCADE; diff --git a/doc/administration/audit_events.md b/doc/administration/audit_events.md index 8207918dbbc..e924da39145 100644 --- a/doc/administration/audit_events.md +++ b/doc/administration/audit_events.md @@ -69,7 +69,8 @@ You can view audit events from user actions across an entire GitLab instance. To view instance audit events: -1. On the top bar, select **Main menu > Admin**. +1. On the left sidebar, expand the top-most chevron (**{chevron-down}**). +1. Select **Admin Area**. 1. On the left sidebar, select **Monitoring > Audit Events**. ### Export to CSV @@ -80,7 +81,8 @@ To view instance audit events: You can export the current view (including filters) of your instance audit events as a CSV file. To export the instance audit events to CSV: -1. On the top bar, select **Main menu > Admin**. +1. On the left sidebar, expand the top-most chevron (**{chevron-down}**). +1. Select **Admin Area**. 1. On the left sidebar, select **Monitoring > Audit Events**. 1. Select the available search [filters](#filter-audit-events). 1. Select **Export as CSV**. diff --git a/doc/administration/auditor_users.md b/doc/administration/auditor_users.md index 38c3a089756..3b6992c92e0 100644 --- a/doc/administration/auditor_users.md +++ b/doc/administration/auditor_users.md @@ -31,7 +31,8 @@ To create a new user account with auditor access (or change an existing user): To create a user account with auditor access: -1. On the top bar, select **Main menu > Admin**. +1. On the left sidebar, expand the top-most chevron (**{chevron-down}**). +1. Select **Admin Area**. 1. On the left sidebar, select **Overview > Users**. 1. Create a new user or edit an existing one. Set **Access Level** to **Auditor**. 1. If you created a user, select **Create user**. For an existing user, select **Save changes**. diff --git a/doc/administration/docs_self_host.md b/doc/administration/docs_self_host.md index e4cb1898aae..54f8c15a922 100644 --- a/doc/administration/docs_self_host.md +++ b/doc/administration/docs_self_host.md @@ -179,7 +179,7 @@ documentation URL requests as needed. For example, if your GitLab version is To test the setting, in GitLab, select a **Learn more** link. For example: -1. On the top bar, in the upper-right corner, select your avatar. +1. On the left sidebar, select your avatar. 1. Select **Preferences**. 1. In the **Syntax highlighting theme** section, select **Learn more**. diff --git a/doc/administration/housekeeping.md b/doc/administration/housekeeping.md index 3a2b3657145..eed14fe1bf1 100644 --- a/doc/administration/housekeeping.md +++ b/doc/administration/housekeeping.md @@ -76,7 +76,8 @@ frequently. You can change how often Gitaly is asked to optimize a repository. -1. On the top bar, select **Main menu > Admin**. +1. On the left sidebar, expand the top-most chevron (**{chevron-down}**). +1. Select **Admin Area**. 1. On the left sidebar, select **Settings > Repository**. 1. Expand **Repository maintenance**. 1. In the **Housekeeping** section, configure the housekeeping options. @@ -108,7 +109,7 @@ housekeeping tasks. The manual trigger can be useful when either: To trigger housekeeping tasks manually: -1. On the top bar, select **Main menu > Projects** and find your project. +1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project. 1. On the left sidebar, select **Settings > General**. 1. Expand **Advanced**. 1. Select **Run housekeeping**. @@ -135,7 +136,7 @@ reduce the likelihood of such race conditions. To trigger a manual prune of unreachable objects: -1. On the top bar, select **Main menu > Projects** and find your project. +1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project. 1. On the left sidebar, select **Settings > General**. 1. Expand **Advanced**. 1. Select **Run housekeeping**. diff --git a/doc/administration/inactive_project_deletion.md b/doc/administration/inactive_project_deletion.md index aad6a420246..278d585f2d9 100644 --- a/doc/administration/inactive_project_deletion.md +++ b/doc/administration/inactive_project_deletion.md @@ -23,7 +23,8 @@ For the default setting on GitLab.com, see the [GitLab.com settings page](../use To configure deletion of inactive projects: -1. On the top bar, select **Main menu > Admin**. +1. On the left sidebar, expand the top-most chevron (**{chevron-down}**). +1. Select **Admin Area**. 1. On the left sidebar, select **Settings > Repository**. 1. Expand **Repository maintenance**. 1. In the **Inactive project deletion** section, select **Delete inactive projects**. diff --git a/doc/administration/instance_review.md b/doc/administration/instance_review.md index 277595190b3..6a2ead82538 100644 --- a/doc/administration/instance_review.md +++ b/doc/administration/instance_review.md @@ -20,7 +20,7 @@ details and contact you with suggestions to improve your use of GitLab. To request an instance review: 1. Sign in as an administrator. -1. On the top bar, in the upper-right corner, select your avatar. +1. On the left sidebar, select your avatar. 1. Select **Get a free instance review**. ![Instance review](img/instance_review_v14_7.png) diff --git a/doc/administration/polling.md b/doc/administration/polling.md index deb6e89183d..50dbc7467d3 100644 --- a/doc/administration/polling.md +++ b/doc/administration/polling.md @@ -26,7 +26,8 @@ The default value (`1`) is recommended for the majority of GitLab installations. To adjust the polling interval multiplier: -1. On the top bar, select **Main menu > Admin**. +1. On the left sidebar, expand the top-most chevron (**{chevron-down}**). +1. Select **Admin Area**. 1. On the left sidebar, select **Settings > Preferences**. 1. Expand **Polling interval multiplier**. 1. Set a value for the polling interval multiplier. This multiplier is applied to all resources at diff --git a/doc/administration/repository_checks.md b/doc/administration/repository_checks.md index 894dceb2151..8cc635b50fc 100644 --- a/doc/administration/repository_checks.md +++ b/doc/administration/repository_checks.md @@ -20,7 +20,8 @@ committed to a repository. GitLab administrators can: To check a project's repository using GitLab UI: -1. On the top bar, select **Main menu > Admin**. +1. On the left sidebar, expand the top-most chevron (**{chevron-down}**). +1. Select **Admin Area**. 1. On the left sidebar, select **Overview > Projects**. 1. Select the project to check. 1. In the **Repository check** section, select **Trigger repository check**. @@ -32,7 +33,8 @@ project page in the Admin Area. If the checks fail, see [what to do](#what-to-do Instead of checking repositories manually, GitLab can be configured to run the checks periodically: -1. On the top bar, select **Main menu > Admin**. +1. On the left sidebar, expand the top-most chevron (**{chevron-down}**). +1. Select **Admin Area**. 1. On the left sidebar, select **Settings > Repository** (`/admin/application_settings/repository`). 1. Expand the **Repository maintenance** section. 1. Enable **Enable repository checks**. @@ -85,7 +87,8 @@ If a repository check fails, locate the error in the [`repocheck.log` file](logs If periodic repository checks cause false alarms, you can clear all repository check states: -1. On the top bar, select **Main menu > Admin**. +1. On the left sidebar, expand the top-most chevron (**{chevron-down}**). +1. Select **Admin Area**. 1. On the left sidebar, select **Settings > Repository** (`/admin/application_settings/repository`). 1. Expand the **Repository maintenance** section. 1. Select **Clear all repository checks**. diff --git a/doc/administration/repository_storage_paths.md b/doc/administration/repository_storage_paths.md index 4679d51e3dd..1a83a05c3dd 100644 --- a/doc/administration/repository_storage_paths.md +++ b/doc/administration/repository_storage_paths.md @@ -146,7 +146,8 @@ Linux package installations store the repositories in a `repositories` subdirect After you [configure](#configure-repository-storage-paths) multiple repository storage paths, you can choose where new repositories are stored: -1. On the top bar, select **Main menu > Admin**. +1. On the left sidebar, expand the top-most chevron (**{chevron-down}**). +1. Select **Admin Area**. 1. On the left sidebar, select **Settings > Repository** and expand the **Repository storage** section. 1. Enter values in the **Storage nodes for new repositories** fields. diff --git a/doc/administration/repository_storage_types.md b/doc/administration/repository_storage_types.md index 375c9a6e981..3bd73b4df94 100644 --- a/doc/administration/repository_storage_types.md +++ b/doc/administration/repository_storage_types.md @@ -78,7 +78,8 @@ Administrators can look up a project's hashed path from its name or ID using: To look up a project's hash path in the Admin Area: -1. On the top bar, select **Main menu > Admin**. +1. On the left sidebar, expand the top-most chevron (**{chevron-down}**). +1. Select **Admin Area**. 1. On the left sidebar, select **Overview > Projects** and select the project. The **Gitaly relative path** is displayed there and looks similar to: diff --git a/doc/administration/server_hooks.md b/doc/administration/server_hooks.md index dcaa19358c4..a205e5a4a6f 100644 --- a/doc/administration/server_hooks.md +++ b/doc/administration/server_hooks.md @@ -71,7 +71,8 @@ If you implemented the server hook code correctly, it should execute when the Gi To create server hooks for a repository: -1. On the top bar, select **Main menu > Admin**. +1. On the left sidebar, expand the top-most chevron (**{chevron-down}**). +1. Select **Admin Area**. 1. Go to **Overview > Projects** and select the project you want to add a server hook to. 1. On the page that appears, locate the value of **Gitaly relative path**. This path is where server hooks must be located. - If you are using [hashed storage](repository_storage_types.md#hashed-storage), see diff --git a/doc/administration/static_objects_external_storage.md b/doc/administration/static_objects_external_storage.md index 73f44ed3889..c7a22da38de 100644 --- a/doc/administration/static_objects_external_storage.md +++ b/doc/administration/static_objects_external_storage.md @@ -16,7 +16,8 @@ storage such as a content delivery network (CDN). To configure external storage for static objects: -1. On the top bar, select **Main menu > Admin**. +1. On the left sidebar, expand the top-most chevron (**{chevron-down}**). +1. Select **Admin Area**. 1. On the left sidebar, select **Settings > Repository**. 1. Expand the **External storage for repository static objects** section. 1. Enter the base URL and an arbitrary token. When you [set up external storage](#set-up-external-storage), diff --git a/doc/administration/system_hooks.md b/doc/administration/system_hooks.md index 8d343e7c541..dcacacaf47b 100644 --- a/doc/administration/system_hooks.md +++ b/doc/administration/system_hooks.md @@ -54,7 +54,8 @@ for Push and Tag events, but we never display commits. To create a system hook: -1. On the top bar, select **Main menu > Admin**. +1. On the left sidebar, expand the top-most chevron (**{chevron-down}**). +1. Select **Admin Area**. 1. On the left sidebar, select **System Hooks**. 1. Provide the **URL** and **Secret Token**. 1. Select the checkbox next to each optional **Trigger** you want to enable. diff --git a/doc/administration/whats-new.md b/doc/administration/whats-new.md index d9c8a991577..b34b054d87c 100644 --- a/doc/administration/whats-new.md +++ b/doc/administration/whats-new.md @@ -23,7 +23,7 @@ All users can see the feature list, but the entries might differ depending on th To access the **What's new** feature: -1. On the top bar, select the **{question}** icon. +1. On the left sidebar, at the bottom, select **Help** (**{question}**). 1. Select **What's new** from the menu. ## Configure What's new @@ -31,7 +31,8 @@ To access the **What's new** feature: You can configure **What's new** to display features based on the tier, or you can hide it. To configure it: -1. On the top bar, select **Main menu > Admin**. +1. On the left sidebar, expand the top-most chevron (**{chevron-down}**). +1. Select **Admin Area**. 1. On the left sidebar, select **Settings > Preferences**. 1. Expand **What's new**, and choose one of the following options: diff --git a/doc/ci/yaml/includes.md b/doc/ci/yaml/includes.md index 3cf1e9c3df9..5c818a81ff8 100644 --- a/doc/ci/yaml/includes.md +++ b/doc/ci/yaml/includes.md @@ -418,11 +418,17 @@ these keywords: ### `include` with `rules:if` +> Support for `when: never` [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/348146) in GitLab 16.1. + Use [`rules:if`](index.md#rulesif) to conditionally include other configuration files based on the status of CI/CD variables. For example: ```yaml include: + - local: builds.yml + rules: + - if: $DONT_INCLUDE_BUILDS == "true" + when: never - local: builds.yml rules: - if: $INCLUDE_BUILDS == "true" @@ -437,11 +443,18 @@ test: ### `include` with `rules:exists` +> Support for `when: never` [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/348146) in GitLab 16.1. + Use [`rules:exists`](index.md#rulesexists) to conditionally include other configuration files based on the existence of files. For example: ```yaml include: + - local: builds.yml + rules: + - exists: + - exception-file.md + when: never - local: builds.yml rules: - exists: diff --git a/doc/update/background_migrations.md b/doc/update/background_migrations.md index 581bd5ff32a..bf9f2df9e87 100644 --- a/doc/update/background_migrations.md +++ b/doc/update/background_migrations.md @@ -96,8 +96,9 @@ Batched background migrations are handled by Sidekiq and [run in isolation](../d To check the status of batched background migrations: -1. On the top bar, select **Main menu > Admin**. -1. On the left sidebar, select **Monitoring > Background Migrations**. +1. On the left sidebar, expand the top-most chevron (**{chevron-down}**). +1. Select **Admin Area**. +1. Select **Monitoring > Background Migrations**. ![queued batched background migrations table](img/batched_background_migrations_queued_v14_0.png) diff --git a/doc/update/plan_your_upgrade.md b/doc/update/plan_your_upgrade.md index e1354ea3665..9378b104c81 100644 --- a/doc/update/plan_your_upgrade.md +++ b/doc/update/plan_your_upgrade.md @@ -122,8 +122,9 @@ to your instance and then upgrade it for any relevant features you're using. [turning on maintenance mode](../administration/maintenance_mode/index.md) during the upgrade. - About PostgreSQL: - - On the top bar, select **Main menu > Admin**, and look for the version of - PostgreSQL you are using. + 1. On the left sidebar, expand the top-most chevron (**{chevron-down}**). + 1. Select **Admin Area**. + 1. Look for the version of PostgreSQL you are using. If [a PostgreSQL upgrade is needed](../administration/package_information/postgresql_versions.md), account for the relevant [packaged](https://docs.gitlab.com/omnibus/settings/database.html#upgrade-packaged-postgresql-server) diff --git a/doc/user/ai_features.md b/doc/user/ai_features.md index ac1de01918e..d5f7201556e 100644 --- a/doc/user/ai_features.md +++ b/doc/user/ai_features.md @@ -76,8 +76,8 @@ Prerequisites: To explain your code: -1. On the top bar, select **Main menu > Projects** and find your project. -1. On the left sidebar, select **Merge requests**, then select your merge request. +1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project. +1. On the left sidebar, select **Code > Merge requests**, then select your merge request. 1. On the secondary menu, select **Changes**. 1. Go to the file, and select the lines that you want to have explained. 1. On the left side, select the question mark (**{question}**). You might have to scroll to the first line of your selection to view it. This sends the selected code, together with a prompt, to provide an explanation to the large language model. @@ -108,8 +108,8 @@ Prerequisites: To explain your vulnerability: -1. On the top bar, select **Main menu > Projects** and find your project. -1. On the left sidebar, select **Security and Compliance > Vulnerability report**. +1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project. +1. On the left sidebar, select **Secure > Vulnerability report**. 1. Find a SAST vulnerability. 1. Open the vulnerability. 1. Select **Try it out**. diff --git a/doc/user/free_user_limit.md b/doc/user/free_user_limit.md index 181eb00bb50..410bdc4b5f5 100644 --- a/doc/user/free_user_limit.md +++ b/doc/user/free_user_limit.md @@ -27,7 +27,7 @@ Prerequisite: - You must have the Owner role for the group. -1. On the top bar, select **Main menu > Groups > View all groups** and find your group. +1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your group. 1. On the left sidebar, select **Settings > Usage Quotas**. 1. To view all members, select the **Seats** tab. 1. To remove a member, select **Remove user**. diff --git a/doc/user/okrs.md b/doc/user/okrs.md index f2e49b44154..b9fbc4594cd 100644 --- a/doc/user/okrs.md +++ b/doc/user/okrs.md @@ -60,8 +60,8 @@ Prerequisites: To create an objective: -1. On the top bar, select **Main menu > Projects** and find your project. -1. On the left sidebar, select **Issues**. +1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project. +1. On the left sidebar, select **Plan > Issues**. 1. In the upper-right corner, next to **New issue**, select the down arrow **{chevron-lg-down}** and then select **New objective**. 1. Select **New objective** again. 1. Enter the objective title. @@ -77,8 +77,8 @@ Prerequisites: To view an objective: -1. On the top bar, select **Main menu > Projects** and find your project. -1. On the left sidebar, select **Issues**. +1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project. +1. On the left sidebar, select **Plan > Issues**. 1. [Filter the list of issues](project/issues/managing_issues.md#filter-the-list-of-issues) for `Type = objective`. 1. Select the title of an objective from the list. @@ -91,8 +91,8 @@ Prerequisites: To view a key result: -1. On the top bar, select **Main menu > Projects** and find your project. -1. On the left sidebar, select **Issues**. +1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project. +1. On the left sidebar, select **Plan > Issues**. 1. [Filter the list of issues](project/issues/managing_issues.md#filter-the-list-of-issues) for `Type = key_result`. 1. Select the title of a key result from the list. diff --git a/doc/user/project/push_options.md b/doc/user/project/push_options.md index 1f85490795f..368a59e69b0 100644 --- a/doc/user/project/push_options.md +++ b/doc/user/project/push_options.md @@ -35,7 +35,7 @@ You can use push options to skip a CI/CD pipeline, or pass CI/CD variables. | Push option | Description | Introduced in version | | ------------------------------ | ------------------------------------------------------------------------------------------- |---------------------- | -| `ci.skip` | Do not create a CI pipeline for the latest push. Only skips branch pipelines and not [merge request pipelines](../../ci/pipelines/merge_request_pipelines.md). | [11.7](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/15643) | +| `ci.skip` | Do not create a CI pipeline for the latest push. Only skips branch pipelines and not [merge request pipelines](../../ci/pipelines/merge_request_pipelines.md). This does not skip pipelines for CI integrations, such as Jenkins. | [11.7](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/15643) | | `ci.variable="="` | Provide [CI/CD variables](../../ci/variables/index.md) to be used in a CI pipeline, if one is created due to the push. Only passes variables to branch pipelines and not [merge request pipelines](../../ci/pipelines/merge_request_pipelines.md). | [12.6](https://gitlab.com/gitlab-org/gitlab/-/issues/27983) | An example of using `ci.skip`: diff --git a/doc/user/project/repository/code_suggestions.md b/doc/user/project/repository/code_suggestions.md index 90330d5f130..e61f9abe20c 100644 --- a/doc/user/project/repository/code_suggestions.md +++ b/doc/user/project/repository/code_suggestions.md @@ -12,6 +12,7 @@ type: index, reference > - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/408158) from GitLab Ultimate to GitLab Premium in 16.0. > - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/410801) from GitLab Premium to GitLab Free in 16.0. > - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/121079) in GitLab 16.1. +> - [Default to third-party AI services](https://gitlab.com/groups/gitlab-org/-/epics/10562) in GitLab 16.1. WARNING: This feature is in [Beta](/ee/policy/experiment-beta-support.md#beta). @@ -34,19 +35,12 @@ Code Suggestions are available in Visual Studio Code when you have the GitLab Wo Code Suggestions may produce [low-quality or incomplete suggestions](#model-accuracy-and-quality). +Language support varies depending on which AI model serves Code Suggestions. To use Code Suggestions entirely within GitLab cloud infrastructure, disable third-party AI services. To receive higher quality suggestions, [enable third-party AI services](#third-party-ai-services-controls). + The best results from Code Suggestions are expected for these languages: -- C/C++ -- C# -- Go -- Java -- JavaScript -- Python -- PHP -- Ruby -- Rust -- Scala -- TypeScript +- **Third-party AI services (Google Codey)**: Go, Google Cloud CLI, Google SQL, Java, JavaScript, Kubernetes Resource Model (KRM), Python, Terraform, TypeScript. +- **GitLab first-party AI model**: C/C++, C#, Go, Java, JavaScript, Python, PHP, Ruby, Rust, Scala, TypeScript. Suggestions may be mixed for other languages. Using natural language code comments to request completions may also not function as expected. @@ -70,6 +64,18 @@ Each user can enable Code Suggestions for themselves: NOTE: If Code Suggestions is [enabled for the group](../../group/manage.md#enable-code-suggestions), the group setting overrides the user setting. +## Enable Code Suggestions in WebIDE + +Prerequisites: + +- Code Suggestions must be [enabled for the top-level group](../../group/manage.md#enable-code-suggestions). +- Code Suggestions must be [enabled for your user account](#enable-code-suggestions-for-an-individual-user). + +Code Suggestions work automatically in the [GitLab WebIDE](../../project/web_ide/index.md) if the above prerequisites are met. To disable Code Suggestions in the WebIDE, disable the user account setting. + +NOTE: +Disabling in the WebIDE will also disable in any other IDEs you use locally like VS Code. Support for [more granular control per IDE](https://gitlab.com/groups/gitlab-org/-/epics/10624) is proposed. + ## Enable Code Suggestions in VS Code Prerequisites: @@ -142,6 +148,14 @@ If the above steps do not solve your issue, the problem may be related to the re - Reauthorize your GitLab account in VSCode using OAuth. - Test the code suggestions feature with different file extensions to verify if the issue is resolved. +## Third-party AI services controls + +Organizations can opt to use Code Suggestions entirely within GitLab cloud infrastructure. This option can be controlled with the top-level group [Third-party AI setting](../../group/manage.md#enable-third-party-ai-features). + +Having the third-party AI setting enabled will allow Code Suggestions to use third-party AI services, which is likely to produce higher quality results. Please note that language support varies between the two options and will change over time. + +To use Code Suggestions entirely within GitLab’s cloud infrastructure, disable third-party AI services. You can disable Code Suggestions entirely in [your user profile settings](#enable-code-suggestions-for-an-individual-user). + ## Stability and performance This feature is currently in [Beta](/ee/policy/experiment-beta-support.md#beta). @@ -158,8 +172,12 @@ Your personal access token enables a secure API connection to GitLab.com. This API connection securely transmits a context window from VS Code to the Code Suggestions ML model for inference, and the generated suggestion is transmitted back to VS Code. +Depending on your settings, different ML models will be used to provide Code Suggestions. GitLab currently leverages [Google Cloud's Vertex AI Codey API models](https://cloud.google.com/vertex-ai/docs/generative-ai/code/code-models-overview) for third-party AI powered Code Suggestions. The sections below refer only to GitLab first-party AI Model. + ### Data privacy +This section applies only to customers who have third-party AI services disabled. + Code Suggestions operate completely in the GitLab.com infrastructure, providing the same level of [security](https://about.gitlab.com/security/) as any other feature of GitLab.com, and processing any personal data in accordance with our [Privacy Statement](https://about.gitlab.com/privacy/). @@ -172,6 +190,8 @@ Your data also never leaves GitLab.com. All training and inference is done in Gi ### Training data +This section applies only to customers who have third-party AI services disabled. + Code Suggestions uses open source pre-trained base models from the [CodeGen family](https://openreview.net/forum?id=iaYcJKpY2B_) including CodeGen-MULTI and CodeGen-NL. We then re-train and fine-tune these base models with a customized open source dataset to enable multi-language @@ -191,14 +211,18 @@ Code Suggestions do not prevent you from writing code in your IDE. ### Internet connectivity +Code Suggestions does not work with offline environments. + To use Code Suggestions: - On GitLab.com, you must have an internet connection and be able to access GitLab. -- In GitLab 16.1 and later, on self-managed GitLab, you must have an internet connection. Code Suggestions does not work with offline environments. +- In GitLab 16.1 and later, on self-managed GitLab, you must have an internet connection. + +[Self-managed support via a proxy to GitLab.com](https://gitlab.com/groups/gitlab-org/-/epics/10528) has been proposed. ### Model accuracy and quality -While in Beta, Code Suggestions can generate low-quality, incomplete, and possibly insecure code. +Regardless of whether third-party AI services are enabled, while in Beta, Code Suggestions can generate low-quality, incomplete, and possibly insecure code. We strongly encourage all beta users to leverage GitLab native [Code Quality Scanning](../../../ci/testing/code_quality.md) and [Security Scanning](../../application_security/index.md) capabilities. diff --git a/doc/user/project/repository/forking_workflow.md b/doc/user/project/repository/forking_workflow.md index 3d60f21c1ad..91f6d0a0bf9 100644 --- a/doc/user/project/repository/forking_workflow.md +++ b/doc/user/project/repository/forking_workflow.md @@ -195,7 +195,6 @@ to share objects with another repository: ## Related topics -- GitLab blog post: [Keep your fork up to date with its origin](https://about.gitlab.com/blog/2016/12/01/how-to-keep-your-fork-up-to-date-with-its-origin/) - GitLab community forum: [Refreshing a fork](https://forum.gitlab.com/t/refreshing-a-fork/32469) ## Troubleshooting diff --git a/doc/user/public_access.md b/doc/user/public_access.md index 58eebc16d74..002cb97dd93 100644 --- a/doc/user/public_access.md +++ b/doc/user/public_access.md @@ -59,7 +59,7 @@ Prerequisite: - You must have the Owner role for a project. -1. On the top bar, select **Main menu > Projects** and find your project. +1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project. 1. On the left sidebar, select **Settings > General**. 1. Expand **Visibility, project features, permissions**. 1. Change **Project visibility** to either **Private**, **Internal**, or **Public**. @@ -78,7 +78,7 @@ Prerequisites: restrictive as the new setting of the parent group. For example, you cannot set a group to private if a subgroup or project in that group is public. -1. On the top bar, select **Main menu > Groups** and find your project. +1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your group. 1. On the left sidebar, select **Settings > General**. 1. Expand **Naming, visibility**. 1. Under **Visibility level** select either **Private**, **Internal**, or **Public**. diff --git a/doc/user/shortcuts.md b/doc/user/shortcuts.md index 6216a1630b2..e195be5586a 100644 --- a/doc/user/shortcuts.md +++ b/doc/user/shortcuts.md @@ -324,7 +324,7 @@ press ? to display the list of shortcuts. To enable keyboard shortcuts: -1. On the top bar, select the Help menu (**{question}**), then **Keyboard shortcuts**. +1. On the left sidebar, at the bottom, select **Help** (**{question}**), then **Keyboard shortcuts**. 1. Select **Toggle shortcuts**. ## Troubleshooting diff --git a/doc/user/snippets.md b/doc/user/snippets.md index 7ca897288e1..3ad003e4f4c 100644 --- a/doc/user/snippets.md +++ b/doc/user/snippets.md @@ -66,14 +66,22 @@ In GitLab versions 13.0 and later, snippets are [versioned by default](#versione To discover all snippets visible to you in GitLab, you can: -- **View all snippets visible to you**: On the top bar of your GitLab - instance, select **Main menu > Your work** and then **Snippets** to view your snippets dashboard. -- **Visit [GitLab snippets](https://gitlab.com/dashboard/snippets)** for your snippets on GitLab.com. -- **Explore all public snippets**: On the top bar of your GitLab - instance, select **Main menu > Explore** and select **Snippets** to view - [all public snippets](https://gitlab.com/explore/snippets). -- **View a project's snippets**: In your project, - go to **Snippets**. +- **View a project's snippets**: + 1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project. + 1. Select **Code > Snippets**. +- **View all the snippets you created**: + 1. On the left sidebar, expand the top-most chevron (**{chevron-down}**). + 1. Select **Your work**. + 1. Select **Snippets**. + + On GitLab.com, you can also visit your [snippets directly](https://gitlab.com/dashboard/snippets). + +- **Explore all public snippets**: + 1. On the left sidebar, expand the top-most chevron (**{chevron-down}**). + 1. Select **Explore**. + 1. Select **Snippets**. + + On GitLab.com, you can also visit [all public snippets directly](https://gitlab.com/explore/snippets). ## Change default visibility of snippets @@ -225,8 +233,8 @@ Prerequisites: To do this task: -1. On the top bar, select **Main menu > Projects** and find your project. -1. On the left sidebar, select **Snippets**. +1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project. +1. On the left sidebar, select **Code > Snippets**. 1. Select the snippet you want to report as spam. 1. Select **Submit as spam**. diff --git a/doc/user/ssh.md b/doc/user/ssh.md index b698f5a3edc..a11f3c4dbd6 100644 --- a/doc/user/ssh.md +++ b/doc/user/ssh.md @@ -277,7 +277,7 @@ You can use [1Password](https://1password.com/) and the [1Password browser exten - Use an existing SSH in your 1Password vault to authenticate with GitLab. 1. Sign in to GitLab. -1. On the top bar, in the upper-right corner, select your avatar. +1. On the left sidebar, select your avatar. 1. Select **Edit profile**. 1. On the left sidebar, select **SSH Keys**. 1. Select **Key**, and you should see the 1Password helper appear. @@ -322,7 +322,7 @@ To use SSH with GitLab, copy your public key to your GitLab account: Replace `id_ed25519.pub` with your filename. For example, use `id_rsa.pub` for RSA. 1. Sign in to GitLab. -1. On the top bar, in the upper-right corner, select your avatar. +1. On the left sidebar, select your avatar. 1. Select **Edit profile**. 1. On the left sidebar, select **SSH Keys**. 1. In the **Key** box, paste the contents of your public key. @@ -395,7 +395,7 @@ on `ssh` command options, see the `man` pages for both `ssh` and `ssh_config`. ## View your account's SSH keys 1. Sign in to GitLab. -1. On the top bar, in the upper-right corner, select your avatar. +1. On the left sidebar, select your avatar. 1. Select **Edit profile**. 1. On the left sidebar, select **SSH Keys**. diff --git a/doc/user/todos.md b/doc/user/todos.md index 8f67311b559..95bc8a553c1 100644 --- a/doc/user/todos.md +++ b/doc/user/todos.md @@ -20,7 +20,7 @@ You can use the To-Do List to track [actions](#actions-that-create-to-do-items) To access your To-Do List: -On the top bar, in the upper-right corner, select the To-Do List (**{task-done}**). +On the left sidebar, at the top, select To-Do list (**{task-done}**). ## Search the To-Do List diff --git a/doc/user/usage_quotas.md b/doc/user/usage_quotas.md index d6ca09e4392..933d950eb35 100644 --- a/doc/user/usage_quotas.md +++ b/doc/user/usage_quotas.md @@ -23,10 +23,8 @@ Prerequisites: - To view storage usage for a project, you must have at least the Maintainer role for the project or Owner role for the namespace. - To view storage usage for a namespace, you must have the Owner role for the namespace. -1. Go to your project or namespace: - - For a project, on the top bar, select **Main menu > Projects** and find your project. - - For a namespace, enter the URL in your browser's toolbar. -1. From the left sidebar, select **Settings > Usage Quotas**. +1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project. +1. On the left sidebar, select **Settings > Usage Quotas**. 1. Select the **Storage** tab. Select any title to view details. The information on this page diff --git a/lib/gitlab/ci/config/entry/include/rules/rule.rb b/lib/gitlab/ci/config/entry/include/rules/rule.rb index fa99a7204d6..60ce43a1546 100644 --- a/lib/gitlab/ci/config/entry/include/rules/rule.rb +++ b/lib/gitlab/ci/config/entry/include/rules/rule.rb @@ -9,10 +9,14 @@ module Gitlab include ::Gitlab::Config::Entry::Validatable include ::Gitlab::Config::Entry::Attributable - ALLOWED_KEYS = %i[if exists].freeze + ALLOWED_KEYS = %i[if exists when].freeze + ALLOWED_WHEN = %w[never].freeze - attributes :if, :exists + attributes :if, :exists, :when + # Include rules are validated before Entry validations. This is because + # the include files are expanded before `compose!` runs in Ci::Config. + # The actual validation logic is in lib/gitlab/ci/config/external/rules.rb. validations do validates :config, presence: true validates :config, type: { with: Hash } diff --git a/lib/gitlab/ci/config/external/rules.rb b/lib/gitlab/ci/config/external/rules.rb index 95470537de3..8aaa14b3d7b 100644 --- a/lib/gitlab/ci/config/external/rules.rb +++ b/lib/gitlab/ci/config/external/rules.rb @@ -6,6 +6,7 @@ module Gitlab module External class Rules ALLOWED_KEYS = Entry::Include::Rules::Rule::ALLOWED_KEYS + ALLOWED_WHEN = Entry::Include::Rules::Rule::ALLOWED_WHEN InvalidIncludeRulesError = Class.new(Mapper::Error) @@ -16,7 +17,17 @@ module Gitlab end def evaluate(context) - Result.new(@rule_list.nil? || match_rule(context)) + if Feature.enabled?(:ci_support_include_rules_when_never, context.project) + if @rule_list.nil? + Result.new(nil) + elsif matched_rule = match_rule(context) + Result.new(matched_rule.attributes[:when]) + else + Result.new('never') + end + else + LegacyResult.new(@rule_list.nil? || match_rule(context)) + end end private @@ -29,13 +40,23 @@ module Gitlab return unless rule_hashes.is_a?(Array) rule_hashes.each do |rule_hash| - next if (rule_hash.keys - ALLOWED_KEYS).empty? + next if (rule_hash.keys - ALLOWED_KEYS).empty? && valid_when?(rule_hash) raise InvalidIncludeRulesError, "invalid include rule: #{rule_hash}" end end - Result = Struct.new(:result) do + def valid_when?(rule_hash) + rule_hash[:when].nil? || rule_hash[:when].in?(ALLOWED_WHEN) + end + + Result = Struct.new(:when) do + def pass? + self.when != 'never' + end + end + + LegacyResult = Struct.new(:result) do def pass? !!result end diff --git a/lib/gitlab/database_importers/default_organization_importer.rb b/lib/gitlab/database_importers/default_organization_importer.rb new file mode 100644 index 00000000000..147c0d19b01 --- /dev/null +++ b/lib/gitlab/database_importers/default_organization_importer.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module Gitlab + module DatabaseImporters + module DefaultOrganizationImporter + def self.create_default_organization + return if Organizations::Organization.default_organization + + # When adding or changing attributes, consider changing the factory for Organization model as well + # spec/factories/organizations/organizations.rb + Organizations::Organization.create!( + id: Organizations::Organization::DEFAULT_ORGANIZATION_ID, + name: 'Default', + path: 'default' + ) + end + end + end +end diff --git a/lib/gitlab/usage/metrics/instrumentations/count_imported_projects_metric.rb b/lib/gitlab/usage/metrics/instrumentations/count_imported_projects_metric.rb index d485e8b4f72..05e29f2d885 100644 --- a/lib/gitlab/usage/metrics/instrumentations/count_imported_projects_metric.rb +++ b/lib/gitlab/usage/metrics/instrumentations/count_imported_projects_metric.rb @@ -23,7 +23,7 @@ module Gitlab ::Project .select(:id) .where(Project.arel_table[:created_at].gteq(start)) # rubocop:disable UsageData/LargeTable - .order(created_at: :asc).limit(1).first&.id + .order(created_at: :asc).order(id: :asc).limit(1).first&.id end end end @@ -36,7 +36,7 @@ module Gitlab ::Project .select(:id) .where(Project.arel_table[:created_at].lteq(finish)) # rubocop:disable UsageData/LargeTable - .order(created_at: :desc).limit(1).first&.id + .order(created_at: :desc).order(id: :desc).limit(1).first&.id end end end diff --git a/spec/factories/organizations/organizations.rb b/spec/factories/organizations/organizations.rb index c916b966abc..f88ef046248 100644 --- a/spec/factories/organizations/organizations.rb +++ b/spec/factories/organizations/organizations.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +# When adding or changing attributes, consider changing the database importer as well +# lib/gitlab/database_importers/default_organization_importer.rb FactoryBot.define do factory :organization, class: 'Organizations::Organization' do sequence(:name) { |n| "Organization ##{n}" } diff --git a/spec/frontend/editor/schema/ci/yaml_tests/negative_tests/include.yml b/spec/frontend/editor/schema/ci/yaml_tests/negative_tests/include.yml index 6afd8baa0e8..56941fcc6d5 100644 --- a/spec/frontend/editor/schema/ci/yaml_tests/negative_tests/include.yml +++ b/spec/frontend/editor/schema/ci/yaml_tests/negative_tests/include.yml @@ -1,3 +1,10 @@ +# invalid include:rules +include: + - local: builds.yml + rules: + - if: '$INCLUDE_BUILDS == "true"' + when: on_success + # invalid trigger:include trigger missing file property: stage: prepare diff --git a/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/include.yml b/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/include.yml index c00ab0d464a..fffdda8e6d6 100644 --- a/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/include.yml +++ b/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/include.yml @@ -5,8 +5,8 @@ stages: include: - local: builds.yml rules: - - if: '$INCLUDE_BUILDS == "true"' - when: always + - if: '$INCLUDE_BUILDS == "false"' + when: never # valid trigger:include trigger:include accepts project and file properties: diff --git a/spec/lib/gitlab/ci/config/entry/include/rules/rule_spec.rb b/spec/lib/gitlab/ci/config/entry/include/rules/rule_spec.rb index 6116fbced2b..10c1d92e209 100644 --- a/spec/lib/gitlab/ci/config/entry/include/rules/rule_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/include/rules/rule_spec.rb @@ -3,7 +3,7 @@ require 'fast_spec_helper' require_dependency 'active_model' -RSpec.describe Gitlab::Ci::Config::Entry::Include::Rules::Rule do +RSpec.describe Gitlab::Ci::Config::Entry::Include::Rules::Rule, feature_category: :pipeline_composition do let(:factory) do Gitlab::Config::Entry::Factory.new(described_class) .value(config) @@ -24,6 +24,12 @@ RSpec.describe Gitlab::Ci::Config::Entry::Include::Rules::Rule do let(:config) { { if: '$THIS || $THAT' } } it { is_expected.to be_valid } + + context 'with when:' do + let(:config) { { if: '$THIS || $THAT', when: 'never' } } + + it { is_expected.to be_valid } + end end context 'when specifying an exists: clause' do @@ -90,6 +96,14 @@ RSpec.describe Gitlab::Ci::Config::Entry::Include::Rules::Rule do it 'returns the config' do expect(subject).to eq(if: '$THIS || $THAT') end + + context 'with when:' do + let(:config) { { if: '$THIS || $THAT', when: 'never' } } + + it 'returns the config' do + expect(subject).to eq(if: '$THIS || $THAT', when: 'never') + end + end end context 'when specifying an exists: clause' do diff --git a/spec/lib/gitlab/ci/config/external/mapper/filter_spec.rb b/spec/lib/gitlab/ci/config/external/mapper/filter_spec.rb index 5195567ebb4..4da3e7e51a7 100644 --- a/spec/lib/gitlab/ci/config/external/mapper/filter_spec.rb +++ b/spec/lib/gitlab/ci/config/external/mapper/filter_spec.rb @@ -18,6 +18,7 @@ RSpec.describe Gitlab::Ci::Config::External::Mapper::Filter, feature_category: : describe '#process' do let(:locations) do [{ local: 'config/.gitlab-ci.yml', rules: [{ if: '$VARIABLE1' }] }, + { remote: 'https://testing.com/.gitlab-ci.yml', rules: [{ if: '$VARIABLE1', when: 'never' }] }, { remote: 'https://example.com/.gitlab-ci.yml', rules: [{ if: '$VARIABLE2' }] }] end @@ -28,5 +29,18 @@ RSpec.describe Gitlab::Ci::Config::External::Mapper::Filter, feature_category: : [{ local: 'config/.gitlab-ci.yml', rules: [{ if: '$VARIABLE1' }] }] ) end + + context 'when FF `ci_support_include_rules_when_never` is disabled' do + before do + stub_feature_flags(ci_support_include_rules_when_never: false) + end + + it 'filters locations according to rules ignoring when:' do + is_expected.to eq( + [{ local: 'config/.gitlab-ci.yml', rules: [{ if: '$VARIABLE1' }] }, + { remote: 'https://testing.com/.gitlab-ci.yml', rules: [{ if: '$VARIABLE1', when: 'never' }] }] + ) + end + end end end diff --git a/spec/lib/gitlab/ci/config/external/rules_spec.rb b/spec/lib/gitlab/ci/config/external/rules_spec.rb index cc73338b5a8..3cb9dedbefe 100644 --- a/spec/lib/gitlab/ci/config/external/rules_spec.rb +++ b/spec/lib/gitlab/ci/config/external/rules_spec.rb @@ -3,43 +3,42 @@ require 'spec_helper' RSpec.describe Gitlab::Ci::Config::External::Rules, feature_category: :pipeline_composition do - let(:rule_hashes) {} + # Remove `project` property when FF `ci_support_include_rules_when_never` is removed + let(:context) { double(variables_hash: {}, project: nil) } + let(:rule_hashes) { [{ if: '$MY_VAR == "hello"' }] } subject(:rules) { described_class.new(rule_hashes) } describe '#evaluate' do - let(:context) { double(variables_hash: {}) } - subject(:result) { rules.evaluate(context).pass? } context 'when there is no rule' do + let(:rule_hashes) {} + it { is_expected.to eq(true) } end - context 'when there is a rule with if' do - let(:rule_hashes) { [{ if: '$MY_VAR == "hello"' }] } + shared_examples 'when there is a rule with if' do |rule_matched_result = true, rule_not_matched_result = false| + # Remove this `before` block when FF `ci_support_include_rules_when_never` is removed + before do + allow(context).to receive(:project).and_return(nil) + end context 'when the rule matches' do let(:context) { double(variables_hash: { 'MY_VAR' => 'hello' }) } - it { is_expected.to eq(true) } + it { is_expected.to eq(rule_matched_result) } end context 'when the rule does not match' do let(:context) { double(variables_hash: { 'MY_VAR' => 'invalid' }) } - it { is_expected.to eq(false) } + it { is_expected.to eq(rule_not_matched_result) } end end - context 'when there is a rule with exists' do + shared_examples 'when there is a rule with exists' do |file_exists_result = true, file_not_exists_result = false| let(:project) { create(:project, :repository) } - let(:context) { double(project: project, sha: project.repository.tree.sha, top_level_worktree_paths: ['test.md']) } - let(:rule_hashes) { [{ exists: 'Dockerfile' }] } - - context 'when the file does not exist' do - it { is_expected.to eq(false) } - end context 'when the file exists' do let(:context) { double(project: project, sha: project.repository.tree.sha, top_level_worktree_paths: ['Dockerfile']) } @@ -48,16 +47,83 @@ RSpec.describe Gitlab::Ci::Config::External::Rules, feature_category: :pipeline_ project.repository.create_file(project.first_owner, 'Dockerfile', "commit", message: 'test', branch_name: "master") end - it { is_expected.to eq(true) } + it { is_expected.to eq(file_exists_result) } + end + + context 'when the file does not exist' do + let(:context) { double(project: project, sha: project.repository.tree.sha, top_level_worktree_paths: ['test.md']) } + + it { is_expected.to eq(file_not_exists_result) } end end - context 'when there is a rule with if and when' do - let(:rule_hashes) { [{ if: '$MY_VAR == "hello"', when: 'on_success' }] } + it_behaves_like 'when there is a rule with if' - it 'raises an error' do - expect { result }.to raise_error(described_class::InvalidIncludeRulesError, - 'invalid include rule: {:if=>"$MY_VAR == \"hello\"", :when=>"on_success"}') + context 'when there is a rule with exists' do + let(:rule_hashes) { [{ exists: 'Dockerfile' }] } + + it_behaves_like 'when there is a rule with exists' + end + + context 'when there is a rule with if and when' do + context 'with when: never' do + let(:rule_hashes) { [{ if: '$MY_VAR == "hello"', when: 'never' }] } + + it_behaves_like 'when there is a rule with if', false, false + + context 'when FF `ci_support_include_rules_when_never` is disabled' do + before do + stub_feature_flags(ci_support_include_rules_when_never: false) + end + + it_behaves_like 'when there is a rule with if' + end + end + + context 'with when: ' do + let(:rule_hashes) { [{ if: '$MY_VAR == "hello"', when: 'on_success' }] } + + it 'raises an error' do + expect { result }.to raise_error(described_class::InvalidIncludeRulesError, + 'invalid include rule: {:if=>"$MY_VAR == \"hello\"", :when=>"on_success"}') + end + end + + context 'with when: null' do + let(:rule_hashes) { [{ if: '$MY_VAR == "hello"', when: nil }] } + + it_behaves_like 'when there is a rule with if' + end + end + + context 'when there is a rule with exists and when' do + context 'with when: never' do + let(:rule_hashes) { [{ exists: 'Dockerfile', when: 'never' }] } + + it_behaves_like 'when there is a rule with exists', false, false + + context 'when FF `ci_support_include_rules_when_never` is disabled' do + before do + stub_feature_flags(ci_support_include_rules_when_never: false) + end + + it_behaves_like 'when there is a rule with exists' + end + end + + context 'with when: ' do + let(:rule_hashes) { [{ exists: 'Dockerfile', when: 'on_success' }] } + + it 'raises an error' do + expect { result }.to raise_error(described_class::InvalidIncludeRulesError, + 'invalid include rule: {:exists=>"Dockerfile", :when=>"on_success"}') + end + end + + context 'with when: null' do + let(:rule_hashes) { [{ exists: 'Dockerfile', when: nil }] } + + it_behaves_like 'when there is a rule with exists' end end diff --git a/spec/lib/gitlab/database_importers/default_organization_importer_spec.rb b/spec/lib/gitlab/database_importers/default_organization_importer_spec.rb new file mode 100644 index 00000000000..41a8aaca699 --- /dev/null +++ b/spec/lib/gitlab/database_importers/default_organization_importer_spec.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::DatabaseImporters::DefaultOrganizationImporter, feature_category: :cell do + describe '#create_default_organization' do + let(:default_id) { Organizations::Organization::DEFAULT_ORGANIZATION_ID } + + subject { described_class.create_default_organization } + + context 'when default organization does not exists' do + it 'creates a default organization' do + expect(Organizations::Organization.find_by(id: default_id)).to be_nil + + subject + + default_org = Organizations::Organization.find(default_id) + + expect(default_org.name).to eq('Default') + expect(default_org.path).to eq('default') + end + end + + context 'when default organization exists' do + let!(:default_org) { create(:organization, :default) } + + it 'does not create another organization' do + expect { subject }.not_to change { Organizations::Organization.count } + end + end + end +end diff --git a/spec/migrations/20230605095810_ensure_default_organization_spec.rb b/spec/migrations/20230605095810_ensure_default_organization_spec.rb new file mode 100644 index 00000000000..97e9a4c54e7 --- /dev/null +++ b/spec/migrations/20230605095810_ensure_default_organization_spec.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +require 'spec_helper' + +require_migration! + +RSpec.describe EnsureDefaultOrganization, feature_category: :cell do + let(:organization) { table(:organizations) } + + it "creates default organization if needed" do + reversible_migration do |migration| + migration.before -> { + expect(organization.where(id: 1, name: 'Default', path: 'default')).to be_empty + } + migration.after -> { + expect(organization.where(id: 1, name: 'Default', path: 'default')).not_to be_empty + } + end + end + + context 'when default organization already exists' do + it "does not creates default organization if needed" do + reversible_migration do |migration| + migration.before -> { + organization.create!(id: 1, name: 'Default', path: 'default') + + expect(organization.where(id: 1, name: 'Default', path: 'default')).not_to be_empty + } + migration.after -> { + expect(organization.where(id: 1, name: 'Default', path: 'default')).not_to be_empty + } + end + end + end + + context 'when the path is in use by another organization' do + before do + organization.create!(id: 1000, name: 'Default', path: 'default') + end + + it "adds a random hash to the path" do + reversible_migration do |migration| + migration.after -> { + default_organization = organization.where(id: 1) + + expect(default_organization.first.path).to match(/default-\w{6}/) + } + end + end + end +end diff --git a/spec/models/organizations/organization_spec.rb b/spec/models/organizations/organization_spec.rb index cc2262634e3..4a75f352b6f 100644 --- a/spec/models/organizations/organization_spec.rb +++ b/spec/models/organizations/organization_spec.rb @@ -58,6 +58,12 @@ RSpec.describe Organizations::Organization, type: :model, feature_category: :cel end end + describe '.default_organization' do + it 'returns the default organization' do + expect(described_class.default_organization).to eq(default_organization) + end + end + describe '#id' do context 'when organization is default' do it 'has id 1' do