diff --git a/app/assets/javascripts/notes/components/comment_form.vue b/app/assets/javascripts/notes/components/comment_form.vue index 2ebebd76e1e..4e31fdcd4f0 100644 --- a/app/assets/javascripts/notes/components/comment_form.vue +++ b/app/assets/javascripts/notes/components/comment_form.vue @@ -1,14 +1,5 @@ + + diff --git a/app/models/packages/package.rb b/app/models/packages/package.rb index dcc3970c49f..34eae6ab5dc 100644 --- a/app/models/packages/package.rb +++ b/app/models/packages/package.rb @@ -293,6 +293,13 @@ class Packages::Package < ApplicationRecord ::Packages::Maven::Metadata::SyncWorker.perform_async(user.id, project.id, name) end + def create_build_infos!(build) + return unless build&.pipeline + + # TODO: use an upsert call when https://gitlab.com/gitlab-org/gitlab/-/issues/339093 is implemented + build_infos.find_or_create_by!(pipeline: build.pipeline) + end + private def composer_tag_version? diff --git a/app/services/packages/generic/create_package_file_service.rb b/app/services/packages/generic/create_package_file_service.rb index 42a191fb415..78c97000654 100644 --- a/app/services/packages/generic/create_package_file_service.rb +++ b/app/services/packages/generic/create_package_file_service.rb @@ -29,7 +29,8 @@ module Packages package.update_column(:status, params[:status]) if params[:status] && params[:status] != package.status - package.build_infos.safe_find_or_create_by!(pipeline: params[:build].pipeline) if params[:build].present? + package.create_build_infos!(params[:build]) + package end diff --git a/app/services/packages/maven/find_or_create_package_service.rb b/app/services/packages/maven/find_or_create_package_service.rb index c7ffd468864..b29adf4e11a 100644 --- a/app/services/packages/maven/find_or_create_package_service.rb +++ b/app/services/packages/maven/find_or_create_package_service.rb @@ -51,7 +51,7 @@ module Packages .execute end - package.build_infos.safe_find_or_create_by!(pipeline: params[:build].pipeline) if params[:build].present? + package.create_build_infos!(params[:build]) ServiceResponse.success(payload: { package: package }) end diff --git a/db/post_migrate/20210706112800_remove_cloud_license_enabled_from_application_settings.rb b/db/post_migrate/20210706112800_remove_cloud_license_enabled_from_application_settings.rb new file mode 100644 index 00000000000..7224e84c1b3 --- /dev/null +++ b/db/post_migrate/20210706112800_remove_cloud_license_enabled_from_application_settings.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +class RemoveCloudLicenseEnabledFromApplicationSettings < ActiveRecord::Migration[6.1] + include Gitlab::Database::MigrationHelpers + + disable_ddl_transaction! + + def up + with_lock_retries do + remove_column :application_settings, :cloud_license_enabled + end + end + + def down + with_lock_retries do + add_column :application_settings, :cloud_license_enabled, :boolean, null: false, default: false + end + end +end diff --git a/db/schema_migrations/20210706112800 b/db/schema_migrations/20210706112800 new file mode 100644 index 00000000000..f1f00867472 --- /dev/null +++ b/db/schema_migrations/20210706112800 @@ -0,0 +1 @@ +5dd1596d0d6e6f5aa39cbf8a65be294650bead7a099cf50917b438cf75529257 \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 88b7693b749..163ac643a3d 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -9598,7 +9598,6 @@ CREATE TABLE application_settings ( encrypted_cloud_license_auth_token text, encrypted_cloud_license_auth_token_iv text, secret_detection_revocation_token_types_url text, - cloud_license_enabled boolean DEFAULT false NOT NULL, disable_feed_token boolean DEFAULT false NOT NULL, personal_access_token_prefix text, rate_limiting_response_text text, diff --git a/doc/api/error_tracking.md b/doc/api/error_tracking.md index d81c8f15402..3fc44e22c42 100644 --- a/doc/api/error_tracking.md +++ b/doc/api/error_tracking.md @@ -96,12 +96,14 @@ Example response: { "id": 1, "active": true, - "public_key": "glet_aa77551d849c083f76d0bc545ed053a3" + "public_key": "glet_aa77551d849c083f76d0bc545ed053a3", + "sentry_dsn": "https://glet_aa77551d849c083f76d0bc545ed053a3@gitlab.example.com/api/v4/error_tracking/collector/5" }, { "id": 3, "active": true, - "public_key": "glet_0ff98b1d849c083f76d0bc545ed053a3" + "public_key": "glet_0ff98b1d849c083f76d0bc545ed053a3", + "sentry_dsn": "https://glet_0ff98b1d849c083f76d0bc545ed053a3@gitlab.example.com/api/v4/error_tracking/collector/5" } ] ``` @@ -129,7 +131,8 @@ Example response: { "id": 3, "active": true, - "public_key": "glet_0ff98b1d849c083f76d0bc545ed053a3" + "public_key": "glet_0ff98b1d849c083f76d0bc545ed053a3", + "sentry_dsn": "https://glet_0ff98b1d849c083f76d0bc545ed053a3@gitlab.example.com/api/v4/error_tracking/collector/5" } ``` diff --git a/doc/development/documentation/index.md b/doc/development/documentation/index.md index 59a1b8c7b99..c6d8695975e 100644 --- a/doc/development/documentation/index.md +++ b/doc/development/documentation/index.md @@ -405,76 +405,7 @@ on how the left-side navigation menu is built and updated. ## Previewing the changes live -NOTE: -To preview your changes to documentation locally, follow this -[development guide](https://gitlab.com/gitlab-org/gitlab-docs/blob/main/README.md#development-when-contributing-to-gitlab-documentation) or [these instructions for GDK](https://gitlab.com/gitlab-org/gitlab-development-kit/blob/main/doc/howto/gitlab_docs.md). - -The live preview is currently enabled for the following projects: - -- [`gitlab`](https://gitlab.com/gitlab-org/gitlab) -- [`omnibus-gitlab`](https://gitlab.com/gitlab-org/omnibus-gitlab) -- [`gitlab-runner`](https://gitlab.com/gitlab-org/gitlab-runner) - -If your merge request has docs changes, you can use the manual `review-docs-deploy` job -to deploy the docs review app for your merge request. - -![Manual trigger a docs build](img/manual_build_docs.png) - -You must push a branch to those repositories, as it doesn't work for forks. - -The `review-docs-deploy*` job: - -1. Triggers a cross project pipeline and build the docs site with your changes. - -In case the review app URL returns 404, this means that either the site is not -yet deployed, or something went wrong with the remote pipeline. Give it a few -minutes and it should appear online, otherwise you can check the status of the -remote pipeline from the link in the merge request's job output. -If the pipeline failed or got stuck, drop a line in the `#docs` chat channel. - -NOTE: -Someone with no merge rights to the GitLab projects (think of forks from -contributors) cannot run the manual job. In that case, you can -ask someone from the GitLab team who has the permissions to do that for you. - -### Troubleshooting review apps - -In case the review app URL returns 404, follow these steps to debug: - -1. **Did you follow the URL from the merge request widget?** If yes, then check if - the link is the same as the one in the job output. -1. **Did you follow the URL from the job output?** If yes, then it means that - either the site is not yet deployed or something went wrong with the remote - pipeline. Give it a few minutes and it should appear online, otherwise you - can check the status of the remote pipeline from the link in the job output. - If the pipeline failed or got stuck, drop a line in the `#docs` chat channel. - -### Technical aspects - -If you want to know the in-depth details, here's what's really happening: - -1. You manually run the `review-docs-deploy` job in a merge request. -1. The job runs the [`scripts/trigger-build`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/scripts/trigger-build) - script with the `docs deploy` flag, which triggers the "Triggered from `gitlab-org/gitlab` 'review-docs-deploy' job" - pipeline trigger in the `gitlab-org/gitlab-docs` project for the `$DOCS_BRANCH` (defaults to `main`). -1. The preview URL is shown both at the job output and in the merge request - widget. You also get the link to the remote pipeline. -1. In the `gitlab-org/gitlab-docs` project, the pipeline is created and it - [skips the test jobs](https://gitlab.com/gitlab-org/gitlab-docs/blob/8d5d5c750c602a835614b02f9db42ead1c4b2f5e/.gitlab-ci.yml#L50-55) - to lower the build time. -1. Once the docs site is built, the HTML files are uploaded as artifacts. -1. A specific runner tied only to the docs project, runs the Review App job - that downloads the artifacts and uses `rsync` to transfer the files over - to a location where NGINX serves them. - -The following GitLab features are used among others: - -- [Manual jobs](../../ci/jobs/job_control.md#create-a-job-that-must-be-run-manually) -- [Multi project pipelines](../../ci/pipelines/multi_project_pipelines.md) -- [Review Apps](../../ci/review_apps/index.md) -- [Artifacts](../../ci/yaml/index.md#artifacts) -- [Specific runner](../../ci/runners/runners_scope.md#prevent-a-specific-runner-from-being-enabled-for-other-projects) -- [Pipelines for merge requests](../../ci/pipelines/merge_request_pipelines.md) +See how you can use review apps to [preview your changes live](review_apps.md). ## Testing diff --git a/doc/development/documentation/review_apps.md b/doc/development/documentation/review_apps.md new file mode 100644 index 00000000000..a47a111fdf2 --- /dev/null +++ b/doc/development/documentation/review_apps.md @@ -0,0 +1,101 @@ +--- +stage: none +group: Documentation Guidelines +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +description: Learn how documentation review apps work. +--- + +# Documentation review apps + +If your merge request contains documentation changes, you can use a review app to preview +how they would look if they were deployed to the [GitLab Docs site](https://docs.gitlab.com). + +Review apps are enabled for the following projects: + +- [GitLab](https://gitlab.com/gitlab-org/gitlab) +- [Omnibus GitLab](https://gitlab.com/gitlab-org/omnibus-gitlab) +- [GitLab Runner](https://gitlab.com/gitlab-org/gitlab-runner) +- [GitLab Charts](https://gitlab.com/gitlab-org/charts/gitlab) + +Alternatively, check the [`gitlab-docs` development guide](https://gitlab.com/gitlab-org/gitlab-docs/blob/main/README.md#development-when-contributing-to-gitlab-documentation) +or [the GDK documentation](https://gitlab.com/gitlab-org/gitlab-development-kit/blob/main/doc/howto/gitlab_docs.md) +to render and preview the documentation locally. + +## How to trigger a review app + +If a merge request has documentation changes, use the `review-docs-deploy` manual job +to deploy the documentation review app for your merge request. + +![Manual trigger a documentation review app](img/manual_build_docs.png) + +The `review-docs-deploy*` job triggers a cross project pipeline and builds the +docs site with your changes. When the pipeline finishes, the review app URL +appears in the merge request widget. Use it to navigate to your changes. + +You must have the Developer role in the project. Users without the Developer role, such +as external contributors, cannot run the manual job. In that case, ask someone from +the GitLab team to run the job. + +## Technical aspects + +If you want to know the in-depth details, here's what's really happening: + +1. You manually run the `review-docs-deploy` job in a merge request. +1. The job runs the [`scripts/trigger-build`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/scripts/trigger-build) + script with the `docs deploy` flag, which triggers the "Triggered from `gitlab-org/gitlab` 'review-docs-deploy' job" + pipeline trigger in the `gitlab-org/gitlab-docs` project for the `$DOCS_BRANCH` (defaults to `main`). +1. The preview URL is shown both at the job output and in the merge request + widget. You also get the link to the remote pipeline. +1. In the `gitlab-org/gitlab-docs` project, the pipeline is created and it + [skips the test jobs](https://gitlab.com/gitlab-org/gitlab-docs/blob/8d5d5c750c602a835614b02f9db42ead1c4b2f5e/.gitlab-ci.yml#L50-55) + to lower the build time. +1. Once the docs site is built, the HTML files are uploaded as artifacts. +1. A specific runner tied only to the docs project, runs the Review App job + that downloads the artifacts and uses `rsync` to transfer the files over + to a location where NGINX serves them. + +The following GitLab features are used among others: + +- [Manual jobs](../../ci/jobs/job_control.md#create-a-job-that-must-be-run-manually) +- [Multi project pipelines](../../ci/pipelines/multi_project_pipelines.md) +- [Review Apps](../../ci/review_apps/index.md) +- [Artifacts](../../ci/yaml/index.md#artifacts) +- [Specific runner](../../ci/runners/runners_scope.md#prevent-a-specific-runner-from-being-enabled-for-other-projects) +- [Pipelines for merge requests](../../ci/pipelines/merge_request_pipelines.md) + +## Troubleshooting review apps + +### Review app returns a 404 error + +If the review app URL returns a 404 error, either the site is not +yet deployed, or something went wrong with the remote pipeline. You can: + +- Wait a few minutes and it should appear online. +- Check the manual job's log and verify the URL. If the URL is different, try the + one from the job log. +- Check the status of the remote pipeline from the link in the merge request's job output. + If the pipeline failed or got stuck, GitLab team members can ask for help in the `#docs` + chat channel. Contributors can ping a technical writer in the merge request. + +### Not enough disk space + +Sometimes the review app server is full and there is no more disk space. Each review +app takes about 570MB of disk space. + +A cron job to remove review apps older than 20 days runs hourly, +but the disk space still occasionally fills up. To manually free up more space, +a GitLab technical writing team member can: + +1. Navigate to the [`gitlab-docs` schedules page](https://gitlab.com/gitlab-org/gitlab-docs/-/pipeline_schedules). +1. Select the play button for the `Remove old review apps from review app server` + schedule. By default, this cleans up review apps older than 14 days. +1. Navigate to the [pipelines page](https://gitlab.com/gitlab-org/gitlab-docs/-/pipelines) + and start the manual job called `clean-pages`. + +If the job says no review apps were found in that period, edit the `CLEAN_REVIEW_APPS_DAYS` +variable in the schedule, and repeat the process above. Gradually decrease the variable +until the free disk space reaches an acceptable amount (for example, 3GB). +Remember to set it to 14 again when you're done. + +There's an issue to [migrate from the DigitalOcean server to GCP buckets](https://gitlab.com/gitlab-org/gitlab-docs/-/issues/735)), +which should solve the disk space problem. diff --git a/doc/user/permissions.md b/doc/user/permissions.md index 6e95361c3f4..6fbebe2733d 100644 --- a/doc/user/permissions.md +++ b/doc/user/permissions.md @@ -46,18 +46,18 @@ The following table lists project permissions available for each role: | Action | Guest | Reporter | Developer | Maintainer | Owner | |-------------------------------------------------------------------------------------------------------------------------|----------|----------|-----------|------------|-------| | [Analytics](analytics/index.md):
View issue analytics **(PREMIUM)** | ✓ | ✓ | ✓ | ✓ | ✓ | -| [Analytics](analytics/index.md):
View [merge request analytics](analytics/merge_request_analytics.md) **(PREMIUM)** | ✓ | ✓ | ✓ | ✓ | ✓ | +| [Analytics](analytics/index.md):
View [merge request analytics](analytics/merge_request_analytics.md) **(PREMIUM)** | ✓ | ✓ | ✓ | ✓ | ✓ | | [Analytics](analytics/index.md):
View value stream analytics | ✓ | ✓ | ✓ | ✓ | ✓ | | [Analytics](analytics/index.md):
View [DORA metrics](analytics/ci_cd_analytics.md) | | ✓ | ✓ | ✓ | ✓ | | [Analytics](analytics/index.md):
View [CI/CD analytics](analytics/ci_cd_analytics.md) | | ✓ | ✓ | ✓ | ✓ | -| [Analytics](analytics/index.md):
View [code review analytics](analytics/code_review_analytics.md) **(PREMIUM)** | | ✓ | ✓ | ✓ | ✓ | -| [Analytics](analytics/index.md):
View [repository analytics](analytics/repository_analytics.md) | | ✓ | ✓ | ✓ | ✓ | +| [Analytics](analytics/index.md):
View [code review analytics](analytics/code_review_analytics.md) **(PREMIUM)** | | ✓ | ✓ | ✓ | ✓ | +| [Analytics](analytics/index.md):
View [repository analytics](analytics/repository_analytics.md) | | ✓ | ✓ | ✓ | ✓ | | [Application security](application_security/index.md):
View licenses in [dependency list](application_security/dependency_list/index.md) **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ | | [Application security](application_security/index.md):
Create and run [on-demand DAST scans](application_security/dast/index.md#on-demand-scans) **(ULTIMATE)** | | | ✓ | ✓ | ✓ | | [Application security](application_security/index.md):
Manage [security policy](application_security/policies/index.md) **(ULTIMATE)** | | | ✓ | ✓ | ✓ | | [Application security](application_security/index.md):
View [dependency list](application_security/dependency_list/index.md) **(ULTIMATE)** | | | ✓ | ✓ | ✓ | | [Application security](application_security/index.md):
View [threats list](application_security/threat_monitoring/index.md#threat-monitoring) **(ULTIMATE)** | | | ✓ | ✓ | ✓ | -| [Application security](application_security/index.md):
Create a [CVE ID Request](application_security/cve_id_request.md) **(FREE SAAS)** | | | | ✓ | ✓ | +| [Application security](application_security/index.md):
Create a [CVE ID Request](application_security/cve_id_request.md) **(FREE SAAS)** | | | | ✓ | ✓ | | [Application security](application_security/index.md):
Create or assign [security policy project](application_security/policies/index.md) **(ULTIMATE)** | | | | | ✓ | | [CI/CD](../ci/README.md):
Download and browse job artifacts | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ | | [CI/CD](../ci/README.md):
View a job log | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ | @@ -74,13 +74,16 @@ The following table lists project permissions available for each role: | [CI/CD](../ci/README.md):
Run Web IDE's Interactive Web Terminals **(ULTIMATE ONLY)** | | | | ✓ | ✓ | | [CI/CD](../ci/README.md):
Use [environment terminals](../ci/environments/index.md#web-terminals) | | | | ✓ | ✓ | | [CI/CD](../ci/README.md):
Delete pipelines | | | | | ✓ | +| [Container Registry](packages/container_registry/index.md):
Create, edit, delete cleanup policies | | | ✓ | ✓ | ✓ | +| [Container Registry](packages/container_registry/index.md):
Remove a container registry image | | | ✓ | ✓ | ✓ | +| [Container Registry](packages/container_registry/index.md):
Update container registry | | | ✓ | ✓ | ✓ | | [Issues](project/issues/index.md):
Add Labels | ✓ (*16*) | ✓ | ✓ | ✓ | ✓ | | [Issues](project/issues/index.md):
Assign | ✓ (*16*) | ✓ | ✓ | ✓ | ✓ | | [Issues](project/issues/index.md):
Create | ✓ | ✓ | ✓ | ✓ | ✓ | | [Issues](project/issues/index.md):
Create [confidential issues](project/issues/confidential_issues.md) | ✓ | ✓ | ✓ | ✓ | ✓ | | [Issues](project/issues/index.md):
View [Design Management](project/issues/design_management.md) pages | ✓ | ✓ | ✓ | ✓ | ✓ | | [Issues](project/issues/index.md):
View related issues | ✓ | ✓ | ✓ | ✓ | ✓ | -| [Issues](project/issues/index.md):
Set weight | ✓ (*16*) | ✓ | ✓ | ✓ | ✓ | +| [Issues](project/issues/index.md):
Set weight | ✓ (*16*) | ✓ | ✓ | ✓ | ✓ | | [Issues](project/issues/index.md):
View [confidential issues](project/issues/confidential_issues.md) | (*2*) | ✓ | ✓ | ✓ | ✓ | | [Issues](project/issues/index.md):
Lock threads | | ✓ | ✓ | ✓ | ✓ | | [Issues](project/issues/index.md):
Manage related issues | | ✓ | ✓ | ✓ | ✓ | @@ -97,20 +100,28 @@ The following table lists project permissions available for each role: | [Merge requests](project/merge_requests/index.md):
Create | | | ✓ | ✓ | ✓ | | [Merge requests](project/merge_requests/index.md):
Add labels | | | ✓ | ✓ | ✓ | | [Merge requests](project/merge_requests/index.md):
Lock threads | | | ✓ | ✓ | ✓ | -| [Merge requests](project/merge_requests/index.md):
Manage or accept | | | ✓ | ✓ | ✓ | +| [Merge requests](project/merge_requests/index.md):
Manage or accept | | | ✓ | ✓ | ✓ | | [Merge requests](project/merge_requests/index.md):
Manage merge approval rules (project settings) | | | | ✓ | ✓ | | [Merge requests](project/merge_requests/index.md):
Delete | | | | | ✓ | +| [Package registry](packages/index.md):
Pull package | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ | +| [Package registry](packages/index.md):
Publish package | | | ✓ | ✓ | ✓ | +| [Package registry](packages/index.md):
Delete package | | | | ✓ | ✓ | +| [Project operations](../operations/index.md):
View [Error Tracking](../operations/error_tracking.md) list | | ✓ | ✓ | ✓ | ✓ | +| [Project operations](../operations/index.md):
Manage [Feature Flags](../operations/feature_flags.md) **(PREMIUM)** | | | ✓ | ✓ | ✓ | +| [Project operations](../operations/index.md):
Manage [Error Tracking](../operations/error_tracking.md) | | | | ✓ | ✓ | | [Projects](project/index.md):
Download project | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ | | [Projects](project/index.md):
Leave comments | ✓ | ✓ | ✓ | ✓ | ✓ | | [Projects](project/index.md):
Reposition comments on images (posted by any user) | ✓ (*10*) | ✓ (*10*) | ✓ (*10*) | ✓ | ✓ | | [Projects](project/index.md):
View Insights **(ULTIMATE)** | ✓ | ✓ | ✓ | ✓ | ✓ | +| [Projects](project/index.md):
View [releases](project/releases/index.md) | ✓ (*6*) | ✓ | ✓ | ✓ | ✓ | | [Projects](project/index.md):
View Requirements **(ULTIMATE)** | ✓ | ✓ | ✓ | ✓ | ✓ | | [Projects](project/index.md):
View [time tracking](project/time_tracking.md) reports | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ | | [Projects](project/index.md):
View [wiki](project/wiki/index.md) pages | ✓ | ✓ | ✓ | ✓ | ✓ | | [Projects](project/index.md):
Create [snippets](snippets.md) | | ✓ | ✓ | ✓ | ✓ | | [Projects](project/index.md):
Manage labels | | ✓ | ✓ | ✓ | ✓ | -| [Projects](project/index.md):
View project statistics | | ✓ | ✓ | ✓ | ✓ | +| [Projects](project/index.md):
View project statistics | | ✓ | ✓ | ✓ | ✓ | | [Projects](project/index.md):
Create, edit, delete [milestones](project/milestones/index.md). | | | ✓ | ✓ | ✓ | +| [Projects](project/index.md):
Create, edit, delete [releases](project/releases/index.md) | | | ✓ (*13*) | ✓ (*13*) | ✓ (*13*) | | [Projects](project/index.md):
Create, edit [wiki](project/wiki/index.md) pages | | | ✓ | ✓ | ✓ | | [Projects](project/index.md):
Enable Review Apps | | | ✓ | ✓ | ✓ | | [Projects](project/index.md):
View project [Audit Events](../administration/audit_events.md) | | | ✓ (*11*) | ✓ | ✓ | @@ -147,7 +158,7 @@ The following table lists project permissions available for each role: | [Repository](project/repository/index.md):
Enable or disable tag protection | | | | ✓ | ✓ | | [Repository](project/repository/index.md):
Manage [push rules](../push_rules/push_rules.md) | | | | ✓ | ✓ | | [Repository](project/repository/index.md):
Push to protected branches | | | | ✓ | ✓ | -| [Repository](project/repository/index.md):
Turn on or off protected branch push for developers | | | | ✓ | ✓ | +| [Repository](project/repository/index.md):
Turn on or off protected branch push for developers | | | | ✓ | ✓ | | [Repository](project/repository/index.md):
Remove fork relationship | | | | | ✓ | | [Repository](project/repository/index.md):
Force push to protected branches (*4*) | | | | | | | [Repository](project/repository/index.md):
Remove protected branches (*4*) | | | | | | @@ -162,7 +173,6 @@ The following table lists project permissions available for each role: | [Security dashboard](application_security/security_dashboard/index.md):
View vulnerability **(ULTIMATE)** | | | ✓ | ✓ | ✓ | | [Security dashboard](application_security/security_dashboard/index.md):
View vulnerability findings in [dependency list](application_security/dependency_list/index.md) **(ULTIMATE)** | | | ✓ | ✓ | ✓ | | Manage user-starred metrics dashboards (*7*) | ✓ | ✓ | ✓ | ✓ | ✓ | -| View [Releases](project/releases/index.md) | ✓ (*6*) | ✓ | ✓ | ✓ | ✓ | | View allowed and denied licenses **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ | | View GitLab Pages protected by [access control](project/pages/introduction.md#gitlab-pages-access-control) | ✓ | ✓ | ✓ | ✓ | ✓ | | View License Compliance reports **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ | @@ -172,24 +182,14 @@ The following table lists project permissions available for each role: | Create/edit requirements **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ | | Import/export requirements **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ | | Move [test case](../ci/test_cases/index.md) | | ✓ | ✓ | ✓ | ✓ | -| Pull [packages](packages/index.md) | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ | | Reopen [test case](../ci/test_cases/index.md) | | ✓ | ✓ | ✓ | ✓ | -| View Error Tracking list | | ✓ | ✓ | ✓ | ✓ | | View License list **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ | | View metrics dashboard annotations | | ✓ | ✓ | ✓ | ✓ | -| Create/edit/delete [releases](project/releases/index.md)| | | ✓ (*13*) | ✓ (*13*) | ✓ (*13*) | -| Create/edit/delete a Cleanup policy | | | ✓ | ✓ | ✓ | | Create/edit/delete metrics dashboard annotations | | | ✓ | ✓ | ✓ | -| Manage Feature Flags **(PREMIUM)** | | | ✓ | ✓ | ✓ | -| Publish [packages](packages/index.md) | | | ✓ | ✓ | ✓ | | Read Terraform state | | | ✓ | ✓ | ✓ | -| Remove a container registry image | | | ✓ | ✓ | ✓ | -| Update a container registry | | | ✓ | ✓ | ✓ | | View Pods logs | | | ✓ | ✓ | ✓ | | Configure project hooks | | | | ✓ | ✓ | -| Delete [packages](packages/index.md) | | | | ✓ | ✓ | | Manage clusters | | | | ✓ | ✓ | -| Manage Error Tracking | | | | ✓ | ✓ | | Manage GitLab Pages | | | | ✓ | ✓ | | Manage GitLab Pages domains and certificates | | | | ✓ | ✓ | | Manage license policy **(ULTIMATE)** | | | | ✓ | ✓ | diff --git a/doc/user/project/settings/index.md b/doc/user/project/settings/index.md index 999ffa2db47..58d902f5b40 100644 --- a/doc/user/project/settings/index.md +++ b/doc/user/project/settings/index.md @@ -87,59 +87,64 @@ Example `.compliance-gitlab-ci.yml` # Allows compliance team to control the ordering and interweaving of stages/jobs. # Stages without jobs defined will remain hidden. stages: -- pre-compliance -- build -- test -- pre-deploy-compliance -- deploy -- post-compliance + - pre-compliance + - build + - test + - pre-deploy-compliance + - deploy + - post-compliance -variables: # can be overriden by a developer's local .gitlab-ci.yml +variables: # Can be overridden by setting a job-specific variable in project's local .gitlab-ci.yml FOO: sast -sast: # none of these attributes can be overriden by a developer's local .gitlab-ci.yml +sast: # None of these attributes can be overridden by a project's local .gitlab-ci.yml variables: FOO: sast image: ruby:2.6 stage: pre-compliance rules: - - when: always + - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push" + when: never + - when: always # or when: on_success allow_failure: false before_script: - - "# No before scripts." + - "# No before scripts." script: - - echo "running $FOO" + - echo "running $FOO" after_script: - - "# No after scripts." + - "# No after scripts." sanity check: image: ruby:2.6 stage: pre-deploy-compliance rules: - - when: always + - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push" + when: never + - when: always # or when: on_success allow_failure: false before_script: - - "# No before scripts." + - "# No before scripts." script: - - echo "running $FOO" + - echo "running $FOO" after_script: - - "# No after scripts." - + - "# No after scripts." audit trail: image: ruby:2.6 stage: post-compliance rules: - - when: always + - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push" + when: never + - when: always # or when: on_success allow_failure: false before_script: - - "# No before scripts." + - "# No before scripts." script: - - echo "running $FOO" + - echo "running $FOO" after_script: - - "# No after scripts." + - "# No after scripts." -include: # Execute individual project's configuration +include: # Execute individual project's configuration (if project contains .gitlab-ci.yml) project: '$CI_PROJECT_PATH' file: '$CI_CONFIG_PATH' ref: '$CI_COMMIT_REF_NAME' # Must be defined or MR pipelines always use the use default branch. @@ -187,7 +192,7 @@ section. You can now change the [Project visibility](../../../public_access/public_access.md). If you set **Project Visibility** to public, you can limit access to some features to **Only Project Members**. In addition, you can select the option to -[Allow users to request access](../members/index.md#prevent-users-from-requesting-access-to-a-project). +[Allow users to request access](../members/index.md#request-access-to-a-project). Use the switches to enable or disable the following features: @@ -350,7 +355,7 @@ to transfer a project. You can transfer an existing project into a [group](../../group/index.md) if: -- You have at least the Maintainer** role in that group. +- You have at least **Maintainer** [role](../../permissions.md#project-members-permissions) in that group. - You're at least an **Owner** of the project to be transferred. - The group to which the project is being transferred to must allow creation of new projects. @@ -457,7 +462,7 @@ To do so: 1. Confirm the action by typing the project's path as instructed. NOTE: -Only project Owners have the [permissions](../../permissions.md#project-members-permissions) +Only project owners have the [permissions](../../permissions.md#project-members-permissions) to remove a fork relationship. ## Monitor settings diff --git a/lib/api/entities/error_tracking.rb b/lib/api/entities/error_tracking.rb index 06728c4b21f..b55cba05ea0 100644 --- a/lib/api/entities/error_tracking.rb +++ b/lib/api/entities/error_tracking.rb @@ -15,6 +15,7 @@ module API expose :id expose :active expose :public_key + expose :sentry_dsn end end end diff --git a/qa/qa/page/component/note.rb b/qa/qa/page/component/note.rb index 67583f71bf3..7c733a231f1 100644 --- a/qa/qa/page/component/note.rb +++ b/qa/qa/page/component/note.rb @@ -14,8 +14,11 @@ module QA end base.view 'app/assets/javascripts/notes/components/comment_form.vue' do - element :comment_button element :comment_field + end + + base.view 'app/assets/javascripts/notes/components/comment_type_dropdown.vue' do + element :comment_button element :discussion_menu_item end diff --git a/spec/factories/packages.rb b/spec/factories/packages.rb index d4993cc765a..b04b7e691fe 100644 --- a/spec/factories/packages.rb +++ b/spec/factories/packages.rb @@ -354,4 +354,12 @@ FactoryBot.define do package sequence(:name) { |n| "tag-#{n}"} end + + factory :packages_build_info, class: 'Packages::BuildInfo' do + package + + trait :with_pipeline do + association :pipeline, factory: [:ci_pipeline, :with_job] + end + end end diff --git a/spec/frontend/notes/components/comment_form_spec.js b/spec/frontend/notes/components/comment_form_spec.js index bb79b43205b..c3a51c51de0 100644 --- a/spec/frontend/notes/components/comment_form_spec.js +++ b/spec/frontend/notes/components/comment_form_spec.js @@ -10,6 +10,7 @@ import { refreshUserMergeRequestCounts } from '~/commons/nav/user_merge_requests import createFlash from '~/flash'; import axios from '~/lib/utils/axios_utils'; import CommentForm from '~/notes/components/comment_form.vue'; +import CommentTypeDropdown from '~/notes/components/comment_type_dropdown.vue'; import * as constants from '~/notes/constants'; import eventHub from '~/notes/event_hub'; import { COMMENT_FORM } from '~/notes/i18n'; @@ -33,8 +34,8 @@ describe('issue_comment_form component', () => { const findAddToReviewButton = () => wrapper.findByTestId('add-to-review-button'); const findAddCommentNowButton = () => wrapper.findByTestId('add-comment-now-button'); const findConfidentialNoteCheckbox = () => wrapper.findByTestId('confidential-note-checkbox'); - const findCommentGlDropdown = () => wrapper.findByTestId('comment-button'); - const findCommentButton = () => findCommentGlDropdown().find('button'); + const findCommentTypeDropdown = () => wrapper.findComponent(CommentTypeDropdown); + const findCommentButton = () => findCommentTypeDropdown().find('button'); const findErrorAlerts = () => wrapper.findAllComponents(GlAlert).wrappers; async function clickCommentButton({ waitForComponent = true, waitForNetwork = true } = {}) { @@ -381,7 +382,7 @@ describe('issue_comment_form component', () => { it('should render comment button as disabled', () => { mountComponent(); - expect(findCommentGlDropdown().props('disabled')).toBe(true); + expect(findCommentTypeDropdown().props('disabled')).toBe(true); }); it('should enable comment button if it has note', async () => { @@ -389,7 +390,7 @@ describe('issue_comment_form component', () => { await wrapper.setData({ note: 'Foo' }); - expect(findCommentGlDropdown().props('disabled')).toBe(false); + expect(findCommentTypeDropdown().props('disabled')).toBe(false); }); it('should update buttons texts when it has note', () => { @@ -624,7 +625,7 @@ describe('issue_comment_form component', () => { it('when no drafts exist, should not render', () => { mountComponent(); - expect(findCommentGlDropdown().exists()).toBe(true); + expect(findCommentTypeDropdown().exists()).toBe(true); expect(findAddToReviewButton().exists()).toBe(false); expect(findAddCommentNowButton().exists()).toBe(false); }); @@ -637,7 +638,7 @@ describe('issue_comment_form component', () => { it('should render', () => { mountComponent(); - expect(findCommentGlDropdown().exists()).toBe(false); + expect(findCommentTypeDropdown().exists()).toBe(false); expect(findAddToReviewButton().exists()).toBe(true); expect(findAddCommentNowButton().exists()).toBe(true); }); diff --git a/spec/frontend/notes/components/comment_type_dropdown_spec.js b/spec/frontend/notes/components/comment_type_dropdown_spec.js new file mode 100644 index 00000000000..5e1cb813369 --- /dev/null +++ b/spec/frontend/notes/components/comment_type_dropdown_spec.js @@ -0,0 +1,64 @@ +import { GlDropdown, GlDropdownItem } from '@gitlab/ui'; +import { mount } from '@vue/test-utils'; +import { extendedWrapper } from 'helpers/vue_test_utils_helper'; +import CommentTypeDropdown from '~/notes/components/comment_type_dropdown.vue'; +import * as constants from '~/notes/constants'; +import { COMMENT_FORM } from '~/notes/i18n'; + +describe('CommentTypeDropdown component', () => { + let wrapper; + + const findCommentGlDropdown = () => wrapper.findComponent(GlDropdown); + const findCommentDropdownOption = () => wrapper.findAllComponents(GlDropdownItem).at(0); + const findDiscussionDropdownOption = () => wrapper.findAllComponents(GlDropdownItem).at(1); + + const mountComponent = ({ props = {} } = {}) => { + wrapper = extendedWrapper( + mount(CommentTypeDropdown, { + propsData: { + noteableDisplayName: 'issue', + noteType: constants.COMMENT, + ...props, + }, + }), + ); + }; + + afterEach(() => { + wrapper.destroy(); + }); + + it('Should label action button "Comment" and correct dropdown item checked when selected', () => { + mountComponent({ props: { noteType: constants.COMMENT } }); + + expect(findCommentGlDropdown().props()).toMatchObject({ text: COMMENT_FORM.comment }); + expect(findCommentDropdownOption().props()).toMatchObject({ isChecked: true }); + expect(findDiscussionDropdownOption().props()).toMatchObject({ isChecked: false }); + }); + + it('Should label action button "Start Thread" and correct dropdown item option checked when selected', () => { + mountComponent({ props: { noteType: constants.DISCUSSION } }); + + expect(findCommentGlDropdown().props()).toMatchObject({ text: COMMENT_FORM.startThread }); + expect(findCommentDropdownOption().props()).toMatchObject({ isChecked: false }); + expect(findDiscussionDropdownOption().props()).toMatchObject({ isChecked: true }); + }); + + it('Should emit `change` event when clicking on an alternate dropdown option', () => { + mountComponent({ props: { noteType: constants.DISCUSSION } }); + + findCommentDropdownOption().vm.$emit('click'); + findDiscussionDropdownOption().vm.$emit('click'); + + expect(wrapper.emitted('change')[0]).toEqual([constants.COMMENT]); + expect(wrapper.emitted('change').length).toEqual(1); + }); + + it('Should emit `click` event when clicking on the action button', () => { + mountComponent({ props: { noteType: constants.DISCUSSION } }); + + findCommentGlDropdown().vm.$emit('click'); + + expect(wrapper.emitted('click').length > 0).toBe(true); + }); +}); diff --git a/spec/models/packages/package_spec.rb b/spec/models/packages/package_spec.rb index 4d4d4ad4fa9..99e5769fc1f 100644 --- a/spec/models/packages/package_spec.rb +++ b/spec/models/packages/package_spec.rb @@ -1165,4 +1165,47 @@ RSpec.describe Packages::Package, type: :model do it_behaves_like 'not enqueuing a sync worker job' end end + + describe '#create_build_infos!' do + let_it_be(:package) { create(:package) } + let_it_be(:pipeline) { create(:ci_pipeline) } + + let(:build) { double(pipeline: pipeline) } + + subject { package.create_build_infos!(build) } + + context 'with a valid build' do + it 'creates a build info' do + expect { subject }.to change { ::Packages::BuildInfo.count }.by(1) + + last_build = ::Packages::BuildInfo.last + expect(last_build.package).to eq(package) + expect(last_build.pipeline).to eq(pipeline) + end + + context 'with an already existing build info' do + let_it_be(:build_info) { create(:packages_build_info, package: package, pipeline: pipeline) } + + it 'does not create a build info' do + expect { subject }.not_to change { ::Packages::BuildInfo.count } + end + end + end + + context 'with a nil build' do + let(:build) { nil } + + it 'does not create a build info' do + expect { subject }.not_to change { ::Packages::BuildInfo.count } + end + end + + context 'with a build without a pipeline' do + let(:build) { double(pipeline: nil) } + + it 'does not create a build info' do + expect { subject }.not_to change { ::Packages::BuildInfo.count } + end + end + end end diff --git a/spec/requests/api/error_tracking_client_keys_spec.rb b/spec/requests/api/error_tracking_client_keys_spec.rb index 67377b3140b..886ec5ade3d 100644 --- a/spec/requests/api/error_tracking_client_keys_spec.rb +++ b/spec/requests/api/error_tracking_client_keys_spec.rb @@ -63,6 +63,7 @@ RSpec.describe API::ErrorTrackingClientKeys do expect(json_response['id']).to eq(new_key.id) expect(json_response['public_key']).to eq(new_key.public_key) + expect(json_response['sentry_dsn']).to eq(new_key.sentry_dsn) end end end diff --git a/spec/services/packages/generic/create_package_file_service_spec.rb b/spec/services/packages/generic/create_package_file_service_spec.rb index 1c9eb53cfc7..9d6784b7721 100644 --- a/spec/services/packages/generic/create_package_file_service_spec.rb +++ b/spec/services/packages/generic/create_package_file_service_spec.rb @@ -105,6 +105,37 @@ RSpec.describe Packages::Generic::CreatePackageFileService do it { expect { execute_service }.to change { project.package_files.count }.by(1) } end end + + context 'with multiple files for the same package and the same pipeline' do + let(:file_2_params) { params.merge(file_name: 'myfile.tar.gz.2', file: file2) } + let(:file_3_params) { params.merge(file_name: 'myfile.tar.gz.3', file: file3) } + + let(:temp_file2) { Tempfile.new("test2") } + let(:temp_file3) { Tempfile.new("test3") } + + let(:file2) { UploadedFile.new(temp_file2.path, sha256: sha256) } + let(:file3) { UploadedFile.new(temp_file3.path, sha256: sha256) } + + before do + FileUtils.touch(temp_file2) + FileUtils.touch(temp_file3) + expect(::Packages::Generic::FindOrCreatePackageService).to receive(:new).with(project, user, package_params).and_return(package_service).twice + expect(package_service).to receive(:execute).and_return(package).twice + end + + after do + FileUtils.rm_f(temp_file2) + FileUtils.rm_f(temp_file3) + end + + it 'creates the build info only once' do + expect do + described_class.new(project, user, params).execute + described_class.new(project, user, file_2_params).execute + described_class.new(project, user, file_3_params).execute + end.to change { package.build_infos.count }.by(1) + end + end end end end diff --git a/spec/services/packages/maven/find_or_create_package_service_spec.rb b/spec/services/packages/maven/find_or_create_package_service_spec.rb index d8b48af0121..59f5677f526 100644 --- a/spec/services/packages/maven/find_or_create_package_service_spec.rb +++ b/spec/services/packages/maven/find_or_create_package_service_spec.rb @@ -98,6 +98,19 @@ RSpec.describe Packages::Maven::FindOrCreatePackageService do it 'creates a build_info' do expect { subject }.to change { Packages::BuildInfo.count }.by(1) end + + context 'with multiple files for the same package and the same pipeline' do + let(:file_2_params) { params.merge(file_name: 'test2.jar') } + let(:file_3_params) { params.merge(file_name: 'test3.jar') } + + it 'creates a single build info' do + expect do + described_class.new(project, user, params).execute + described_class.new(project, user, file_2_params).execute + described_class.new(project, user, file_3_params).execute + end.to change { ::Packages::BuildInfo.count }.by(1) + end + end end context 'when package duplicates are not allowed' do