PoC: Deployment Approvals
What's changed in this PoC
[NOT FOR MERGE] THIS IS POC/PROTOTYPE
This MR provides a prototype of Deployment Approval feature, that is based on this backend proposal and the UX/UI proposal.
Specifically, this MR introduces the following changes:
- Add
Deployments::Approval
active record model (deployment_approvals
table). This model represents the approval history of deployments. - Add
Deployments::ApprovalService
as a SSOT facility to approve/reject a deployment and trigger a subsequent process. - Add a new status
blocked
to the deployment model. This represents that the a deployment is waiting for approvals. - Add
required_approval_count
column toprotected_environments
table, that represents how many approvals are needed to deploy to a protected environment. - Add a new failure reason
deployment_rejected
to pipeline jobs, that represents a deployment job failed by rejection.
Related #344233 (closed) #343864 (closed) #343864 (closed)
How to use this feature
required_approval_count
on protected environments
Configure Protect an environment (with 1 additional approval)
curl --header 'Content-Type: application/json' --request POST \
--data '{"name": "production", "required_approval_count": 1, "deploy_access_levels": [{"access_level": 40}]}' \
--header "PRIVATE-TOKEN: A3K6cFWthsQrQLaM8Fj1" \
http://local.gitlab.test:8181/api/v4/projects/219/protected_environments
> {"name":"production","deploy_access_levels":[{"access_level":40,"access_level_description":"Maintainers","user_id":null,"group_id":null}],"required_approval_count":1}
Other utilities:
# Get a single Protected Environment
curl -H 'Private-Token: A3K6cFWthsQrQLaM8Fj1' http://local.gitlab.test:8181/api/v4/projects/219/protected_environments/production
> {"name":"production","deploy_access_levels":[{"access_level":40,"access_level_description":"Maintainers","user_id":null,"group_id":null}],"required_approval_count":0}
# List of Protected Environments
curl -H 'Private-Token: A3K6cFWthsQrQLaM8Fj1' http://local.gitlab.test:8181/api/v4/projects/219/protected_environments
> [{"name":"production","deploy_access_levels":[{"access_level":40,"access_level_description":"Maintainers","user_id":null,"group_id":null}],"required_approval_count":0}]
# Unprotect an environment
curl -X DELETE -H 'Private-Token: A3K6cFWthsQrQLaM8Fj1' http://local.gitlab.test:8181/api/v4/projects/219/protected_environments/production
Run a pipeline in a project
Here is an example:
deploy:
script: echo
environment: production
and confirm that a deployment job is blocked.
Approve a deployment to a protected environment
Get the latest deployment and its approval status
curl -H 'Private-Token: A3K6cFWthsQrQLaM8Fj1' "http://local.gitlab.test:8181/api/v4/projects/219/deployments?environment=production&sort=desc" | jq '.[0] | { id: .id, iid: .iid, status: .status, required_approval_count: .required_approval_count, approvals: .approvals }'
{
"id": 1085,
"iid": 17,
"status": "blocked",
"required_approval_count": 1,
"approvals": []
}
Approve the deployemnt as a different user
curl -d 'status=approved' -H 'Private-Token: -B_sqZgkw_ptEf_ytyZP' "http://local.gitlab.test:8181/api/v4/projects/219/deployments/1085/approval"
{"user":{"id":1,"name":"Administrator","username":"root","state":"active","avatar_url":"https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon","web_url":"http://local.gitlab.test:8181/root"},"status":"approved"}
2nd time: Get the latest deployment and its approval status
{
"id": 1085,
"iid": 17,
"status": "success",
"required_approval_count": 0,
"approvals": [
{
"user": {
"id": 1,
"name": "Administrator",
"username": "root",
"state": "active",
"avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
"web_url": "http://local.gitlab.test:8181/root"
},
"status": "approved"
}
]
}
(Note: A runner is needed to actually run the deployment job and transition the deployment status from blocked
to running
=> success
)
Confirm pipeline succeeded
Merge request reports
Activity
changed milestone to %14.5
assigned to @shinya.maeda
- A deleted user
added database databasereview pending labels
5 Warnings This merge request is quite big (545 lines changed), please consider splitting it into multiple merge requests. dc0f3b72: The commit subject must contain at least 3 words. For more information, take a look at our Commit message guidelines. dc0f3b72: Commits that change 30 or more lines across at least 3 files should describe these changes in the commit body. For more information, take a look at our Commit message guidelines. ddf790bc: The commit body should not contain more than 72 characters per line. For more information, take a look at our Commit message guidelines. This merge request changed frontend files without pretty printing them. 1 Message This merge request adds or changes files that require a review from the Database team. This merge request requires a database review. To make sure these changes are reviewed, take the following steps:
- Ensure the merge request has database and databasereview pending labels. If the merge request modifies database files, Danger will do this for you.
- Prepare your MR for database review according to the docs.
- Assign and mention the database reviewer suggested by Reviewer Roulette.
The following files require a review from the Database team:
db/migrate/20211029203950_create_deployment_approval_table.rb
db/migrate/20211029203951_create_protected_environment_approval_access_levels_table.rb
db/migrate/20211029203952_add_required_approval_count_to_protected_environments.rb
db/schema_migrations/20211029203950
db/schema_migrations/20211029203951
db/schema_migrations/20211029203952
db/structure.sql
Pretty print Frontend files
The following files should have been pretty printed with
prettier
:ee/app/assets/javascripts/api.js
ee/app/assets/javascripts/protected_environments/protected_environment_create.js
Please run
node_modules/.bin/prettier --write \ 'ee/app/assets/javascripts/api.js' \ 'ee/app/assets/javascripts/protected_environments/protected_environment_create.js'
Also consider auto-formatting on-save.
Reviewer roulette
Changes that require review have been detected!
Please refer to the table below for assigning reviewers and maintainers suggested by Danger in the specified category:
Category Reviewer Maintainer backend Steve Abrams ( @sabrams
) (UTC-7, 14 hours behind@shinya.maeda
)Vitali Tatarintev ( @ck3g
) (UTC+1, 6 hours behind@shinya.maeda
)database Simon Tomlinson ( @stomlinson
) (UTC-6, 13 hours behind@shinya.maeda
)Steve Abrams ( @sabrams
) (UTC-7, 14 hours behind@shinya.maeda
)frontend Ammar Alakkad ( @aalakkad
) (UTC+3, 4 hours behind@shinya.maeda
)Peter Hegman ( @peterhegman
) (UTC-8, 15 hours behind@shinya.maeda
)~migration No reviewer available No maintainer available To spread load more evenly across eligible reviewers, Danger has picked a candidate for each review slot, based on their timezone. Feel free to override these selections if you think someone else would be better-suited or use the GitLab Review Workload Dashboard to find other available reviewers.
To read more on how to use the reviewer roulette, please take a look at the Engineering workflow and code review guidelines. Please consider assigning a reviewer or maintainer who is a domain expert in the area of the merge request.
Once you've decided who will review this merge request, assign them as a reviewer! Danger does not automatically notify them for you.
If needed, you can retry the
danger-review
job that generated this comment.Generated by
Dangermentioned in issue #344233 (closed)
added 177 commits
-
42ac918d...eea9ad53 - 176 commits from branch
master
- c3de081f - Add tables
-
42ac918d...eea9ad53 - 176 commits from branch
Allure report
allure-report-publisher
generated test report for 13745e62!review-qa-smoke:
test reportUtility commands on Rails console
Running a new pipeline
project = Project.find_by_full_path('root/poc-deployment-approvals') user = User.first pipeline = Ci::CreatePipelineService.new(project, user, ref: 'main').execute(:web)
Checking the environment properties
Ci::Build.last.persisted_environment.need_approval? Ci::Build.last.persisted_environment.protected? Ci::Build.last.persisted_environment.required_approval_count Ci::Build.last.persisted_environment.send(:associated_protected_environments)
Updating an environment properties
ProtectedEnvironment.where(project: project, name: 'production').take.update!(required_approval_count: 1)
Approve/Reject a deployment
project = Project.find_by_full_path('root/poc-deployment-approvals') user = User.first deployment = project.deployments.last; :ok Deployments::ApprovalService.new(project, user).execute(deployment, 'approved') Deployments::ApprovalService.new(project, user).execute(deployment, 'rejected')