mirror of
https://github.com/czhu12/canine.git
synced 2026-05-04 18:41:35 -05:00
updates
This commit is contained in:
@@ -10,6 +10,7 @@ class ProjectForks::Create
|
||||
child_project = parent_project.dup
|
||||
child_project.branch = pull_request.branch
|
||||
child_project.name = "#{parent_project.name}-#{pull_request.number}"
|
||||
child_project.cluster_id = parent_project.project_fork_cluster_id
|
||||
# Duplicate the project_credential_provider
|
||||
child_project_credential_provider = parent_project.project_credential_provider.dup
|
||||
child_project_credential_provider.project = child_project
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
class ProjectForks::CreateFromCanineConfig
|
||||
extend LightService::Action
|
||||
expects :canine_config, :project
|
||||
|
||||
executed do |context|
|
||||
context.canine_config.services.each do |service_config|
|
||||
end
|
||||
|
||||
context.canine_config.environment_variables.each do |environment_variable|
|
||||
end
|
||||
end
|
||||
end
|
||||
+35
-11
@@ -46,6 +46,7 @@ class Project < ApplicationRecord
|
||||
|
||||
has_one :child_fork, class_name: "ProjectFork", foreign_key: :child_project_id
|
||||
has_many :forks, class_name: "ProjectFork", foreign_key: :parent_project_id
|
||||
has_one :project_fork_cluster, class_name: "Cluster", foreign_key: :id, primary_key: :project_fork_cluster_id
|
||||
|
||||
validates :name, presence: true,
|
||||
format: { with: /\A[a-z0-9-]+\z/, message: "must be lowercase, numbers, and hyphens only" }
|
||||
@@ -56,6 +57,7 @@ class Project < ApplicationRecord
|
||||
message: "must be in the format 'owner/repository'"
|
||||
}
|
||||
validates :project_credential_provider, presence: true
|
||||
validate :project_fork_cluster_id_is_owned_by_account
|
||||
|
||||
validate :name_is_unique_to_cluster, on: :create
|
||||
after_save_commit do
|
||||
@@ -78,6 +80,12 @@ class Project < ApplicationRecord
|
||||
delegate :git?, :github?, :gitlab?, to: :project_credential_provider
|
||||
delegate :docker_hub?, to: :project_credential_provider
|
||||
|
||||
def project_fork_cluster_id_is_owned_by_account
|
||||
if project_fork_cluster_id.present? && !account.clusters.exists?(id: project_fork_cluster_id)
|
||||
errors.add(:project_fork_cluster_id, "must be owned by the account")
|
||||
end
|
||||
end
|
||||
|
||||
def name_is_unique_to_cluster
|
||||
if cluster.namespaces.include?(name)
|
||||
errors.add(:name, "must be unique to this cluster")
|
||||
@@ -108,13 +116,21 @@ class Project < ApplicationRecord
|
||||
repository_url.split("/").last
|
||||
end
|
||||
|
||||
def full_repository_url
|
||||
if github?
|
||||
"https://github.com/#{repository_url}"
|
||||
elsif gitlab?
|
||||
"https://gitlab.com/#{repository_url}"
|
||||
def link_to_view
|
||||
if forked?
|
||||
if github?
|
||||
"https://github.com/#{repository_url}/pull/#{child_fork.number}"
|
||||
elsif gitlab?
|
||||
"https://gitlab.com/#{repository_url}/merge_requests/#{child_fork.number}"
|
||||
end
|
||||
else
|
||||
"https://hub.docker.com/r/#{repository_url}"
|
||||
if github?
|
||||
"https://github.com/#{repository_url}"
|
||||
elsif gitlab?
|
||||
"https://gitlab.com/#{repository_url}"
|
||||
else
|
||||
"https://hub.docker.com/r/#{repository_url}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -134,14 +150,22 @@ class Project < ApplicationRecord
|
||||
services.each(&:updated!)
|
||||
end
|
||||
|
||||
def container_tag
|
||||
if forked?
|
||||
branch.gsub("/", "-")
|
||||
else
|
||||
"latest"
|
||||
end
|
||||
end
|
||||
|
||||
def container_registry_url
|
||||
container_registry = self.attributes["container_registry_url"].presence || repository_url
|
||||
if github?
|
||||
"ghcr.io/#{container_registry}:latest"
|
||||
"ghcr.io/#{container_registry}:#{container_tag}"
|
||||
elsif gitlab?
|
||||
"registry.gitlab.com/#{container_registry}:latest"
|
||||
"registry.gitlab.com/#{container_registry}:#{container_tag}"
|
||||
else
|
||||
"docker.io/#{container_registry}:latest"
|
||||
"docker.io/#{container_registry}:#{container_tag}"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -155,14 +179,14 @@ class Project < ApplicationRecord
|
||||
end
|
||||
|
||||
def show_fork_options?
|
||||
!preview? && git?
|
||||
!forked? && git?
|
||||
end
|
||||
|
||||
def can_fork?
|
||||
show_fork_options? && !forks_disabled?
|
||||
end
|
||||
|
||||
def preview?
|
||||
def forked?
|
||||
child_fork.present?
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
class CanineConfig::Definition
|
||||
attr_reader :definition
|
||||
|
||||
def initialize(yaml_path, base_project, pull_request)
|
||||
context = {
|
||||
"cluster_id": base_project.project_fork_cluster_id,
|
||||
"cluster_name": base_project.project_fork_cluster.name,
|
||||
"project_name": "#{base_project.name}-#{pull_request.number}",
|
||||
"number": pull_request.number,
|
||||
"title": pull_request.title,
|
||||
"branch_name": pull_request.branch,
|
||||
"username": pull_request.user
|
||||
}
|
||||
|
||||
content = if yaml_path.to_s.end_with?('.erb')
|
||||
erb = ERB.new(File.read(yaml_path))
|
||||
context_binding = binding
|
||||
context.each do |key, value|
|
||||
context_binding.local_variable_set(key, value)
|
||||
end
|
||||
erb.result(context_binding)
|
||||
else
|
||||
File.read(yaml_path)
|
||||
end
|
||||
|
||||
@definition = YAML.load(content)
|
||||
end
|
||||
|
||||
def services
|
||||
definition['services'].map do |service|
|
||||
params = Service.permitted_params(ActionController::Parameters.new(service:))
|
||||
Service.new(params)
|
||||
end
|
||||
end
|
||||
|
||||
def environment_variables
|
||||
definition['environment_variables'].map do |env|
|
||||
EnvironmentVariable.new(name: env['name'], value: env['value'])
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,21 +0,0 @@
|
||||
class ReviewApp::Definition
|
||||
def initialize(yaml_path, context = {})
|
||||
content = if yaml_path.end_with?('.erb')
|
||||
require 'erb'
|
||||
erb = ERB.new(File.read(yaml_path))
|
||||
context_binding = binding
|
||||
context.each { |key, value| context_binding.local_variable_set(key, value) }
|
||||
erb.result(context_binding)
|
||||
else
|
||||
File.read(yaml_path)
|
||||
end
|
||||
|
||||
@definition = YAML.load(content)
|
||||
end
|
||||
|
||||
def to_yaml
|
||||
{
|
||||
name: @project.name
|
||||
}
|
||||
end
|
||||
end
|
||||
@@ -47,7 +47,7 @@
|
||||
<ul>
|
||||
<% current_account.projects.order(created_at: :desc).each do |project| %>
|
||||
<li>
|
||||
<%= link_to root_projects_path(project), class: "hover:bg-base-content/15 #{'active' if current_page?(root_projects_path(project))}" do %>
|
||||
<%= link_to root_projects_path(project), class: "hover:bg-base-content/15 #{'active' if request.path.start_with?("/projects/#{project.id}")}" do %>
|
||||
<div class="flex items-center gap-2">
|
||||
<%= project.name %>
|
||||
</div>
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
<% if project.forked? %>
|
||||
<div class="mb-2">
|
||||
<%= link_to "← Back to original project", project_path(project.parent_project), class: "btn btn-ghost" %>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="flex flex-col md:flex-row items-center justify-between mb-4">
|
||||
<div class="self-stretch">
|
||||
<div>
|
||||
@@ -15,7 +20,7 @@
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="text-sm">
|
||||
<%= link_to project.full_repository_url, target: "_blank" do %>
|
||||
<%= link_to project.link_to_view, target: "_blank" do %>
|
||||
<% if project.git? %>
|
||||
<% if project.github? %>
|
||||
<iconify-icon icon="lucide:github"></iconify-icon>
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
name: "name"
|
||||
services:
|
||||
- name: "service_1"
|
||||
container_port: 8080
|
||||
service_type: "web_service"
|
||||
environment_variables:
|
||||
- name: "DATABASE_URL"
|
||||
value: "redis://redis.cluster.svc.local/<%= number %>"
|
||||
scripts:
|
||||
clean_up_command: ""
|
||||
@@ -82,10 +82,10 @@ RSpec.describe Project, type: :model do
|
||||
end
|
||||
end
|
||||
|
||||
describe '#full_repository_url' do
|
||||
describe '#link_to_view' do
|
||||
it 'returns the full GitHub URL' do
|
||||
project.repository_url = 'owner/repository-name'
|
||||
expect(project.full_repository_url).to eq('https://github.com/owner/repository-name')
|
||||
expect(project.link_to_view).to eq('https://github.com/owner/repository-name')
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe CanineConfig::Definition do
|
||||
let(:yaml_path) { Rails.root.join('resources', 'canine_config', 'example_1.yaml.erb') }
|
||||
let(:account) { create(:account) }
|
||||
let(:cluster) { create(:cluster, account:) }
|
||||
let(:base_project) { create(:project, project_fork_cluster_id: cluster.id, account:) }
|
||||
let(:pull_request) do
|
||||
Git::Common::PullRequest.new(
|
||||
number: 42,
|
||||
title: 'Test PR',
|
||||
branch: 'feature/test',
|
||||
user: 'testuser'
|
||||
)
|
||||
end
|
||||
|
||||
subject(:definition) { described_class.new(yaml_path, base_project, pull_request) }
|
||||
|
||||
describe '#environment_variables' do
|
||||
it 'returns environment variables from the definition' do
|
||||
env_vars = definition.environment_variables
|
||||
|
||||
expect(env_vars.count).to eq(1)
|
||||
expect(env_vars.first.name).to eq('DATABASE_URL')
|
||||
expect(env_vars.first.value).to eq('redis://redis.cluster.svc.local/42')
|
||||
end
|
||||
end
|
||||
|
||||
describe '#services' do
|
||||
it 'returns services from the definition' do
|
||||
services = definition.services
|
||||
|
||||
expect(services.count).to eq(1)
|
||||
expect(services.first.name).to eq('service_1')
|
||||
expect(services.first.container_port).to eq(8080)
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user