forked from Shopify/shipit-engine
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Summary ------- At PowerHRG we desire to implement the ability to automatically deploy a branch as a new "review instance" of our application to our Kubernetes cluster when a Pull Request for that branch is opened - and subsequently clean up the instance when the PR is closed or merged - functionality similar to Heroku's Review Apps. However, we maintain a number of projects and do NOT want to expose this functionality for every repository. As we understand it, Shipit offers no mechanism at the repository level to control which repositories can dynamically provision stacks. It seems the Stack is the highest level concept which involves a repository, but this remains insufficient since the Stack also marries a particular branch and environment to the repository concept. What we _think_ we'd like is a higher level concept which represents the repository to which stacks could belong. This repository could then contain its own configuration for the project-level features we desire. References ---------- - Shopify#960
- Loading branch information
1 parent
833c850
commit cccf8f9
Showing
9 changed files
with
192 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
module Shipit | ||
class Repository < ApplicationRecord | ||
OWNER_MAX_SIZE = 39 | ||
private_constant :OWNER_MAX_SIZE | ||
|
||
NAME_MAX_SIZE = 100 | ||
private_constant :NAME_MAX_SIZE | ||
|
||
validates :name, uniqueness: {scope: %i(owner), case_sensitive: false, | ||
message: 'cannot be used more than once'} | ||
validates :owner, :name, presence: true, ascii_only: true | ||
validates :owner, format: {with: /\A[a-z0-9_\-\.]+\z/}, length: {maximum: OWNER_MAX_SIZE} | ||
validates :name, format: {with: /\A[a-z0-9_\-\.]+\z/}, length: {maximum: NAME_MAX_SIZE} | ||
|
||
has_many :stacks, dependent: :destroy | ||
|
||
def name=(n) | ||
super(n&.downcase) | ||
end | ||
|
||
def owner=(o) | ||
super(o&.downcase) | ||
end | ||
|
||
def http_url | ||
Shipit.github.url("#{owner}/#{name}") | ||
end | ||
|
||
def git_url | ||
"https://#{Shipit.github.domain}/#{owner}/#{name}.git" | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
class CreateShipitRepositories < ActiveRecord::Migration[6.0] | ||
def change | ||
create_table :repositories do |t| | ||
t.string :owner, limit: 100, null: false | ||
t.string :name, limit: 39, null: false | ||
|
||
t.timestamps | ||
end | ||
|
||
add_index :repositories, ["owner", "name"], name: "repository_unicity", unique: true | ||
end | ||
end |
41 changes: 41 additions & 0 deletions
41
db/migrate/20191209231307_add_repository_reference_to_stacks.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
class AddRepositoryReferenceToStacks < ActiveRecord::Migration[6.0] | ||
def up | ||
add_reference :stacks, :repository | ||
|
||
repositories = Shipit::Stack.distinct.select(:repo_owner, :repo_name).pluck(:repo_owner, :repo_name) | ||
repositories.map do |repo_owner, repo_name| | ||
repository = Shipit::Repository.create_or_find_by( | ||
owner: repo_owner, | ||
name: repo_name, | ||
) | ||
|
||
stacks = Shipit::Stack.where(repo_owner: repository.owner, repo_name: repository.name) | ||
stacks.update(repository: repository) | ||
end | ||
|
||
change_column :stacks, :repository_id, :integer, null: false | ||
|
||
remove_index :stacks, name: "stack_unicity" | ||
add_index :stacks, ["repository_id", "environment"], name: "stack_unicity", unique: true | ||
change_column :stacks, :repo_owner, :string, null: true | ||
change_column :stacks, :repo_name, :string, null: true | ||
remove_column :stacks, :repo_owner | ||
remove_column :stacks, :repo_name | ||
end | ||
|
||
def down | ||
add_column :stacks, :repo_name, :string, limit: 100 | ||
add_column :stacks, :repo_owner, :string, limit: 39 | ||
remove_index :stacks, name: "stack_unicity" | ||
add_index :stacks, ["repo_owner", "repo_name", "environment"], name: "stack_unicity", unique: true | ||
|
||
Shipit::Repository.find_each do |repository| | ||
repository.stacks.update_all(repo_owner: repository.owner, repo_name: repository.name) | ||
end | ||
|
||
change_column :stacks, :repo_name, :string, null: false | ||
change_column :stacks, :repo_owner, :string, null: false | ||
|
||
remove_reference :stacks, :repository | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
shipit: | ||
owner: shopify | ||
name: shipit-engine | ||
|
||
cyclimse: | ||
owner: george | ||
name: cyclimse | ||
|
||
foo-bar: | ||
owner: shopify | ||
name: foo-bar | ||
|
||
soc: | ||
owner: "shopify" | ||
name: "soc" | ||
|
||
check_runs: | ||
owner: shopify | ||
name: check_runs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
require 'test_helper' | ||
|
||
module Shipit | ||
class RepositoryTest < ActiveSupport::TestCase | ||
setup do | ||
@repository = shipit_repositories(:shipit) | ||
end | ||
|
||
test "owner, and name uniqueness is enforced" do | ||
clone = Repository.new(@repository.attributes.except('id')) | ||
refute clone.save | ||
assert_equal ["cannot be used more than once"], clone.errors[:name] | ||
end | ||
|
||
test "owner, name, and environment can only be ASCII" do | ||
@repository.update(owner: 'héllò', name: 'wørld') | ||
refute_predicate @repository, :valid? | ||
end | ||
|
||
test "owner and name are case insensitive" do | ||
assert_no_difference -> { Repository.count } do | ||
error = assert_raises ActiveRecord::RecordInvalid do | ||
Repository.create!( | ||
owner: @repository.owner.upcase, | ||
name: @repository.name.upcase, | ||
) | ||
end | ||
assert_equal 'Validation failed: Name cannot be used more than once', error.message | ||
end | ||
|
||
new_repository = Repository.create!(owner: 'FOO', name: 'BAR') | ||
assert_equal new_repository, Repository.find_by(owner: 'foo', name: 'bar') | ||
end | ||
|
||
test "owner is automatically downcased" do | ||
@repository.owner = 'George' | ||
assert_equal 'george', @repository.owner | ||
end | ||
|
||
test "name is automatically downcased" do | ||
@repository.name = 'Cyclim.se' | ||
assert_equal 'cyclim.se', @repository.name | ||
end | ||
|
||
test "owner cannot contain a `/`" do | ||
assert @repository.valid? | ||
@repository.owner = 'foo/bar' | ||
refute @repository.valid? | ||
end | ||
|
||
test "name cannot contain a `/`" do | ||
assert @repository.valid? | ||
@repository.name = 'foo/bar' | ||
refute @repository.valid? | ||
end | ||
|
||
test "http_url" do | ||
assert_equal "https://github.com/#{@repository.owner}/#{@repository.name}", @repository.http_url | ||
end | ||
|
||
test "git_url" do | ||
assert_equal "https://github.com/#{@repository.owner}/#{@repository.name}.git", @repository.git_url | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters