Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-11-02 09:10:53 +00:00
parent 03c509e17b
commit 4483783083
19 changed files with 555 additions and 471 deletions

View File

@ -17,6 +17,7 @@ export default {
'section',
{
attrs: {
class: 'mr-section-container mr-widget-workflow',
role: 'region',
'aria-label': __('Merge request reports'),
},

View File

@ -563,6 +563,7 @@ export default {
:mr="mr"
:service="service"
/>
<extensions-container :mr="mr" />
<div class="mr-section-container mr-widget-workflow">
<div v-if="hasAlerts" class="gl-overflow-hidden mr-widget-alert-container">
<mr-widget-alert-message
@ -589,8 +590,6 @@ export default {
</mr-widget-alert-message>
</div>
<extensions-container :mr="mr" />
<widget-container v-if="mr" :mr="mr" />
<grouped-codequality-reports-app

View File

@ -14,12 +14,11 @@ metadata:
name: private_token
in: query
tags:
- name: metadata
description: Operations related to metadata of the GitLab instance
# Keep in alphabetical order
- name: access_requests
description: Operations related to access requests
- name: merge_requests
description: Operations related to merge requests
- name: cluster_agents
description: Operations related to the GitLab agent for Kubernetes
- name: deploy_keys
description: Operations related to deploy keys
- name: deploy_tokens
@ -34,7 +33,11 @@ metadata:
description: Operations related to managing Flipper-based feature flags
- name: freeze_periods
description: Operations related to deploy freeze periods
- name: merge_requests
description: Operations related to merge requests
- name: metadata
description: Operations related to metadata of the GitLab instance
- name: release_links
description: Operations related to release assets (links)
- name: cluster_agents
description: Operations related to the GitLab agent for Kubernetes
- name: suggestions
description: Operations related to suggestions

View File

@ -4,96 +4,96 @@ group: Pipeline Insights
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
# Review Apps **(FREE)**
# Review apps **(FREE)**
Review Apps is a collaboration tool that assists with providing an environment to showcase product changes.
Review apps are a collaboration tool that provide an environment to showcase product changes.
NOTE:
If you have a Kubernetes cluster, you can automate this feature in your applications
by using [Auto DevOps](../../topics/autodevops/index.md).
Review Apps:
Review apps:
- Provide an automatic live preview of changes made in a feature branch by spinning up a dynamic environment for your merge requests.
- Allow designers and product managers to see your changes without needing to check out your branch and run your changes in a sandbox environment.
- Are fully integrated with the [GitLab DevOps LifeCycle](../../index.md#the-entire-devops-lifecycle).
- Allow you to deploy your changes wherever you want.
![Review Apps Workflow](img/continuous-delivery-review-apps.svg)
![review apps workflow](img/continuous-delivery-review-apps.svg)
In the previous example:
- A Review App is built every time a commit is pushed to `topic branch`.
- A review app is built every time a commit is pushed to `topic branch`.
- The reviewer fails two reviews before passing the third review.
- After the review passes, `topic branch` is merged into the default branch, where it's deployed to staging.
- After its approval in staging, the changes that were merged into the default branch are deployed to production.
## How Review Apps work
## How review apps work
A Review App is a mapping of a branch with an [environment](../environments/index.md).
Access to the Review App is made available as a link on the [merge request](../../user/project/merge_requests/index.md) relevant to the branch.
A review app is a mapping of a branch with an [environment](../environments/index.md).
Access to the review app is made available as a link on the [merge request](../../user/project/merge_requests/index.md) relevant to the branch.
The following is an example of a merge request with an environment set dynamically.
![Review App in merge request](img/review_apps_preview_in_mr.png)
![review app in merge request](img/review_apps_preview_in_mr.png)
In this example, a branch was:
- Successfully built.
- Deployed under a dynamic environment that can be reached by selecting **View app**.
After adding Review Apps to your workflow, you follow the branched Git flow. That is:
After adding review apps to your workflow, you follow the branched Git flow. That is:
1. Push a branch and let the runner deploy the Review App based on the `script` definition of the dynamic environment job.
1. Push a branch and let the runner deploy the review app based on the `script` definition of the dynamic environment job.
1. Wait for the runner to build and deploy your web application.
1. To view the changes live, select the link in the merge request related to the branch.
## Configuring Review Apps
## Configuring review apps
Review Apps are built on [dynamic environments](../environments/index.md#create-a-dynamic-environment), which allow you to dynamically create a new environment for each branch.
Review apps are built on [dynamic environments](../environments/index.md#create-a-dynamic-environment), which allow you to dynamically create a new environment for each branch.
The process of configuring Review Apps is as follows:
The process of configuring review apps is as follows:
1. Set up the infrastructure to host and deploy the Review Apps (check the [examples](#review-apps-examples) below).
1. Set up the infrastructure to host and deploy the review apps (check the [examples](#review-apps-examples) below).
1. [Install](https://docs.gitlab.com/runner/install/) and [configure](https://docs.gitlab.com/runner/commands/) a runner to do deployment.
1. Set up a job in `.gitlab-ci.yml` that uses the [predefined CI/CD variable](../variables/index.md) `${CI_COMMIT_REF_SLUG}`
to create dynamic environments and restrict it to run only on branches.
Alternatively, you can get a YAML template for this job by [enabling review apps](#enable-review-apps-button) for your project.
1. Optionally, set a job that [manually stops](../environments/index.md#stop-an-environment) the Review Apps.
Alternatively, you can get a YAML template for this job by [enabling review apps](#enable-review-app-button) for your project.
1. Optionally, set a job that [manually stops](../environments/index.md#stop-an-environment) the review apps.
### Enable Review Apps button
### Enable review app button
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118844) in GitLab 12.8.
When configuring Review Apps for a project, you add a new job to the `.gitlab-ci.yml` file,
When configuring review apps for a project, you add a new job to the `.gitlab-ci.yml` file,
as mentioned above. To facilitate this, and if you are using Kubernetes, you can select
**Enable Review Apps** and GitLab prompts you with a template code block that
**Enable review app** and GitLab prompts you with a template code block that
you can copy and paste into `.gitlab-ci.yml` as a starting point.
Prerequisite:
- You need at least the Developer role for the project.
To use the Review Apps template:
To use the review apps template:
1. On the top bar, select **Main menu > Projects** and find the project you want to create a Review App job for.
1. On the top bar, select **Main menu > Projects** and find the project you want to create a review app job for.
1. On the left sidebar, select **Deployments > Environments**.
1. Select **Enable Review Apps**.
1. Select **Enable review app**.
1. Copy the provided code snippet and paste it into your
`.gitlab-ci.yml` file:
![Enable Review Apps modal](img/enable_review_app_v12_8.png)
![enable review apps modal](img/enable_review_app_v12_8.png)
You can edit this template as needed.
## Review Apps auto-stop
## Review apps auto-stop
See how to [configure Review Apps environments to expire and auto-stop](../environments/index.md#stop-an-environment-after-a-certain-time-period)
See how to [configure review apps environments to expire and auto-stop](../environments/index.md#stop-an-environment-after-a-certain-time-period)
after a given period of time.
## Review Apps examples
## Review apps examples
The following are example projects that demonstrate Review App configuration:
The following are example projects that demonstrate review app configuration:
| Project | Configuration file |
|-------------------------------------------------------------------------|--------------------|
@ -104,17 +104,17 @@ The following are example projects that demonstrate Review App configuration:
| [`https://about.gitlab.com/`](https://gitlab.com/gitlab-com/www-gitlab-com/) | [`.gitlab-ci.yml`](https://gitlab.com/gitlab-com/www-gitlab-com/-/blob/6ffcdc3cb9af2abed490cbe5b7417df3e83cd76c/.gitlab-ci.yml#L332) |
| [GitLab Insights](https://gitlab.com/gitlab-org/gitlab-insights/) | [`.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab-insights/-/blob/9e63f44ac2a5a4defc965d0d61d411a768e20546/.gitlab-ci.yml#L234) |
Other examples of Review Apps:
Other examples of review apps:
- <i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
[Cloud Native Development with GitLab](https://www.youtube.com/watch?v=jfIyQEwrocw).
- [Review Apps for Android](https://about.gitlab.com/blog/2020/05/06/how-to-create-review-apps-for-android-with-gitlab-fastlane-and-appetize-dot-io/).
- [Review apps for Android](https://about.gitlab.com/blog/2020/05/06/how-to-create-review-apps-for-android-with-gitlab-fastlane-and-appetize-dot-io/).
## Route Maps
Route Maps allows you to go directly from source files
to public pages on the [environment](../environments/index.md) defined for
Review Apps.
review apps.
Once set up, the review app link in the merge request
widget can take you directly to the pages changed, making it easier
@ -209,7 +209,7 @@ With Visual Reviews, members of any team (Product, Design, Quality, and so on) c
### Using Visual Reviews
After Visual Reviews has been [configured](#configure-review-apps-for-visual-reviews) for the
Review App, the Visual Reviews feedback form is overlaid on the right side of every page.
review app, the Visual Reviews feedback form is overlaid on the right side of every page.
![Visual review feedback form](img/toolbar_feedback_form_v13_5.png)
@ -227,9 +227,9 @@ To use the feedback form to make a comment in the merge request:
<i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
To see Visual reviews in action, see the [Visual Reviews Walk through](https://youtu.be/1_tvWTlPfM4).
### Configure Review Apps for Visual Reviews
### Configure review apps for Visual Reviews
The feedback form is served through a script you add to pages in your Review App.
The feedback form is served through a script you add to pages in your review app.
It should be added to the `<head>` of your application and
consists of some project and merge request specific values. Here's how it
looks for a project with code hosted in a project on GitLab.com:

View File

@ -936,6 +936,10 @@ Instead of:
- Select **Create user** or **Save changes** if you created a new user or
edited an existing one respectively.
## review app
Use lowercase for **review app**.
## roles
Do not use **roles** and [**permissions**](#permissions) interchangeably. Each user is assigned a role. Each role includes a set of permissions.

View File

@ -4,9 +4,9 @@ group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
# Review Apps
# Using review apps in the development of GitLab
Review Apps are deployed using the `start-review-app-pipeline` job which triggers a child pipeline containing a series of jobs to perform the various tasks needed to deploy a Review App.
Review apps are deployed using the `start-review-app-pipeline` job which triggers a child pipeline containing a series of jobs to perform the various tasks needed to deploy a review app.
![start-review-app-pipeline job](img/review-app-parent-pipeline.png)
@ -21,7 +21,7 @@ For any of the following scenarios, the `start-review-app-pipeline` job would be
- for scheduled pipelines
- the MR has the `pipeline:run-review-app` label set
## QA runs on Review Apps
## QA runs on review apps
On every [pipeline](https://gitlab.com/gitlab-org/gitlab/pipelines/125315730) in the `qa` stage (which comes after the
`review` stage), the `review-qa-smoke` and `review-qa-reliable` jobs are automatically started. The `review-qa-smoke` runs
@ -34,7 +34,7 @@ You can also manually start the `review-qa-all`: it runs the full QA suite.
After the end-to-end test runs have finished, [Allure reports](https://github.com/allure-framework/allure2) are generated and published by
the `allure-report-qa-smoke`, `allure-report-qa-reliable`, and `allure-report-qa-all` jobs. A comment with links to the reports are added to the merge request.
Errors can be found in the `gitlab-review-apps` Sentry project and [filterable by Review App URL](https://sentry.gitlab.net/gitlab/gitlab-review-apps/?query=url%3A%22https%3A%2F%2Fgitlab-review-require-ve-u92nn2.gitlab-review.app%2F%22) or [commit SHA](https://sentry.gitlab.net/gitlab/gitlab-review-apps/releases/6095b501da7/all-events/).
Errors can be found in the `gitlab-review-apps` Sentry project and [filterable by review app URL](https://sentry.gitlab.net/gitlab/gitlab-review-apps/?query=url%3A%22https%3A%2F%2Fgitlab-review-require-ve-u92nn2.gitlab-review.app%2F%22) or [commit SHA](https://sentry.gitlab.net/gitlab/gitlab-review-apps/releases/6095b501da7/all-events/).
### Bypass failed review app deployment to merge a broken `master` fix
@ -47,7 +47,7 @@ On every [pipeline](https://gitlab.com/gitlab-org/gitlab/pipelines/125315730) in
browser performance testing using a
[Sitespeed.io Container](../../ci/testing/browser_performance_testing.md).
## Sample Data for Review Apps
## Sample Data for review apps
Upon deployment of a review app, project data is created from the [`sample-gitlab-project`](https://gitlab.com/gitlab-org/sample-data-templates/sample-gitlab-project) template project. This aims to provide projects with prepopulated resources to facilitate manual and exploratory testing.
@ -55,16 +55,16 @@ The sample projects will be created in the `root` user namespace and can be acce
## How to
### Redeploy Review App from a clean slate
### Redeploy review app from a clean slate
To reset Review App and redeploy from a clean slate, do the following:
To reset review app and redeploy from a clean slate, do the following:
1. Run `review-stop` job.
1. Re-deploy by running or retrying `review-deploy` job.
Doing this will remove all existing data from a previously deployed Review App.
Doing this will remove all existing data from a previously deployed review app.
### Get access to the GCP Review Apps cluster
### Get access to the GCP review apps cluster
You need to [open an access request (internal link)](https://gitlab.com/gitlab-com/access-requests/-/issues/new)
for the `gcp-review-apps-dev` GCP group and role.
@ -74,7 +74,7 @@ This grants you the following permissions for:
- [Retrieving pod logs](#dig-into-a-pods-logs). Granted by [Viewer (`roles/viewer`)](https://cloud.google.com/iam/docs/understanding-roles#kubernetes-engine-roles).
- [Running a Rails console](#run-a-rails-console). Granted by [Kubernetes Engine Developer (`roles/container.pods.exec`)](https://cloud.google.com/iam/docs/understanding-roles#kubernetes-engine-roles).
### Log into my Review App
### Log into my review app
For GitLab Team Members only. If you want to sign in to the review app, review
the GitLab handbook information for the [shared 1Password account](https://about.gitlab.com/handbook/security/#1password-for-teams).
@ -82,23 +82,23 @@ the GitLab handbook information for the [shared 1Password account](https://about
- The default username is `root`.
- The password can be found in the 1Password login item named `GitLab EE Review App`.
### Enable a feature flag for my Review App
### Enable a feature flag for my review app
1. Open your Review App and sign in as documented above.
1. Open your review app and sign in as documented above.
1. Create a personal access token.
1. Enable the feature flag using the [Feature flag API](../../api/features.md).
### Find my Review App slug
### Find my review app slug
1. Open the `review-deploy` job.
1. Look for `** Deploying review-*`.
1. For instance for `** Deploying review-1234-abc-defg... **`,
your Review App slug would be `review-1234-abc-defg` in this case.
your review app slug would be `review-1234-abc-defg` in this case.
### Run a Rails console
1. Make sure you [have access to the cluster](#get-access-to-the-gcp-review-apps-cluster) and the `container.pods.exec` permission first.
1. [Filter Workloads by your Review App slug](https://console.cloud.google.com/kubernetes/workload?project=gitlab-review-apps). For example, `review-qa-raise-e-12chm0`.
1. [Filter Workloads by your review app slug](https://console.cloud.google.com/kubernetes/workload?project=gitlab-review-apps). For example, `review-qa-raise-e-12chm0`.
1. Find and open the `toolbox` Deployment. For example, `review-qa-raise-e-12chm0-toolbox`.
1. Select the Pod in the "Managed pods" section. For example, `review-qa-raise-e-12chm0-toolbox-d5455cc8-2lsvz`.
1. Select the `KUBECTL` dropdown list, then `Exec` -> `toolbox`.
@ -111,7 +111,7 @@ the GitLab handbook information for the [shared 1Password account](https://about
### Dig into a Pod's logs
1. Make sure you [have access to the cluster](#get-access-to-the-gcp-review-apps-cluster) and the `container.pods.getLogs` permission first.
1. [Filter Workloads by your Review App slug](https://console.cloud.google.com/kubernetes/workload?project=gitlab-review-apps). For example, `review-qa-raise-e-12chm0`.
1. [Filter Workloads by your review app slug](https://console.cloud.google.com/kubernetes/workload?project=gitlab-review-apps). For example, `review-qa-raise-e-12chm0`.
1. Find and open the `migrations` Deployment. For example, `review-qa-raise-e-12chm0-migrations.1`.
1. Select the Pod in the "Managed pods" section. For example, `review-qa-raise-e-12chm0-migrations.1-nqwtx`.
1. Select `Container logs`.
@ -149,11 +149,11 @@ subgraph "2. gitlab `review-prepare` stage"
end
subgraph "3. gitlab `review` stage"
C["review-deploy<br><br>Helm deploys the Review App using the Cloud<br/>Native images built by the CNG-mirror pipeline.<br><br>Cloud Native images are deployed to the `review-apps`<br>Kubernetes (GKE) cluster, in the GCP `gitlab-review-apps` project."]
C["review-deploy<br><br>Helm deploys the review app using the Cloud<br/>Native images built by the CNG-mirror pipeline.<br><br>Cloud Native images are deployed to the `review-apps`<br>Kubernetes (GKE) cluster, in the GCP `gitlab-review-apps` project."]
end
subgraph "4. gitlab `qa` stage"
E[review-qa-smoke, review-qa-reliable<br><br>gitlab-qa runs the smoke and reliable suites against the Review App.]
E[review-qa-smoke, review-qa-reliable<br><br>gitlab-qa runs the smoke and reliable suites against the review app.]
end
subgraph "CNG-mirror pipeline"
@ -180,10 +180,10 @@ subgraph "CNG-mirror pipeline"
- We use the [`CNG-mirror`](https://gitlab.com/gitlab-org/build/CNG-mirror) project so that the `CNG`, (Cloud
Native GitLab), project's registry is not overloaded with a lot of transient Docker images.
1. Once `review-build-cng` is done, the [`review-deploy`](https://gitlab.com/gitlab-org/gitlab/-/jobs/467724810) job
deploys the Review App using [the official GitLab Helm chart](https://gitlab.com/gitlab-org/charts/gitlab/) to
deploys the review app using [the official GitLab Helm chart](https://gitlab.com/gitlab-org/charts/gitlab/) to
the [`review-apps`](https://console.cloud.google.com/kubernetes/clusters/details/us-central1-b/review-apps?project=gitlab-review-apps)
Kubernetes cluster on GCP.
- The actual scripts used to deploy the Review App can be found at
- The actual scripts used to deploy the review app can be found at
[`scripts/review_apps/review-apps.sh`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/scripts/review_apps/review-apps.sh).
- These scripts are basically
[our official Auto DevOps scripts](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml) where the
@ -192,11 +192,11 @@ subgraph "CNG-mirror pipeline"
- Since we're using [the official GitLab Helm chart](https://gitlab.com/gitlab-org/charts/gitlab/), this means
you get a dedicated environment for your branch that's very close to what
it would look in production.
- Each review app is deployed to its own Kubernetes namespace. The namespace is based on the Review App slug that is
- Each review app is deployed to its own Kubernetes namespace. The namespace is based on the review app slug that is
unique to each branch.
1. Once the [`review-deploy`](https://gitlab.com/gitlab-org/gitlab/-/jobs/467724810) job succeeds, you should be able to
use your Review App thanks to the direct link to it from the MR widget. To log
into the Review App, see "Log into my Review App?" below.
use your review app thanks to the direct link to it from the MR widget. To log
into the review app, see "Log into my review app?" below.
**Additional notes:**
@ -213,23 +213,23 @@ subgraph "CNG-mirror pipeline"
`#quality` channel and/or create a ~Quality ~"type::bug" issue with a link to your
merge request.
- The manual `review-stop` can be used to
stop a Review App manually, and is also started by GitLab once a merge
stop a review app manually, and is also started by GitLab once a merge
request's branch is deleted after being merged.
- The Kubernetes cluster is connected to the `gitlab` projects using the
[GitLab Kubernetes integration](../../user/infrastructure/clusters/index.md). This basically
allows to have a link to the Review App directly from the merge request widget.
allows to have a link to the review app directly from the merge request widget.
### Auto-stopping of Review Apps
### Auto-stopping of review apps
Review Apps are automatically stopped 2 days after the last deployment thanks to
Review apps are automatically stopped 2 days after the last deployment thanks to
the [Environment auto-stop](../../ci/environments/index.md#stop-an-environment-after-a-certain-time-period) feature.
If you need your Review App to stay up for a longer time, you can
If you need your review app to stay up for a longer time, you can
[pin its environment](../../ci/environments/index.md#override-a-deployments-scheduled-stop-time) or retry the
`review-deploy` job to update the "latest deployed at" time.
The `review-cleanup` job that automatically runs in scheduled
pipelines stops stale Review Apps after 5 days,
pipelines stops stale review apps after 5 days,
deletes their environment after 6 days, and cleans up any dangling Helm releases
and Kubernetes resources after 7 days.
@ -246,13 +246,13 @@ The Helm version used is defined in the
[`registry.gitlab.com/gitlab-org/gitlab-build-images:gitlab-helm3.5-kubectl1.17` image](https://gitlab.com/gitlab-org/gitlab-build-images/-/blob/master/Dockerfile.gitlab-helm3.5-kubectl1.17#L6)
used by the `review-deploy` and `review-stop` jobs.
## Diagnosing unhealthy Review App releases
## Diagnosing unhealthy review app releases
If [Review App Stability](https://app.periscopedata.com/app/gitlab/496118/Engineering-Productivity-Sandbox?widget=6690556&udv=785399)
If [review app stability](https://app.periscopedata.com/app/gitlab/496118/Engineering-Productivity-Sandbox?widget=6690556&udv=785399)
dips this may be a signal that the `review-apps` cluster is unhealthy.
Leading indicators may be health check failures leading to restarts or majority failure for Review App deployments.
Leading indicators may be health check failures leading to restarts or majority failure for review app deployments.
The [Review Apps Overview dashboard](https://console.cloud.google.com/monitoring/classic/dashboards/6798952013815386466?project=gitlab-review-apps&timeDomain=1d)
The [review apps Overview dashboard](https://console.cloud.google.com/monitoring/classic/dashboards/6798952013815386466?project=gitlab-review-apps&timeDomain=1d)
aids in identifying load spikes on the cluster, and if nodes are problematic or the entire cluster is trending towards unhealthy.
See the [review apps page of the Engineering Productivity Runbook](https://gitlab.com/gitlab-org/quality/engineering-productivity/team/-/blob/main/runbook/review-apps.md) for troubleshooting review app releases.
@ -273,7 +273,7 @@ find a way to limit it to only us.**
## Other resources
- [Review Apps integration for CE/EE (presentation)](https://docs.google.com/presentation/d/1QPLr6FO4LduROU8pQIPkX1yfGvD13GEJIBOenqoKxR8/edit?usp=sharing)
- [Review apps integration for CE/EE (presentation)](https://docs.google.com/presentation/d/1QPLr6FO4LduROU8pQIPkX1yfGvD13GEJIBOenqoKxR8/edit?usp=sharing)
- [Stability issues](https://gitlab.com/gitlab-org/quality/team-tasks/-/issues/212)
### Helpful command line tools

View File

@ -6,7 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# CI/CD analytics **(FREE)**
Use the CI/CD analytics page to view pipeline success rates and duration, and the history of [DORA metrics](index.md#devops-research-and-assessment-dora-key-metrics) over time.
Use the CI/CD analytics page to view pipeline success rates and duration, and the history of DORA metrics over time.
## Pipeline success and duration charts
@ -35,7 +35,7 @@ To view CI/CD analytics:
1. On the top bar, select **Main menu > Projects** and find your project.
1. On the left sidebar, select **Analytics > CI/CD Analytics**.
## View deployment frequency chart **(ULTIMATE)**
## View DORA deployment frequency chart **(ULTIMATE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/275991) in GitLab 13.8.
@ -44,7 +44,7 @@ frequency to the `production` environment. The environment must be part of the
[production deployment tier](../../ci/environments/index.md#deployment-tier-of-environments)
for its deployment information to appear on the graphs.
Deployment frequency is one of the four [DORA metrics](index.md#devops-research-and-assessment-dora-key-metrics) that DevOps teams use for measuring excellence in software delivery.
Deployment frequency is one of the four DORA metrics that DevOps teams use for measuring excellence in software delivery.
The deployment frequency chart is available for groups and projects.
@ -56,7 +56,7 @@ To view the deployment frequency chart:
![Deployment frequency](img/deployment_frequency_charts_v13_12.png)
## View lead time for changes chart **(ULTIMATE)**
## View DORA lead time for changes chart **(ULTIMATE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/250329) in GitLab 13.11.
@ -68,7 +68,7 @@ merge requests to be deployed to a production environment. This chart is availab
- For time periods in which no merge requests were deployed, the charts render a
red, dashed line.
Lead time for changes is one of the four [DORA metrics](index.md#devops-research-and-assessment-dora-key-metrics) that DevOps teams use for measuring excellence in software delivery.
Lead time for changes is one of the four DORA metrics that DevOps teams use for measuring excellence in software delivery.
To view the lead time for changes chart:
@ -78,13 +78,13 @@ To view the lead time for changes chart:
![Lead time](img/lead_time_chart_v13_11.png)
## View time to restore service chart **(ULTIMATE)**
## View DORA time to restore service chart **(ULTIMATE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/356959) in GitLab 15.1
The time to restore service chart shows information about the median time an incident was open in a production environment. This chart is available for groups and projects.
Time to restore service is one of the four [DORA metrics](index.md#devops-research-and-assessment-dora-key-metrics) that DevOps teams use for measuring excellence in software delivery.
Time to restore service is one of the four DORA metrics that DevOps teams use for measuring excellence in software delivery.
To view the time to restore service chart:
@ -94,13 +94,13 @@ To view the time to restore service chart:
![Lead time](img/time_to_restore_service_charts_v15_1.png)
## View change failure rate chart **(ULTIMATE)**
## View DORA change failure rate chart **(ULTIMATE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/357072) in GitLab 15.2
The change failure rate chart shows information about the percentage of deployments that cause an incident in a production environment. This chart is available for groups and projects.
Change failure rate is one of the four [DORA metrics](index.md#devops-research-and-assessment-dora-key-metrics) that DevOps teams use for measuring excellence in software delivery.
Change failure rate is one of the four DORA metrics that DevOps teams use for measuring excellence in software delivery.
To view the change failure rate chart:

View File

@ -0,0 +1,105 @@
---
stage: Plan
group: Optimize
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
# DevOps Research and Assessment (DORA) metrics **(ULTIMATE)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/275991) in GitLab 13.7.
> - [Added support](https://gitlab.com/gitlab-org/gitlab/-/issues/291746) for lead time for changes in GitLab 13.10.
The [DevOps Research and Assessment (DORA)](https://cloud.google.com/blog/products/devops-sre/using-the-four-keys-to-measure-your-devops-performance)
team has identified four metrics that measure DevOps performance.
Using these metrics helps improve DevOps efficiency and communicate performance to business stakeholders, which can accelerate business results.
DORA includes four key metrics, divided into two core areas of DevOps:
- [Deployment Frequency](#deployment-frequency) and [Lead Time for Change](#lead-time-for-changes) measure team velocity.
- [Change Failure Rate](#change-failure-rate) and [Time to Restore Service](#time-to-restore-service) measure stability.
For software leaders, tracking velocity alongside quality metrics ensures they're not sacrificing quality for speed.
## DORA Metrics dashboard in Value Stream Analytics
The four DORA metrics are available out-of-the-box in the [Value Stream Analytics (VSA) overview dashboard](../group/value_stream_analytics/index.md#view-dora-metrics-and-key-metrics-for-a-group).
This helps you visualize the engineering work in the context of end-to-end value delivery.
The One DevOps Platform [Value Stream Management](https://gitlab.com/gitlab-org/gitlab/-/value_stream_analytics) provides end-to-end visibility to the entire software delivery lifecycle.
This enables teams and managers to understand all aspects of productivity, quality, and delivery, without the ["toolchain tax"](https://about.gitlab.com/solutions/value-stream-management/).
## Deployment frequency
Deployment frequency is the frequency of successful deployments to production (hourly, daily, weekly, monthly, or yearly).
This measures how often you deliver value to end users. A higher deployment frequency means you can
get feedback sooner and iterate faster to deliver improvements and features. GitLab measures this as the number of
deployments to a production environment in the given time period.
Deployment frequency displays in several charts:
- [Group-level value stream analytics](../group/value_stream_analytics/index.md)
- [Project-level value stream analytics](value_stream_analytics.md)
- [CI/CD analytics](ci_cd_analytics.md)
To retrieve metrics for deployment frequency, use the [GraphQL](../../api/graphql/reference/index.md) or the [REST](../../api/dora/metrics.md) APIs.
## Lead time for changes
Lead time for changes measures the time to deliver a feature once it has been developed,
as described in [Measuring DevOps Performance](https://devops.com/measuring-devops-performance/).
Lead time for changes displays in several charts:
- [Group-level value stream analytics](../group/value_stream_analytics/index.md)
- [Project-level value stream analytics](value_stream_analytics.md)
- [CI/CD analytics](ci_cd_analytics.md)
To retrieve metrics for lead time for changes, use the [GraphQL](../../api/graphql/reference/index.md) or the [REST](../../api/dora/metrics.md) APIs.
## Time to restore service
Time to restore service measures how long it takes an organization to recover from a failure in production.
GitLab measures this as the average time required to close the incidents
in the given time period. This assumes:
- All incidents are related to a production environment.
- Incidents and deployments have a strictly one-to-one relationship. An incident is related to only
one production deployment, and any production deployment is related to no more than one incident).
Time to restore service displays in several charts:
- [Group-level value stream analytics](../group/value_stream_analytics/index.md)
- [Project-level value stream analytics](value_stream_analytics.md)
- [CI/CD analytics](ci_cd_analytics.md)
To retrieve metrics for time to restore service, use the [GraphQL](../../api/graphql/reference/index.md) or the [REST](../../api/dora/metrics.md) APIs.
## Change failure rate
Change failure rate measures the percentage of deployments that cause a failure in production. GitLab measures this as the number
of incidents divided by the number of deployments to a
production environment in the given time period. This assumes:
- All incidents are related to a production environment.
- Incidents and deployments have a strictly one-to-one relationship. An incident is related to only
one production deployment, and any production deployment is related to no
more than one incident.
To retrieve metrics for change failure rate, use the [GraphQL](../../api/graphql/reference/index.md) or the [REST](../../api/dora/metrics.md) APIs.
### Insights: Custom DORA reporting
Custom charts to visualize DORA data with Insights YAML-based reports.
With this new visualization, software leaders can track metrics improvements, understand patterns in their metrics trends, and compare performance between groups and projects.
### Supported DORA metrics in GitLab
| Metric | Level | API | UI chart | Comments |
|---------------------------|-------------------|-----------------------------------------------------|------------------------|----------|
| `deployment_frequency` | Project | [GitLab 13.7 and later](../../api/dora/metrics.md) | GitLab 14.8 and later | The previous API endpoint was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/323713) in 13.10. |
| `deployment_frequency` | Group | [GitLab 13.10 and later](../../api/dora/metrics.md) | GitLab 13.12 and later | |
| `lead_time_for_changes` | Project | [GitLab 13.10 and later](../../api/dora/metrics.md) | GitLab 13.11 and later | Unit in seconds. Aggregation method is median. |
| `lead_time_for_changes` | Group | [GitLab 13.10 and later](../../api/dora/metrics.md) | GitLab 14.0 and later | Unit in seconds. Aggregation method is median. |
| `time_to_restore_service` | Project and group | [GitLab 14.9 and later](../../api/dora/metrics.md) | GitLab 15.1 and later | Unit in days. Aggregation method is median. |
| `change_failure_rate` | Project and group | [GitLab 14.10 and later](../../api/dora/metrics.md) | GitLab 15.2 and later | Percentage of deployments. |

View File

@ -34,7 +34,7 @@ GitLab provides several analytics features at the group level. Some of these fea
You can use GitLab to review analytics at the project level. Some of these features require you to use a higher tier than GitLab Free.
- [Application Security](../application_security/security_dashboard/index.md)
- [CI/CD](ci_cd_analytics.md)
- [CI/CD & DORA](ci_cd_analytics.md)
- [Code Review](code_review_analytics.md)
- [Insights](../project/insights/index.md)
- [Issue](../group/issues_analytics/index.md)
@ -51,93 +51,6 @@ The following analytics features are available for users to create personalized
Be sure to review the documentation page for this feature for GitLab tier requirements.
## DevOps Research and Assessment (DORA) key metrics **(ULTIMATE)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/275991) in GitLab 13.7.
> - [Added support](https://gitlab.com/gitlab-org/gitlab/-/issues/291746) for lead time for changes in GitLab 13.10.
The [DevOps Research and Assessment (DORA)](https://cloud.google.com/blog/products/devops-sre/using-the-four-keys-to-measure-your-devops-performance)
team developed several key metrics that you can use as performance indicators for software development
teams.
### Deployment frequency
Deployment frequency is the frequency of successful deployments to production (hourly, daily, weekly, monthly, or yearly).
This measures how often you deliver value to end users. A higher deployment frequency means you can
get feedback sooner and iterate faster to deliver improvements and features. GitLab measures this as the number of
deployments to a production environment in the given time period.
Deployment frequency displays in several charts:
- [Group-level value stream analytics](../group/value_stream_analytics/index.md)
- [Project-level value stream analytics](value_stream_analytics.md)
- [CI/CD analytics](ci_cd_analytics.md)
To retrieve metrics for deployment frequency, use the [GraphQL](../../api/graphql/reference/index.md) or the [REST](../../api/dora/metrics.md) APIs.
### Lead time for changes
DORA Lead time for changes measures the time to successfully deliver a feature into production.
This metric reflects the efficiency of CI/CD pipelines.
In GitLab, Lead time for changes calculates the median time it takes for a merge request to get merged into production.
We measure "FROM code committed TO code successfully running in production" without adding the "coding_time" to the calculation.
Over time, the lead time for changes should decrease, while your team's performance should increase.
Lead time for changes displays in several charts:
- [Group-level value stream analytics](../group/value_stream_analytics/index.md)
- [Project-level value stream analytics](value_stream_analytics.md)
- [CI/CD analytics](ci_cd_analytics.md)
To retrieve metrics for lead time for changes, use the [GraphQL](../../api/graphql/reference/index.md) or the [REST](../../api/dora/metrics.md) APIs.
- The definition of lead time for change can vary widely, which often creates confusion within the industry.
- "Lead time for changes" is not the same as "Lead time". In the value stream, "Lead time" measures the time it takes for work on issue to move from the moment it's requested (Issue created) to the time it's fulfilled and delivered (Issue closed).
### Time to restore service
Time to restore service measures how long it takes an organization to recover from a failure in production.
GitLab measures this as the average time required to close the incidents
in the given time period. This assumes:
- All incidents are related to a production environment.
- Incidents and deployments have a strictly one-to-one relationship. An incident is related to only
one production deployment, and any production deployment is related to no more than one incident).
Time to restore service displays in several charts:
- [Group-level value stream analytics](../group/value_stream_analytics/index.md)
- [Project-level value stream analytics](value_stream_analytics.md)
- [CI/CD analytics](ci_cd_analytics.md)
To retrieve metrics for time to restore service, use the [GraphQL](../../api/graphql/reference/index.md) or the [REST](../../api/dora/metrics.md) APIs.
### Change failure rate
Change failure rate measures the percentage of deployments that cause a failure in production. GitLab measures this as the number
of incidents divided by the number of deployments to a
production environment in the given time period. This assumes:
- All incidents are related to a production environment.
- Incidents and deployments have a strictly one-to-one relationship. An incident is related to only
one production deployment, and any production deployment is related to no
more than one incident.
To retrieve metrics for change failure rate, use the [GraphQL](../../api/graphql/reference/index.md) or the [REST](../../api/dora/metrics.md) APIs.
### Supported DORA metrics in GitLab
| Metric | Level | API | UI chart | Comments |
|---------------------------|-------------------|-----------------------------------------------------|------------------------|----------|
| `deployment_frequency` | Project | [GitLab 13.7 and later](../../api/dora/metrics.md) | GitLab 14.8 and later | The previous API endpoint was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/323713) in 13.10. |
| `deployment_frequency` | Group | [GitLab 13.10 and later](../../api/dora/metrics.md) | GitLab 13.12 and later | |
| `lead_time_for_changes` | Project | [GitLab 13.10 and later](../../api/dora/metrics.md) | GitLab 13.11 and later | Unit in seconds. Aggregation method is median. |
| `lead_time_for_changes` | Group | [GitLab 13.10 and later](../../api/dora/metrics.md) | GitLab 14.0 and later | Unit in seconds. Aggregation method is median. |
| `time_to_restore_service` | Project and group | [GitLab 14.9 and later](../../api/dora/metrics.md) | GitLab 15.1 and later | Unit in days. Aggregation method is median. |
| `change_failure_rate` | Project and group | [GitLab 14.10 and later](../../api/dora/metrics.md) | GitLab 15.2 and later | Percentage of deployments. |
## Definitions
We use the following terms to describe GitLab analytics:

View File

@ -169,6 +169,7 @@ module API
# Mount endpoints to include in the OpenAPI V2 documentation here
namespace do
# Keep in alphabetical order
mount ::API::AccessRequests
mount ::API::Appearance
mount ::API::BulkImports
@ -182,14 +183,16 @@ module API
mount ::API::FeatureFlagsUserLists
mount ::API::Features
mount ::API::FreezePeriods
mount ::API::Metadata
mount ::API::MergeRequestDiffs
mount ::API::UserCounts
mount ::API::Metadata
mount ::API::ProjectRepositoryStorageMoves
mount ::API::Release::Links
mount ::API::ResourceAccessTokens
mount ::API::SnippetRepositoryStorageMoves
mount ::API::Statistics
mount ::API::Suggestions
mount ::API::Tags
mount ::API::UserCounts
add_open_api_documentation!
end
@ -299,7 +302,6 @@ module API
mount ::API::Releases
mount ::API::RemoteMirrors
mount ::API::Repositories
mount ::API::ResourceAccessTokens
mount ::API::ResourceLabelEvents
mount ::API::ResourceMilestoneEvents
mount ::API::ResourceStateEvents
@ -311,7 +313,6 @@ module API
mount ::API::Snippets
mount ::API::Submodules
mount ::API::Subscriptions
mount ::API::Suggestions
mount ::API::SystemHooks
mount ::API::Tags
mount ::API::Templates

View File

@ -3,9 +3,16 @@
module API
module Entities
class PersonalAccessToken < Grape::Entity
expose :id, :name, :revoked, :created_at, :scopes, :user_id, :last_used_at
expose :active?, as: :active
expose :expires_at do |personal_access_token|
expose :id, documentation: { type: 'string', example: 2 }
expose :name, documentation: { type: 'string', example: 'John Doe' }
expose :revoked, documentation: { type: 'boolean' }
expose :created_at, documentation: { type: 'dateTime' }
expose :scopes, documentation: { type: 'array', example: ['api'] }
expose :user_id, documentation: { type: 'string', example: 3 }
expose :last_used_at, documentation: { type: 'dateTime', example: '2020-08-31T15:53:00.073Z' }
expose :active?, as: :active, documentation: { type: 'boolean' }
expose :expires_at, documentation:
{ type: 'dateTime', example: '2020-08-31T15:53:00.073Z' } do |personal_access_token|
personal_access_token.expires_at ? personal_access_token.expires_at.strftime("%Y-%m-%d") : nil
end
end

View File

@ -3,7 +3,12 @@
module API
module Entities
class ResourceAccessToken < Entities::PersonalAccessToken
expose :access_level do |token, options|
expose :access_level,
documentation: { type: 'integer',
example: 40,
description: 'Access level. Valid values are 10 (Guest), 20 (Reporter), 30 (Developer) \
, 40 (Maintainer), and 50 (Owner). Defaults to 40.',
values: [10, 20, 30, 40, 50] } do |token, options|
options[:resource].member(token.user).access_level
end
end

View File

@ -14,9 +14,12 @@ module API
resource source_type.pluralize, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
desc 'Get list of all access tokens for the specified resource' do
detail 'This feature was introduced in GitLab 13.9.'
is_array true
tags ["#{source_type}_access_tokens"]
success Entities::ResourceAccessToken
end
params do
requires :id, type: String, desc: "The #{source_type} ID"
requires :id, types: [String, Integer], desc: "ID or URL-encoded path of the #{source_type}"
end
get ":id/access_tokens" do
resource = find_source(source_type, params[:id])
@ -31,9 +34,11 @@ module API
desc 'Get an access token for the specified resource by ID' do
detail 'This feature was introduced in GitLab 14.10.'
tags ["#{source_type}_access_tokens"]
success Entities::ResourceAccessToken
end
params do
requires :id, type: String, desc: "The #{source_type} ID"
requires :id, types: [String, Integer], desc: "ID or URL-encoded path of the #{source_type}"
requires :token_id, type: String, desc: "The ID of the token"
end
get ":id/access_tokens/:token_id" do
@ -53,6 +58,12 @@ module API
desc 'Revoke a resource access token' do
detail 'This feature was introduced in GitLab 13.9.'
tags ["#{source_type}_access_tokens"]
success code: 204
failure [
{ code: 400, message: 'Bad Request' },
{ code: 404, message: 'Not found' }
]
end
params do
requires :id, type: String, desc: "The #{source_type} ID"
@ -77,13 +88,21 @@ module API
desc 'Create a resource access token' do
detail 'This feature was introduced in GitLab 13.9.'
tags ["#{source_type}_access_tokens"]
success Entities::ResourceAccessTokenWithToken
end
params do
requires :id, type: String, desc: "The #{source_type} ID"
requires :name, type: String, desc: "Resource access token name"
requires :scopes, type: Array[String], values: ::Gitlab::Auth.resource_bot_scopes.map(&:to_s), desc: "The permissions of the token"
optional :access_level, type: Integer, values: ALLOWED_RESOURCE_ACCESS_LEVELS.values, default: Gitlab::Access::MAINTAINER, desc: "The access level of the token in the #{source_type}"
optional :expires_at, type: Date, desc: "The expiration date of the token"
requires :id, type: String, desc: "The #{source_type} ID", documentation: { example: 2 }
requires :name, type: String, desc: "Resource access token name", documentation: { example: 'test' }
requires :scopes, type: Array[String], values: ::Gitlab::Auth.resource_bot_scopes.map(&:to_s),
desc: "The permissions of the token",
documentation: { example: %w[api read_repository] }
optional :access_level, type: Integer,
values: ALLOWED_RESOURCE_ACCESS_LEVELS.values,
default: Gitlab::Access::MAINTAINER,
desc: "The access level of the token in the #{source_type}",
documentation: { example: 40 }
optional :expires_at, type: Date, desc: "The expiration date of the token", documentation: { example: '"2021-01-31' }
end
post ':id/access_tokens' do
resource = find_source(source_type, params[:id])

View File

@ -9,9 +9,10 @@ module API
resource :suggestions do
desc 'Apply suggestion patch in the Merge Request it was created' do
success Entities::Suggestion
tags %w[suggestions]
end
params do
requires :id, type: String, desc: 'The suggestion ID'
requires :id, type: Integer, desc: 'The ID of the suggestion'
optional :commit_message, type: String, desc: "A custom commit message to use instead of the default generated message or the project's default message"
end
put ':id/apply', urgency: :low do
@ -26,9 +27,10 @@ module API
desc 'Apply multiple suggestion patches in the Merge Request where they were created' do
success Entities::Suggestion
tags %w[suggestions]
end
params do
requires :ids, type: Array[Integer], coerce_with: ::API::Validations::Types::CommaSeparatedToIntegerArray.coerce, desc: "An array of suggestion ID's"
requires :ids, type: Array[Integer], coerce_with: ::API::Validations::Types::CommaSeparatedToIntegerArray.coerce, desc: "An array of the suggestion IDs"
optional :commit_message, type: String, desc: "A custom commit message to use instead of the default generated message or the project's default message"
end
put 'batch_apply', urgency: :low do

View File

@ -1,227 +1,194 @@
# frozen_string_literal: true
module QA
# Spec uses real github.com, which means outage of github.com can actually block deployment
# Keep spec in reliable bucket but don't run in blocking pipelines
#
# https://github.com/gitlab-qa-github/import-test <- project under test
RSpec.describe 'Manage', :github, :reliable, :skip_live_env, :requires_admin, product_group: :import do
describe 'Project import', issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/353583' do
let!(:api_client) { Runtime::API::Client.as_admin }
let!(:group) { Resource::Group.fabricate_via_api! { |resource| resource.api_client = api_client } }
let!(:user) do
Resource::User.fabricate_via_api! do |resource|
resource.api_client = api_client
resource.hard_delete_on_api_removal = true
#
RSpec.describe 'Manage', product_group: :import do
describe 'GitHub import', :reliable do
include_context 'with github import'
context 'when imported via api' do
it 'imports project', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347670' do
imported_project.reload! # import the project
expect { imported_project.project_import_status[:import_status] }.to eventually_eq('finished')
.within(max_duration: 240, sleep_interval: 1)
aggregate_failures do
verify_status_data
verify_repository_import
verify_protected_branches_import
verify_commits_import
verify_labels_import
verify_issues_import
verify_milestones_import
verify_wikis_import
verify_merge_requests_import
verify_release_import
end
end
end
let!(:user_api_client) { Runtime::API::Client.new(user: user) }
let(:imported_project) do
Resource::ProjectImportedFromGithub.fabricate_via_api! do |project|
project.name = 'imported-project'
project.group = group
project.github_personal_access_token = Runtime::Env.github_access_token
project.github_repository_path = 'gitlab-qa-github/import-test'
project.api_client = user_api_client
project.issue_events_import = true
project.full_notes_import = true
def verify_status_data
stats = imported_project.project_import_status.dig(:stats, :imported)
expect(stats).to include(
issue: 1,
label: 9,
milestone: 1,
note: 3,
pull_request: 1,
pull_request_review: 1,
diff_note: 1,
release: 1
)
end
end
before do
group.add_member(user, Resource::Members::AccessLevel::MAINTAINER)
end
after do
user.remove_via_api!
end
it 'imports Github repo via api', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347670' do
imported_project.reload! # import the project
expect { imported_project.project_import_status[:import_status] }.to eventually_eq('finished')
.within(max_duration: 240, sleep_interval: 1)
aggregate_failures do
verify_status_data
verify_repository_import
verify_protected_branches_import
verify_commits_import
verify_labels_import
verify_issues_import
verify_milestones_import
verify_wikis_import
verify_merge_requests_import
verify_release_import
def verify_repository_import
expect(imported_project.reload!.description).to eq('Project for github import test')
expect(imported_project.api_response[:import_error]).to be_nil
end
end
def verify_status_data
stats = imported_project.project_import_status.dig(:stats, :imported)
expect(stats).to include(
issue: 1,
label: 9,
milestone: 1,
note: 3,
pull_request: 1,
pull_request_review: 1,
diff_note: 1,
release: 1
)
end
def verify_repository_import
expect(imported_project.reload!.description).to eq('Project for github import test')
expect(imported_project.api_response[:import_error]).to be_nil
end
def verify_protected_branches_import
branches = imported_project.protected_branches.map do |branch|
branch.slice(:name, :allow_force_push, :code_owner_approval_required)
def verify_protected_branches_import
branches = imported_project.protected_branches.map do |branch|
branch.slice(:name, :allow_force_push, :code_owner_approval_required)
end
expect(branches.first).to include(
{
name: 'main'
# TODO: Add validation once https://gitlab.com/groups/gitlab-org/-/epics/8585 is closed
# At the moment both options are always set to false regardless of state in github
# allow_force_push: true,
# code_owner_approval_required: true
}
)
end
expect(branches.first).to include(
{
name: 'main'
# TODO: Add validation once https://gitlab.com/groups/gitlab-org/-/epics/8585 is closed
# At the moment both options are always set to false regardless of state in github
# allow_force_push: true,
# code_owner_approval_required: true
}
)
# GitHub branch protection rule "Require signed commits" is mapped to the
# "Reject unsigned commits" push rule
expect(imported_project.push_rules[:reject_unsigned_commits]).to be_truthy
end
def verify_commits_import
expect(imported_project.commits.length).to eq(2)
end
def verify_commits_import
expect(imported_project.commits.length).to eq(2)
end
def verify_labels_import
labels = imported_project.labels.map { |label| label.slice(:name, :color) }
def verify_labels_import
labels = imported_project.labels.map { |label| label.slice(:name, :color) }
expect(labels).to include(
{ name: 'bug', color: '#d73a4a' },
{ name: 'documentation', color: '#0075ca' },
{ name: 'duplicate', color: '#cfd3d7' },
{ name: 'enhancement', color: '#a2eeef' },
{ name: 'good first issue', color: '#7057ff' },
{ name: 'help wanted', color: '#008672' },
{ name: 'invalid', color: '#e4e669' },
{ name: 'question', color: '#d876e3' },
{ name: 'wontfix', color: '#ffffff' }
)
end
expect(labels).to include(
{ name: 'bug', color: '#d73a4a' },
{ name: 'documentation', color: '#0075ca' },
{ name: 'duplicate', color: '#cfd3d7' },
{ name: 'enhancement', color: '#a2eeef' },
{ name: 'good first issue', color: '#7057ff' },
{ name: 'help wanted', color: '#008672' },
{ name: 'invalid', color: '#e4e669' },
{ name: 'question', color: '#d876e3' },
{ name: 'wontfix', color: '#ffffff' }
)
end
def verify_milestones_import
milestones = imported_project.milestones
def verify_milestones_import
milestones = imported_project.milestones
expect(milestones.length).to eq(1)
expect(milestones.first).to include(title: '0.0.1', description: nil, state: 'active')
end
expect(milestones.length).to eq(1)
expect(milestones.first).to include(title: '0.0.1', description: nil, state: 'active')
end
def verify_wikis_import
wikis = imported_project.wikis
def verify_wikis_import
wikis = imported_project.wikis
expect(wikis.length).to eq(1)
expect(wikis.first).to include(title: 'Home', format: 'markdown')
end
expect(wikis.length).to eq(1)
expect(wikis.first).to include(title: 'Home', format: 'markdown')
end
def verify_issues_import
issues = imported_project.issues
issue = Resource::Issue.init do |resource|
resource.project = imported_project
resource.iid = issues.first[:iid]
resource.api_client = user_api_client
end.reload!
comments, events = fetch_events_and_comments(issue)
def verify_issues_import
issues = imported_project.issues
issue = Resource::Issue.init do |resource|
resource.project = imported_project
resource.iid = issues.first[:iid]
resource.api_client = user_api_client
end.reload!
comments, events = fetch_events_and_comments(issue)
expect(issues.length).to eq(1)
expect(issue.api_resource).to include(
title: 'Test issue',
description: "*Created by: gitlab-qa-github*\n\nTest issue description",
labels: ['good first issue', 'help wanted', 'question']
)
expect(comments).to match_array(
[
"*Created by: gitlab-qa-github*\n\nSome test comment",
"*Created by: gitlab-qa-github*\n\nAnother test comment"
]
)
expect(events).to match_array(
[
{ name: "add_label", label: "question" },
{ name: "add_label", label: "good first issue" },
{ name: "add_label", label: "help wanted" },
{ name: "add_milestone", label: "0.0.1" },
{ name: "closed" },
{ name: "reopened" }
]
)
end
expect(issues.length).to eq(1)
expect(issue.api_resource).to include(
title: 'Test issue',
description: "*Created by: gitlab-qa-github*\n\nTest issue description",
labels: ['good first issue', 'help wanted', 'question']
)
expect(comments).to match_array(
[
"*Created by: gitlab-qa-github*\n\nSome test comment",
"*Created by: gitlab-qa-github*\n\nAnother test comment"
def verify_merge_requests_import
merge_requests = imported_project.merge_requests
merge_request = Resource::MergeRequest.init do |mr|
mr.project = imported_project
mr.iid = merge_requests.first[:iid]
mr.api_client = user_api_client
end.reload!
comments, events = fetch_events_and_comments(merge_request)
expect(merge_requests.length).to eq(1)
expect(merge_request.api_resource).to include(
title: 'Test pull request',
state: 'opened',
target_branch: 'main',
source_branch: 'gitlab-qa-github-patch-1',
labels: %w[documentation],
description: "*Created by: gitlab-qa-github*\n\nTest pull request body"
)
expect(comments).to match_array(
[
"*Created by: gitlab-qa-github*\n\n**Review:** Commented\n\nGood but needs some improvement",
"*Created by: gitlab-qa-github*\n\n```suggestion:-0+0\nProject for GitHub import test to GitLab\r\n```",
"*Created by: gitlab-qa-github*\n\nSome test PR comment"
]
)
expect(events).to match_array(
[
{ name: "add_label", label: "documentation" },
{ name: "add_milestone", label: "0.0.1" }
]
)
end
def verify_release_import
releases = imported_project.releases
expect(releases.length).to eq(1)
expect(releases.first).to include(
tag_name: "0.0.1",
name: "0.0.1",
description: "Initial release",
created_at: "2022-03-07T07:59:22.000Z",
released_at: "2022-03-07T08:02:09.000Z"
)
end
# Fetch events and comments from issue or mr
#
# @param [QA::Resource::Issuable] issuable
# @return [Array]
def fetch_events_and_comments(issuable)
comments = issuable.comments.map { |comment| comment[:body] }
events = [
*issuable.label_events.map { |e| { name: "#{e[:action]}_label", label: e.dig(:label, :name) } },
*issuable.state_events.map { |e| { name: e[:state] } },
*issuable.milestone_events.map { |e| { name: "#{e[:action]}_milestone", label: e.dig(:milestone, :title) } }
]
)
expect(events).to match_array(
[
{ name: "add_label", label: "question" },
{ name: "add_label", label: "good first issue" },
{ name: "add_label", label: "help wanted" },
{ name: "add_milestone", label: "0.0.1" },
{ name: "closed" },
{ name: "reopened" }
]
)
end
def verify_merge_requests_import
merge_requests = imported_project.merge_requests
merge_request = Resource::MergeRequest.init do |mr|
mr.project = imported_project
mr.iid = merge_requests.first[:iid]
mr.api_client = user_api_client
end.reload!
comments, events = fetch_events_and_comments(merge_request)
expect(merge_requests.length).to eq(1)
expect(merge_request.api_resource).to include(
title: 'Test pull request',
state: 'opened',
target_branch: 'main',
source_branch: 'gitlab-qa-github-patch-1',
labels: %w[documentation],
description: "*Created by: gitlab-qa-github*\n\nTest pull request body"
)
expect(comments).to match_array(
[
"*Created by: gitlab-qa-github*\n\n**Review:** Commented\n\nGood but needs some improvement",
"*Created by: gitlab-qa-github*\n\n```suggestion:-0+0\nProject for GitHub import test to GitLab\r\n```",
"*Created by: gitlab-qa-github*\n\nSome test PR comment"
]
)
expect(events).to match_array(
[
{ name: "add_label", label: "documentation" },
{ name: "add_milestone", label: "0.0.1" }
]
)
end
def verify_release_import
releases = imported_project.releases
expect(releases.length).to eq(1)
expect(releases.first).to include(
tag_name: "0.0.1",
name: "0.0.1",
description: "Initial release",
created_at: "2022-03-07T07:59:22.000Z",
released_at: "2022-03-07T08:02:09.000Z"
)
end
# Fetch events and comments from issue or mr
#
# @param [QA::Resource::Issuable] issuable
# @return [Array]
def fetch_events_and_comments(issuable)
comments = issuable.comments.map { |comment| comment[:body] }
events = [
*issuable.label_events.map { |e| { name: "#{e[:action]}_label", label: e.dig(:label, :name) } },
*issuable.state_events.map { |e| { name: e[:state] } },
*issuable.milestone_events.map { |e| { name: "#{e[:action]}_milestone", label: e.dig(:milestone, :title) } }
]
[comments, events]
[comments, events]
end
end
end
end

View File

@ -4,88 +4,90 @@ module QA
# Spec uses real github.com, which means outage of github can actually block deployment
# Keep spec in reliable bucket but don't run in blocking pipelines
RSpec.describe 'Manage', :github, :reliable, :skip_live_env, :requires_admin, product_group: :import do
describe 'Project import' do
let(:github_repo) { 'gitlab-qa-github/import-test' }
let(:api_client) { Runtime::API::Client.as_admin }
let(:group) { Resource::Group.fabricate_via_api! { |resource| resource.api_client = api_client } }
let(:user) do
Resource::User.fabricate_via_api! do |resource|
resource.api_client = api_client
resource.hard_delete_on_api_removal = true
end
end
let(:imported_project) do
Resource::ProjectImportedFromGithub.init do |project|
project.import = true
project.group = group
project.github_personal_access_token = Runtime::Env.github_access_token
project.github_repository_path = github_repo
project.api_client = api_client
end
end
let(:imported_issue) do
Resource::Issue.init do |resource|
resource.project = imported_project
resource.iid = imported_project.issues.first[:iid]
resource.api_client = api_client
end.reload!
end
let(:imported_issue_events) do
imported_issue.label_events.map { |e| { name: "#{e[:action]}_label", label: e.dig(:label, :name) } }
end
before do
group.add_member(user, Resource::Members::AccessLevel::MAINTAINER)
Flow::Login.sign_in(as: user)
Page::Main::Menu.perform(&:go_to_create_project)
Page::Project::New.perform do |project_page|
project_page.click_import_project
project_page.click_github_link
end
end
after do
user.remove_via_api!
end
it 'imports a GitHub repo', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347877' do
Page::Project::Import::Github.perform do |import_page|
import_page.add_personal_access_token(Runtime::Env.github_access_token)
import_page.select_advanced_option(:single_endpoint_issue_events_import)
import_page.select_advanced_option(:single_endpoint_notes_import)
import_page.select_advanced_option(:attachments_import)
import_page.import!(github_repo, group.full_path, imported_project.name)
aggregate_failures do
expect(import_page).to have_imported_project(github_repo, wait: 240)
# validate button is present instead of navigating to avoid dealing with multiple tabs
# which makes the test more complicated
expect(import_page).to have_go_to_project_button(github_repo)
describe 'GitHub import' do
context 'when imported via UI' do
let(:github_repo) { 'gitlab-qa-github/import-test' }
let(:api_client) { Runtime::API::Client.as_admin }
let(:group) { Resource::Group.fabricate_via_api! { |resource| resource.api_client = api_client } }
let(:user) do
Resource::User.fabricate_via_api! do |resource|
resource.api_client = api_client
resource.hard_delete_on_api_removal = true
end
end
imported_project.reload!.visit!
Page::Project::Show.perform do |project|
aggregate_failures do
expect(project).to have_content(imported_project.name)
expect(project).to have_content('Project for github import test')
let(:imported_project) do
Resource::ProjectImportedFromGithub.init do |project|
project.import = true
project.group = group
project.github_personal_access_token = Runtime::Env.github_access_token
project.github_repository_path = github_repo
project.api_client = api_client
end
end
# Validate :single_endpoint_issue_events_import option was triggered correctly and imported the events
expect(imported_issue_events).to match_array(
[
{ name: "add_label", label: "question" },
{ name: "add_label", label: "good first issue" },
{ name: "add_label", label: "help wanted" }
]
)
let(:imported_issue) do
Resource::Issue.init do |resource|
resource.project = imported_project
resource.iid = imported_project.issues.first[:iid]
resource.api_client = api_client
end.reload!
end
let(:imported_issue_events) do
imported_issue.label_events.map { |e| { name: "#{e[:action]}_label", label: e.dig(:label, :name) } }
end
before do
group.add_member(user, Resource::Members::AccessLevel::MAINTAINER)
Flow::Login.sign_in(as: user)
Page::Main::Menu.perform(&:go_to_create_project)
Page::Project::New.perform do |project_page|
project_page.click_import_project
project_page.click_github_link
end
end
after do
user.remove_via_api!
end
it 'imports a project', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347877' do
Page::Project::Import::Github.perform do |import_page|
import_page.add_personal_access_token(Runtime::Env.github_access_token)
import_page.select_advanced_option(:single_endpoint_issue_events_import)
import_page.select_advanced_option(:single_endpoint_notes_import)
import_page.select_advanced_option(:attachments_import)
import_page.import!(github_repo, group.full_path, imported_project.name)
aggregate_failures do
expect(import_page).to have_imported_project(github_repo, wait: 240)
# validate button is present instead of navigating to avoid dealing with multiple tabs
# which makes the test more complicated
expect(import_page).to have_go_to_project_button(github_repo)
end
end
imported_project.reload!.visit!
Page::Project::Show.perform do |project|
aggregate_failures do
expect(project).to have_content(imported_project.name)
expect(project).to have_content('Project for github import test')
end
end
# Validate :single_endpoint_issue_events_import option was triggered correctly and imported the events
expect(imported_issue_events).to match_array(
[
{ name: "add_label", label: "question" },
{ name: "add_label", label: "good first issue" },
{ name: "add_label", label: "help wanted" }
]
)
end
end
end
end

View File

@ -0,0 +1,43 @@
# frozen_string_literal: true
module QA
RSpec.shared_context "with github import", :github, :skip_live_env, :requires_admin do
let!(:api_client) { Runtime::API::Client.as_admin }
let!(:group) do
Resource::Group.fabricate_via_api! do |resource|
resource.api_client = api_client
resource.path = "destination-group-for-import-#{SecureRandom.hex(4)}"
end
end
let!(:user) do
Resource::User.fabricate_via_api! do |resource|
resource.api_client = api_client
resource.hard_delete_on_api_removal = true
end
end
let!(:user_api_client) { Runtime::API::Client.new(user: user) }
let(:imported_project) do
Resource::ProjectImportedFromGithub.fabricate_via_api! do |project|
project.name = 'imported-project'
project.group = group
project.github_personal_access_token = Runtime::Env.github_access_token
project.github_repository_path = 'gitlab-qa-github/import-test'
project.api_client = user_api_client
project.issue_events_import = true
project.full_notes_import = true
end
end
before do
group.add_member(user, Resource::Members::AccessLevel::MAINTAINER)
end
after do
user.remove_via_api!
end
end
end

View File

@ -14,9 +14,6 @@ QA::Runtime::Scenario.from_env(QA::Runtime::Env.runtime_scenario_attributes)
# Enable zero monkey patching mode before loading any other RSpec code.
RSpec.configure(&:disable_monkey_patching!)
Dir[::File.join(__dir__, "features/shared_examples/*.rb")].sort.each { |f| require f }
Dir[::File.join(__dir__, "features/shared_contexts/*.rb")].sort.each { |f| require f }
# For JH additionally process when `jh/` exists
require_relative('../../../jh/qa/qa/specs/spec_helper') if GitlabEdition.jh?
@ -149,3 +146,6 @@ RSpec.configure do |config|
end
end
end
Dir[::File.join(__dir__, "features/shared_examples/*.rb")].sort.each { |f| require f }
Dir[::File.join(__dir__, "features/shared_contexts/*.rb")].sort.each { |f| require f }

View File

@ -91,7 +91,7 @@ RSpec.describe API::Suggestions do
end
context 'when suggestion is not found' do
let(:url) { "/suggestions/foo-123/apply" }
let(:url) { "/suggestions/9999/apply" }
it 'renders a not found error and returns json content' do
project.add_maintainer(user)
@ -103,6 +103,19 @@ RSpec.describe API::Suggestions do
end
end
context 'when suggestion ID is not valid' do
let(:url) { "/suggestions/foo-123/apply" }
it 'renders a not found error and returns json content' do
project.add_maintainer(user)
put api(url, user)
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response).to eq({ 'error' => 'id is invalid' })
end
end
context 'when unauthorized' do
it 'renders a forbidden error and returns json content' do
project.add_reporter(user)