Commit 9809a9af authored by Adam Niedzielski's avatar Adam Niedzielski

Introduce "Set up autodeploy" button to help configure GitLab CI for deployment

The button allows to choose a ".gitlab-ci.yml" template that automatically
sets up the deployment of an application.
The currently supported template is Kubernetes template.
parent 528c3e2b
......@@ -188,7 +188,7 @@ module BlobHelper
end
def gitlab_ci_ymls
@gitlab_ci_ymls ||= Gitlab::Template::GitlabCiYmlTemplate.dropdown_names
@gitlab_ci_ymls ||= Gitlab::Template::GitlabCiYmlTemplate.dropdown_names(params[:context])
end
def dockerfile_names
......
......@@ -280,13 +280,15 @@ module ProjectsHelper
end
end
def add_special_file_path(project, file_name:, commit_message: nil)
def add_special_file_path(project, file_name:, commit_message: nil, target_branch: nil, context: nil)
namespace_project_new_blob_path(
project.namespace,
project,
project.default_branch || 'master',
file_name: file_name,
commit_message: commit_message || "Add #{file_name.downcase}"
commit_message: commit_message || "Add #{file_name.downcase}",
target_branch: target_branch,
context: context
)
end
......
......@@ -68,6 +68,10 @@
- if koding_enabled? && @repository.koding_yml.blank?
%li.missing
= link_to 'Set up Koding', add_koding_stack_path(@project)
- if @repository.gitlab_ci_yml.blank? && @project.deployment_service.present?
%li.missing
= link_to add_special_file_path(@project, file_name: '.gitlab-ci.yml', commit_message: 'Set up autodeploy', target_branch: 'autodeploy', context: 'autodeploy') do
Set up autodeploy
- if @repository.commit
.project-last-commit{ class: container_class }
......
---
title: Introduce "Set up autodeploy" button to help configure GitLab CI for deployment
merge_request: 8135
author:
......@@ -23,6 +23,7 @@
- [CI/CD pipelines settings](../user/project/pipelines/settings.md)
- [Review Apps](review_apps/index.md)
- [Git submodules](git_submodules.md) Using Git submodules in your CI jobs
- [Autodeploy](autodeploy/index.md)
## Breaking changes
......
# Autodeploy
> [Introduced][mr-8135] in GitLab 8.15.
Autodeploy is an easy way to configure GitLab CI for the deployment of your
application. GitLab Community maintains a list of `.gitlab-ci.yml`
templates for various infrastructure providers and deployment scripts
powering them. These scripts are responsible for packaging your application,
setting up the infrastructure and spinning up necessary services (for
example a database).
You can use [project services][project-services] to store credentials to
your infrastructure provider and they will be available during the
deployment.
## Supported templates
The list of supported autodeploy templates is available [here][autodeploy-templates].
## Configuration
1. Enable a deployment [project service][project-services] to store your
credentials. For example, if you want to deploy to a Kubernetes cluster
you have to enable [Kubernetes service][kubernetes-service].
1. Configure GitLab Runner to use [docker-in-docker executor][docker-in-docker].
1. Navigate to the "Project" tab and click "Set up autodeploy" button.
![Autodeploy button](img/autodeploy_button.png)
1. Select a template.
![Dropdown with autodeploy templates](img/autodeploy_dropdown.png)
1. Commit your changes and create a merge request.
1. Test your deployment configuration using a [Review App][review-app] that was
created automatically for you.
[mr-8135]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8135
[project-services]: ../../project_services/project_services.md
[autodeploy-templates]: https://gitlab.com/gitlab-org/gitlab-ci-yml/tree/master/autodeploy
[kubernetes-service]: ../../project_services/kubernetes.md
[docker-in-docker]: ../docker/using_docker_build.md#use-docker-in-docker-executor
[review-app]: ../review_apps/index.md
......@@ -13,8 +13,9 @@ module Gitlab
def categories
{
"General" => '',
"Pages" => 'Pages'
'General' => '',
'Pages' => 'Pages',
'Autodeploy' => 'autodeploy'
}
end
......@@ -25,6 +26,11 @@ module Gitlab
def finder(project = nil)
Gitlab::Template::Finders::GlobalTemplateFinder.new(self.base_dir, self.extension, self.categories)
end
def dropdown_names(context)
categories = context == 'autodeploy' ? ['Autodeploy'] : ['General', 'Pages']
super().slice(*categories)
end
end
end
end
......
......@@ -48,6 +48,19 @@ FactoryGirl.define do
end
end
trait :kubernetes do
after :create do |project|
project.create_kubernetes_service(
active: true,
properties: {
namespace: project.path,
api_url: 'https://kubernetes.example.com/api',
token: 'a' * 40,
}
)
end
end
# Nest Project Feature attributes
transient do
wiki_access_level ProjectFeature::ENABLED
......@@ -137,17 +150,4 @@ FactoryGirl.define do
)
end
end
factory :kubernetes_project, parent: :empty_project do
after :create do |project|
project.create_kubernetes_service(
active: true,
properties: {
namespace: project.path,
api_url: 'https://kubernetes.example.com',
token: 'a' * 40,
}
)
end
end
end
require 'spec_helper'
describe 'Auto deploy' do
include WaitForAjax
let(:user) { create(:user) }
let(:project) { create(:project, :kubernetes) }
before do
project.team << [user, :master]
login_as user
end
context 'when no deployment service is active' do
before do
project.kubernetes_service.update!(active: false)
end
it 'does not show a button to set up auto deploy' do
visit namespace_project_path(project.namespace, project)
expect(page).to have_no_content('Set up autodeploy')
end
end
context 'when a deployment service is active' do
before do
project.kubernetes_service.update!(active: true)
visit namespace_project_path(project.namespace, project)
end
it 'shows a button to set up auto deploy' do
expect(page).to have_link('Set up autodeploy')
end
it 'includes Kubernetes as an available template', js: true do
click_link 'Set up autodeploy'
click_button 'Choose a GitLab CI Yaml template'
within '.gitlab-ci-yml-selector' do
expect(page).to have_content('Kubernetes')
end
end
it 'creates a merge request using "autodeploy" branch', js: true do
click_link 'Set up autodeploy'
click_button 'Choose a GitLab CI Yaml template'
within '.gitlab-ci-yml-selector' do
click_on 'Kubernetes'
end
wait_for_ajax
click_button 'Commit Changes'
expect(page).to have_content('New Merge Request From autodeploy into master')
end
end
end
......@@ -93,7 +93,7 @@ feature 'Environment', :feature do
end
context 'with terminal' do
let(:project) { create(:kubernetes_project, :test_repo) }
let(:project) { create(:empty_project, :kubernetes, :test_repo) }
context 'for project master' do
let(:role) { :master }
......
......@@ -151,7 +151,7 @@ feature 'Environments page', :feature, :js do
end
context 'with terminal' do
let(:project) { create(:kubernetes_project, :test_repo) }
let(:project) { create(:empty_project, :kubernetes, :test_repo) }
context 'for project master' do
let(:role) { :master }
......
......@@ -200,7 +200,7 @@ describe Environment, models: true do
context 'when the enviroment is available' do
context 'with a deployment service' do
let(:project) { create(:kubernetes_project) }
let(:project) { create(:empty_project, :kubernetes) }
context 'and a deployment' do
let!(:deployment) { create(:deployment, environment: environment) }
......@@ -218,14 +218,14 @@ describe Environment, models: true do
end
context 'when the environment is unavailable' do
let(:project) { create(:kubernetes_project) }
let(:project) { create(:empty_project, :kubernetes) }
before { environment.stop }
it { is_expected.to be_falsy }
end
end
describe '#terminals' do
let(:project) { create(:kubernetes_project) }
let(:project) { create(:empty_project, :kubernetes) }
subject { environment.terminals }
context 'when the environment has terminals' do
......
......@@ -4,7 +4,7 @@ describe KubernetesService, models: true, caching: true do
include KubernetesHelpers
include ReactiveCachingHelpers
let(:project) { create(:kubernetes_project) }
let(:project) { create(:empty_project, :kubernetes) }
let(:service) { project.kubernetes_service }
# We use Kubeclient to interactive with the Kubernetes API. It will
......
......@@ -1719,7 +1719,7 @@ describe Project, models: true do
end
context 'when project has a deployment service' do
let(:project) { create(:kubernetes_project) }
let(:project) { create(:empty_project, :kubernetes) }
it 'returns variables from this service' do
expect(project.deployment_variables).to include(
......
require 'spec_helper'
describe ReactiveCachingWorker do
let(:project) { create(:kubernetes_project) }
let(:project) { create(:empty_project, :kubernetes) }
let(:service) { project.deployment_service }
subject { described_class.new.perform("KubernetesService", service.id) }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment