diff --git a/app/actions/environment_variables/bulk_update.rb b/app/actions/environment_variables/bulk_update.rb index 4b716489..d6b015cd 100644 --- a/app/actions/environment_variables/bulk_update.rb +++ b/app/actions/environment_variables/bulk_update.rb @@ -2,18 +2,30 @@ class EnvironmentVariables::BulkUpdate extend LightService::Action expects :project, :params + expects :current_user, default: nil executed do |context| project = context.project - # Delete all environment variables and create new ones + env_variable_data = context.params[:environment_variables] - project.environment_variables.destroy_all + incoming_variable_names = env_variable_data.map { |ev| ev[:name] } + current_variable_names = project.environment_variables.pluck(:name) - (context.params[:environment_variables] || []).each do |environment_variable_params| - next if environment_variable_params[:name].blank? - name = environment_variable_params[:name].strip.upcase - value = environment_variable_params[:value].strip - project.environment_variables.create!(name:, value:) + new_names = incoming_variable_names - current_variable_names + + if new_names.any? + env_variable_data.filter { |ev| new_names.include?(ev[:name]) }.each do |ev| + next if ev[:name].blank? + project.environment_variables.create!( + name: ev[:name].strip.upcase, + value: ev[:value].strip, + current_user: context.current_user + ) + end end + + destroy_names = current_variable_names - incoming_variable_names + + project.environment_variables.where(name: destroy_names).destroy_all if destroy_names.any? end -end \ No newline at end of file +end diff --git a/app/actions/projects/deploy_latest_commit.rb b/app/actions/projects/deploy_latest_commit.rb index 788ff66a..6e06bb40 100644 --- a/app/actions/projects/deploy_latest_commit.rb +++ b/app/actions/projects/deploy_latest_commit.rb @@ -2,18 +2,20 @@ class Projects::DeployLatestCommit extend LightService::Action expects :project + expects :current_user, default: nil promises :project executed do |context| # Fetch the latest commit from the default branch project = context.project + current_user = context.current_user || project.account.owner client = Octokit::Client.new(access_token: project.account.github_access_token) commit = client.commits(project.repository_url).first - build = Build.create!( - project: project, + build = project.builds.create!( commit_sha: commit.sha, - commit_message: commit.commit[:message] + commit_message: commit.commit[:message], + current_user: current_user ) Projects::BuildJob.perform_later(build) end diff --git a/app/controllers/inbound_webhooks/github_controller.rb b/app/controllers/inbound_webhooks/github_controller.rb index 3b396d5c..13469b85 100644 --- a/app/controllers/inbound_webhooks/github_controller.rb +++ b/app/controllers/inbound_webhooks/github_controller.rb @@ -7,7 +7,7 @@ module InboundWebhooks record = InboundWebhook.create(body: payload) # Queue webhook for processing - InboundWebhooks::GithubJob.perform_later(record) + InboundWebhooks::GithubJob.perform_later(record, current_user:) # Tell service we received the webhook successfully head :ok diff --git a/app/controllers/projects/deployments_controller.rb b/app/controllers/projects/deployments_controller.rb index 1c196a90..c0f4fdf9 100644 --- a/app/controllers/projects/deployments_controller.rb +++ b/app/controllers/projects/deployments_controller.rb @@ -11,6 +11,7 @@ class Projects::DeploymentsController < Projects::BaseController def redeploy new_build = @build.dup.tap do |build| build.status = :in_progress + build.current_user = current_user end if new_build.save Projects::BuildJob.perform_later(new_build) @@ -21,7 +22,7 @@ class Projects::DeploymentsController < Projects::BaseController end def deploy - result = Projects::DeployLatestCommit.execute(project: @project) + result = Projects::DeployLatestCommit.execute(project: @project, current_user:) if result.success? redirect_to @project, notice: "Deploying project..." else diff --git a/app/helpers/eventable.rb b/app/helpers/eventable.rb new file mode 100644 index 00000000..2c1867f2 --- /dev/null +++ b/app/helpers/eventable.rb @@ -0,0 +1,17 @@ +module Eventable + extend ActiveSupport::Concern + + included do + attr_accessor :current_user + has_many :events, as: :eventable, dependent: :destroy + after_save :create_event + end + + def create_event + events.create!( + user: current_user, + event_action: id_changed? ? :create : :update, + project: + ) if current_user + end +end diff --git a/app/jobs/inbound_webhooks/github_job.rb b/app/jobs/inbound_webhooks/github_job.rb index 48de87a7..dc54c1f7 100644 --- a/app/jobs/inbound_webhooks/github_job.rb +++ b/app/jobs/inbound_webhooks/github_job.rb @@ -2,14 +2,14 @@ module InboundWebhooks class GithubJob < ApplicationJob queue_as :default - def perform(inbound_webhook) + def perform(inbound_webhook, current_user: nil) inbound_webhook.processing! # Process webhook # Determine the project # Trigger a docker build & docker deploy if auto deploy is on for the project body = JSON.parse(inbound_webhook.body) - process_webhook(body) + process_webhook(body, current_user:) inbound_webhook.processed! @@ -17,16 +17,16 @@ module InboundWebhooks # inbound_webhook.failed! end - def process_webhook(body) - return if body['pusher'].nil? - branch = body['ref'].gsub('refs/heads/', '') - projects = Project.where(repository_url: body['repository']['full_name'], branch: branch, autodeploy: true) + def process_webhook(body, current_user:) + return if body["pusher"].nil? + branch = body["ref"].gsub("refs/heads/", "") + projects = Project.where(repository_url: body["repository"]["full_name"], branch: branch, autodeploy: true) projects.each do |project| # Trigger a docker build & docker deploy - build = Build.create!( - project_id: project.id, - commit_sha: body['head_commit']['id'], - commit_message: body['head_commit']['message'] + build = project.builds.create!( + current_user:, + commit_sha: body["head_commit"]["id"], + commit_message: body["head_commit"]["message"] ) Projects::BuildJob.perform_later(build) end diff --git a/app/models/build.rb b/app/models/build.rb index 290d4075..dd0951fb 100644 --- a/app/models/build.rb +++ b/app/models/build.rb @@ -22,8 +22,11 @@ # class Build < ApplicationRecord include Loggable + include Eventable + belongs_to :project has_one :deployment, dependent: :destroy + enum status: { in_progress: 0, completed: 1, diff --git a/app/models/environment_variable.rb b/app/models/environment_variable.rb index d751b850..3408e0a8 100644 --- a/app/models/environment_variable.rb +++ b/app/models/environment_variable.rb @@ -19,6 +19,8 @@ # fk_rails_... (project_id => projects.id) # class EnvironmentVariable < ApplicationRecord + include Eventable + belongs_to :project validates :name, presence: true, uniqueness: { scope: :project_id } diff --git a/app/models/event.rb b/app/models/event.rb new file mode 100644 index 00000000..3f627fc2 --- /dev/null +++ b/app/models/event.rb @@ -0,0 +1,28 @@ +# == Schema Information +# +# Table name: events +# +# id :bigint not null, primary key +# event_action :integer not null +# eventable_type :string not null +# created_at :datetime not null +# updated_at :datetime not null +# eventable_id :bigint not null +# project_id :bigint not null +# user_id :bigint not null +# +# Indexes +# +# index_events_on_eventable (eventable_type,eventable_id) +# index_events_on_project_id (project_id) +# index_events_on_user_id (user_id) +# +class Event < ApplicationRecord + belongs_to :eventable, polymorphic: true + belongs_to :user + belongs_to :project + enum event_action: { + create: 0, + update: 1 + }, _prefix: true +end diff --git a/app/models/project.rb b/app/models/project.rb index 6c60d540..96e9d41c 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -34,9 +34,11 @@ class Project < ApplicationRecord has_many :builds, dependent: :destroy has_many :deployments, through: :builds has_many :domains, through: :services + has_many :events validates :name, presence: true, format: { with: /\A[a-z0-9_-]+\z/, message: "must be lowercase, numbers, hyphens, and underscores only" } + validates_uniqueness_of :name, scope: :cluster_id enum :status, { diff --git a/app/views/projects/deployments/index.html.erb b/app/views/projects/deployments/index.html.erb index 505a059b..b7d2d952 100644 --- a/app/views/projects/deployments/index.html.erb +++ b/app/views/projects/deployments/index.html.erb @@ -28,6 +28,9 @@