This commit is contained in:
Celina Lopez
2024-10-24 11:49:25 -07:00
parent 93e7d5d660
commit b38f7b5ea0
18 changed files with 126 additions and 129 deletions

View File

@@ -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
end

View File

@@ -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

View File

@@ -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

View File

@@ -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

17
app/helpers/eventable.rb Normal file
View File

@@ -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

View File

@@ -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

View File

@@ -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,

View File

@@ -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 }

28
app/models/event.rb Normal file
View File

@@ -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

View File

@@ -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, {

View File

@@ -28,6 +28,9 @@
<th>
<span class="text-sm font-medium text-base-content/80">Deployed At</span>
</th>
<th>
<span class="text-sm font-medium text-base-content/80">User</span>
</th>
<th>
<span class="text-sm font-medium text-base-content/80"></span>
</th>
@@ -65,6 +68,13 @@
<div class="text-sm capitalize"><%= distance_of_time_in_words(build.created_at, Time.current) %> ago</div>
</div>
</td>
<td>
<% if build.events.present? %>
<div class="text-sm capitalize truncate w-[100px]">
<%= build.events.last.user.email %>
</div>
<% end %>
</td>
<td>
<div class="text-sm capitalize">
<%= button_to redeploy_project_deployment_path(@project, build), method: :post, class: "btn btn-primary btn-sm min-w-max" do %>

View File

@@ -36,7 +36,7 @@ Rails.application.routes.draw do
end
resources :metrics, only: [ :index ], module: :projects
resources :project_add_ons, only: %i[create destroy], module: :projects
resources :environment_variables, only: %i[index create], module: :projects
resources :environment_variables, only: %i[index create destroy], module: :projects
resources :deployments, only: %i[index show], module: :projects do
collection do
post :deploy

View File

@@ -0,0 +1,11 @@
class CreateEvents < ActiveRecord::Migration[7.2]
def change
create_table :events do |t|
t.references :user, null: false
t.references :project, null: false
t.references :eventable, polymorphic: true, null: false
t.integer :event_action, null: false
t.timestamps
end
end
end

15
db/schema.rb generated
View File

@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.2].define(version: 2024_10_09_172011) do
ActiveRecord::Schema[7.2].define(version: 2024_10_23_225911) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -134,6 +134,19 @@ ActiveRecord::Schema[7.2].define(version: 2024_10_09_172011) do
t.index ["project_id"], name: "index_environment_variables_on_project_id"
end
create_table "events", force: :cascade do |t|
t.bigint "user_id", null: false
t.bigint "project_id", null: false
t.string "eventable_type", null: false
t.bigint "eventable_id", null: false
t.integer "event_action", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["eventable_type", "eventable_id"], name: "index_events_on_eventable"
t.index ["project_id"], name: "index_events_on_project_id"
t.index ["user_id"], name: "index_events_on_user_id"
end
create_table "friendly_id_slugs", force: :cascade do |t|
t.string "slug", null: false
t.integer "sluggable_id", null: false

View File

@@ -1,28 +0,0 @@
# == Schema Information
#
# Table name: account_users
#
# id :bigint not null, primary key
# created_at :datetime not null
# updated_at :datetime not null
# account_id :bigint not null
# user_id :bigint not null
#
# Indexes
#
# index_account_users_on_account_id (account_id)
# index_account_users_on_user_id (user_id)
#
# Foreign Keys
#
# fk_rails_... (account_id => accounts.id)
# fk_rails_... (user_id => users.id)
#
one:
user: one
account: one
two:
user: two
account: two

View File

@@ -1,24 +0,0 @@
# == Schema Information
#
# Table name: accounts
#
# id :bigint not null, primary key
# name :string not null
# created_at :datetime not null
# updated_at :datetime not null
# owner_id :bigint
#
# Indexes
#
# index_accounts_on_owner_id (owner_id)
#
# Foreign Keys
#
# fk_rails_... (owner_id => users.id)
#
one:
owner_id:
two:
owner_id:

View File

@@ -1,25 +0,0 @@
# == Schema Information
#
# Table name: accounts
#
# id :bigint not null, primary key
# name :string not null
# created_at :datetime not null
# updated_at :datetime not null
# owner_id :bigint
#
# Indexes
#
# index_accounts_on_owner_id (owner_id)
#
# Foreign Keys
#
# fk_rails_... (owner_id => users.id)
#
require "test_helper"
class AccountTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end

View File

@@ -1,27 +0,0 @@
# == Schema Information
#
# Table name: account_users
#
# id :bigint not null, primary key
# created_at :datetime not null
# updated_at :datetime not null
# account_id :bigint not null
# user_id :bigint not null
#
# Indexes
#
# index_account_users_on_account_id (account_id)
# index_account_users_on_user_id (user_id)
#
# Foreign Keys
#
# fk_rails_... (account_id => accounts.id)
# fk_rails_... (user_id => users.id)
#
require "test_helper"
class AccountUserTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end