summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorKamil Trzcinski <ayufan@ayufan.eu>2016-06-10 23:36:54 +0200
committerKamil Trzcinski <ayufan@ayufan.eu>2016-06-10 23:36:54 +0200
commit907c0e6796b69f9577c147dd489cf55748c749ac (patch)
treec4db6a3d3785fa845be98447eb4303b548ab7809 /app
parentcf7da039bedcad5163ce9deedccc94206d4c485a (diff)
downloadgitlab-ce-907c0e6796b69f9577c147dd489cf55748c749ac.tar.gz
Added initial version of deployments
Diffstat (limited to 'app')
-rw-r--r--app/controllers/projects/builds_controller.rb2
-rw-r--r--app/controllers/projects/commit_controller.rb2
-rw-r--r--app/controllers/projects/environments_controller.rb14
-rw-r--r--app/helpers/projects_helper.rb4
-rw-r--r--app/models/ability.rb12
-rw-r--r--app/models/ci/build.rb13
-rw-r--r--app/models/deployment.rb25
-rw-r--r--app/models/environment.rb11
-rw-r--r--app/models/project.rb2
-rw-r--r--app/services/ci/create_builds_service.rb3
-rw-r--r--app/services/create_deployment_service.rb45
-rw-r--r--app/views/projects/deployments/_deployment.html.haml32
-rw-r--r--app/views/projects/environments/_environment.html.haml68
-rw-r--r--app/views/projects/environments/index.html.haml38
-rw-r--r--app/views/projects/environments/show.html.haml46
-rw-r--r--app/views/projects/pipelines/_head.html.haml6
16 files changed, 217 insertions, 106 deletions
diff --git a/app/controllers/projects/builds_controller.rb b/app/controllers/projects/builds_controller.rb
index 14c82826342..ef3051d7519 100644
--- a/app/controllers/projects/builds_controller.rb
+++ b/app/controllers/projects/builds_controller.rb
@@ -51,7 +51,7 @@ class Projects::BuildsController < Projects::ApplicationController
return render_404
end
- build = Ci::Build.retry(@build)
+ build = Ci::Build.retry(@build, current_user)
redirect_to build_path(build)
end
diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb
index 20637fa46fe..6751737d15e 100644
--- a/app/controllers/projects/commit_controller.rb
+++ b/app/controllers/projects/commit_controller.rb
@@ -46,7 +46,7 @@ class Projects::CommitController < Projects::ApplicationController
def retry_builds
ci_builds.latest.failed.each do |build|
if build.retryable?
- Ci::Build.retry(build)
+ Ci::Build.retry(build, current_user)
end
end
diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb
index f5af24ed217..722954a6b78 100644
--- a/app/controllers/projects/environments_controller.rb
+++ b/app/controllers/projects/environments_controller.rb
@@ -1,17 +1,19 @@
class Projects::EnvironmentsController < Projects::ApplicationController
layout 'project'
+ before_action :authorize_read_environment!
+ before_action :environment, only: [:show]
def index
- @environments = project.builds.where.not(environment: nil).pluck(:environment).uniq
- @environments = @environments.map { |env| build_for_env(env) }.compact
+ @environments = project.environments
end
def show
- @environment = params[:id].to_s
- @builds = project.builds.where.not(status: ["manual"]).where(environment: params[:id].to_s).order(id: :desc).page(params[:page]).per(30)
end
- def build_for_env(environment)
- project.builds.success.order(id: :desc).find_by(environment: environment)
+ private
+
+ def environment
+ @environment ||= project.environments.find(params[:id].to_s)
+ @environment || render_404
end
end
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index 5e5d170a9f3..2ad7520b63a 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -156,6 +156,10 @@ module ProjectsHelper
nav_tabs << :container_registry
end
+ if can?(current_user, :read_environment, project)
+ nav_tabs << :environments
+ end
+
if can?(current_user, :admin_project, project)
nav_tabs << :settings
end
diff --git a/app/models/ability.rb b/app/models/ability.rb
index 44515550d9e..747f250ff4f 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -228,6 +228,8 @@ class Ability
:read_build,
:read_container_image,
:read_pipeline,
+ :read_environment,
+ :read_deployment
]
end
@@ -246,6 +248,10 @@ class Ability
:push_code,
:create_container_image,
:update_container_image,
+ :create_environment,
+ :update_environment,
+ :create_deployment,
+ :update_deployment,
]
end
@@ -273,7 +279,9 @@ class Ability
:admin_commit_status,
:admin_build,
:admin_container_image,
- :admin_pipeline
+ :admin_pipeline,
+ :admin_environment,
+ :admin_deployment
]
end
@@ -317,6 +325,8 @@ class Ability
unless project.builds_enabled
rules += named_abilities('build')
rules += named_abilities('pipeline')
+ rules += named_abilities('environment')
+ rules += named_abilities('deployment')
end
unless project.container_registry_enabled
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index 6a64ca451f7..60202525727 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -38,7 +38,7 @@ module Ci
new_build.save
end
- def retry(build)
+ def retry(build, user = nil)
new_build = Ci::Build.new(status: 'pending')
new_build.ref = build.ref
new_build.tag = build.tag
@@ -52,6 +52,7 @@ module Ci
new_build.stage = build.stage
new_build.stage_idx = build.stage_idx
new_build.trigger_request = build.trigger_request
+ new_build.user = user
new_build.save
MergeRequests::AddTodoWhenBuildFailsService.new(build.project, nil).close(new_build)
new_build
@@ -73,6 +74,12 @@ module Ci
build.update_coverage
build.execute_hooks
end
+
+ after_transition any: :success do |build|
+ if build.environment.present?
+ CreateDeploymentService.new(build.project, build.user, environment: build.environment).execute(build)
+ end
+ end
end
def retryable?
@@ -83,10 +90,6 @@ module Ci
!self.pipeline.statuses.latest.include?(self)
end
- def retry
- Ci::Build.retry(self)
- end
-
def depends_on_builds
# Get builds of the same type
latest_builds = self.pipeline.builds.latest
diff --git a/app/models/deployment.rb b/app/models/deployment.rb
new file mode 100644
index 00000000000..7cdfc740441
--- /dev/null
+++ b/app/models/deployment.rb
@@ -0,0 +1,25 @@
+class Deployment < ActiveRecord::Base
+ include InternalId
+
+ belongs_to :project
+ belongs_to :environment
+ belongs_to :user
+ belongs_to :deployable, polymorphic: true
+
+ validates_presence_of :sha
+ validates_presence_of :ref
+
+ delegate :name, to: :environment, prefix: true
+
+ def commit
+ project.commit(sha)
+ end
+
+ def commit_title
+ commit.try(:title)
+ end
+
+ def short_sha
+ Commit::truncate_sha(sha)
+ end
+end
diff --git a/app/models/environment.rb b/app/models/environment.rb
new file mode 100644
index 00000000000..623404ba634
--- /dev/null
+++ b/app/models/environment.rb
@@ -0,0 +1,11 @@
+class Environment < ActiveRecord::Base
+ belongs_to :project
+
+ has_many :deployments
+
+ validates_presence_of :name
+
+ def last_deployment
+ deployments.last
+ end
+end
diff --git a/app/models/project.rb b/app/models/project.rb
index e2f7ffe493c..be714ea41fd 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -125,6 +125,8 @@ class Project < ActiveRecord::Base
has_many :runners, through: :runner_projects, source: :runner, class_name: 'Ci::Runner'
has_many :variables, dependent: :destroy, class_name: 'Ci::Variable', foreign_key: :gl_project_id
has_many :triggers, dependent: :destroy, class_name: 'Ci::Trigger', foreign_key: :gl_project_id
+ has_many :environments, dependent: :destroy
+ has_many :deployments, dependent: :destroy
accepts_nested_attributes_for :variables, allow_destroy: true
diff --git a/app/services/ci/create_builds_service.rb b/app/services/ci/create_builds_service.rb
index 64bcdac5c65..3a74ae094e8 100644
--- a/app/services/ci/create_builds_service.rb
+++ b/app/services/ci/create_builds_service.rb
@@ -29,7 +29,8 @@ module Ci
:options,
:allow_failure,
:stage,
- :stage_idx)
+ :stage_idx,
+ :environment)
build_attrs.merge!(ref: @pipeline.ref,
tag: @pipeline.tag,
diff --git a/app/services/create_deployment_service.rb b/app/services/create_deployment_service.rb
new file mode 100644
index 00000000000..f745471913f
--- /dev/null
+++ b/app/services/create_deployment_service.rb
@@ -0,0 +1,45 @@
+require_relative 'base_service'
+
+class CreateDeploymentService < BaseService
+ def execute(deployable)
+ environment = find_or_create_environment(params[:environment])
+
+ deployment = create_deployment(environment, deployable)
+ if deployment.persisted?
+ success(deployment)
+ else
+ error(deployment.errors)
+ end
+ end
+
+ private
+
+ def find_or_create_environment(environment)
+ find_environment(environment) || create_environment(environment)
+ end
+
+ def create_environment(environment)
+ project.environments.create(name: environment)
+ end
+
+ def find_environment(environment)
+ project.environments.find_by(name: environment)
+ end
+
+ def create_deployment(environment, deployable)
+ environment.deployments.create(
+ project: project,
+ ref: build.ref,
+ tag: build.tag,
+ sha: build.sha,
+ user: current_user,
+ deployable: deployable,
+ )
+ end
+
+ def success(deployment)
+ out = super()
+ out[:deployment] = deployment
+ out
+ end
+end
diff --git a/app/views/projects/deployments/_deployment.html.haml b/app/views/projects/deployments/_deployment.html.haml
new file mode 100644
index 00000000000..363c394d6d3
--- /dev/null
+++ b/app/views/projects/deployments/_deployment.html.haml
@@ -0,0 +1,32 @@
+%tr.deployment
+ %td
+ %strong= "##{environment.id}"
+
+ %td
+ %div.branch-commit
+ - if deployment.ref
+ = link_to last.ref, namespace_project_commits_path(@project.namespace, @project, deployment.ref), class: "monospace"
+ &middot;
+ = link_to deployment.short_sha, namespace_project_commit_path(@project.namespace, @project, deployment.sha), class: "commit-id monospace"
+
+ %p
+ %span
+ - if commit_title = deployment.commit_title
+ = link_to_gfm commit_title, namespace_project_commit_path(@project.namespace, @project, deployment.sha), class: "commit-row-message"
+ - else
+ Cant find HEAD commit for this branch
+
+ %td
+ - if deployment.deployable
+ = link_to [@project.namespace.becomes(Namespace), @project, deployment.deployable], class: "monospace" do
+ = "#{deployment.deployable.name} (##{deployment.deployable.id})"
+
+ %td
+ %p
+ %i.fa.fa-calendar
+ &nbsp;
+ #{time_ago_with_tooltip(deployment.created_at)}
+
+ %td
+ - if can?(current_user, :update_deployment, @project) && deployment.deployable
+ = link_to [@project.namespace.becomes(Namespace), @project, deployment.deployable, :retry], method: :post, title: 'Retry', class: 'btn btn-build'
diff --git a/app/views/projects/environments/_environment.html.haml b/app/views/projects/environments/_environment.html.haml
index e3216aea6cd..a4c88fface2 100644
--- a/app/views/projects/environments/_environment.html.haml
+++ b/app/views/projects/environments/_environment.html.haml
@@ -1,58 +1,32 @@
-%tr.commit
- - commit = build.commit
- - status = build.status
+- last_deployment = environment.last_deployment
+%tr.environment
%td
%strong
- = link_to build.environment, namespace_project_environment_path(@project.namespace, @project, build.environment), class: "monospace"
-
- %td.commit-link
- = link_to namespace_project_pipeline_path(@project.namespace, @project, commit.id), class: "ci-status ci-#{commit.status}" do
- = ci_icon_for_status(commit.status)
- %strong ##{commit.id}
-
- %td.commit-link
- = link_to namespace_project_build_path(@project.namespace, @project, build.id), class: "ci-status ci-#{build.status}" do
- = ci_icon_for_status(build.status)
- %strong ##{build.id}
+ = link_to environment.name, namespace_project_environment_path(@project.namespace, @project, environment), class: "monospace"
%td
- %div.branch-commit
- - if commit.ref
- = link_to commit.ref, namespace_project_commits_path(@project.namespace, @project, commit.ref), class: "monospace"
- &middot;
- = link_to commit.short_sha, namespace_project_commit_path(@project.namespace, @project, commit.sha), class: "commit-id monospace"
+ - if last_deployment
+ %div.branch-commit
+ - if last_deployment.ref
+ = link_to last.ref, namespace_project_commits_path(@project.namespace, @project, last_deployment.ref), class: "monospace"
+ &middot;
+ = link_to last_deployment.short_sha, namespace_project_commit_path(@project.namespace, @project, last_deployment.sha), class: "commit-id monospace"
+ %p
+ %span
+ - if commit_title = last_deployment.commit_title
+ = link_to_gfm commit_title, namespace_project_commit_path(@project.namespace, @project, last_deployment.sha), class: "commit-row-message"
+ - else
+ Cant find HEAD commit for this branch
+ - else
%p
- %span
- - if commit_data = commit.commit_data
- = link_to_gfm commit_data.title, namespace_project_commit_path(@project.namespace, @project, commit_data.id), class: "commit-row-message"
- - else
- Cant find HEAD commit for this branch
+ No deployments yet
%td
- - if build.started_at && build.finished_at
- %p
- %i.fa.fa-clock-o
- &nbsp;
- #{duration_in_words(build.finished_at, build.started_at)}
- - if build.finished_at
- %p
- %i.fa.fa-calendar
- &nbsp;
- #{time_ago_with_tooltip(build.finished_at)}
+ %p
+ %i.fa.fa-calendar
+ &nbsp;
+ #{time_ago_with_tooltip(last_deployment.created_at)}
%td
- .controls.hidden-xs.pull-right
- - manual = commit.builds.latest.manual_actions.to_a
- - if manual.any?
- .dropdown.inline
- %button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'}
- = icon('play')
- %b.caret
- %ul.dropdown-menu.dropdown-menu-align-right
- - manual.each do |manual_build|
- %li
- = link_to '#', rel: 'nofollow' do
- %i.fa.fa-play
- %span #{manual_build.name}
diff --git a/app/views/projects/environments/index.html.haml b/app/views/projects/environments/index.html.haml
index e94bc97be9d..40d35ef3881 100644
--- a/app/views/projects/environments/index.html.haml
+++ b/app/views/projects/environments/index.html.haml
@@ -1,22 +1,22 @@
+- @no_container = true
- page_title "Environments"
-= render "header_title"
+= render "projects/pipelines/head"
-.gray-content-block
- Environments for this project
+%div{ class: (container_class) }
+ .gray-content-block
+ Environments for this project
-%ul.content-list
- - if @environments.blank?
- %li
- .nothing-here-block No environments to show
- - else
- .table-holder
- %table.table.builds
- %tbody
- %th Environment
- %th Pipeline ID
- %th Build ID
- %th Changes
- %th
- %th
- - @environments.each do |build|
- = render "environment", build: build
+ %ul.content-list
+ - if @environments.blank?
+ %li
+ .nothing-here-block No environments to show
+ - else
+ .table-holder
+ %table.table.builds
+ %tbody
+ %th Environment
+ %th Last deployment
+ %th Date
+ %th
+ - @environments.each do |environment|
+ = render 'environment', environment: environment
diff --git a/app/views/projects/environments/show.html.haml b/app/views/projects/environments/show.html.haml
index ce2d9cf7d71..de5e686044f 100644
--- a/app/views/projects/environments/show.html.haml
+++ b/app/views/projects/environments/show.html.haml
@@ -1,30 +1,26 @@
+- @no_container = true
- page_title "Environments"
+= render "projects/pipelines/head"
-= render "header_title"
+%div{ class: (container_class) }
+ .gray-content-block
+ Latest deployments for
+ %strong= @environment.name
-.gray-content-block
- Latest deployments for
- %strong
- = @environment
+ %ul.content-list
+ - if @deployments.blank?
+ %li
+ .nothing-here-block No deployment for specific environment
+ - else
+ .table-holder
+ %table.table.builds
+ %thead
+ %tr
+ %th Commit
+ %th Context
+ %th Date
+ %th
-%ul.content-list
- - if @builds.blank?
- %li
- .nothing-here-block No builds to show for specific environment
- - else
- .table-holder
- %table.table.builds
- %thead
- %tr
- %th Status
- %th Build ID
- %th Commit
- %th Ref
- %th Name
- %th Duration
- %th Finished at
- %th
+ = render @deployments
- = render @builds, commit_sha: true, ref: true, allow_retry: true
-
- = paginate @builds, theme: 'gitlab'
+ = paginate @deployments, theme: 'gitlab'
diff --git a/app/views/projects/pipelines/_head.html.haml b/app/views/projects/pipelines/_head.html.haml
index f278d4e0538..3562d91dfbd 100644
--- a/app/views/projects/pipelines/_head.html.haml
+++ b/app/views/projects/pipelines/_head.html.haml
@@ -13,3 +13,9 @@
%span
Builds
%span.badge.count.builds_counter= number_with_delimiter(@project.running_or_pending_build_count)
+
+ - if project_nav_tab? :environments
+ = nav_link(controller: %w(environments)) do
+ = link_to project_environments_path(@project), title: 'Environments', class: 'shortcuts-environments' do
+ %span
+ Environments