Skip to content

Commit

Permalink
Merge pull request #102 from upmaru/feature/support-same-hash-deployment
Browse files Browse the repository at this point in the history
Update deployments index
  • Loading branch information
zacksiri authored Aug 13, 2024
2 parents 960d6db + 1aa4684 commit de3ddd0
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 4 deletions.
10 changes: 6 additions & 4 deletions lib/uplink/packages/deployment/manager.ex
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,10 @@ defmodule Uplink.Packages.Deployment.Manager do
@spec get_or_create(%App{}, map) :: {:ok, %Deployment{}}
def get_or_create(%App{id: app_id} = app, params) do
hash = Map.get(params, :hash) || Map.get(params, "hash")
channel = Map.get(params, :channel) || Map.get(params, "channel")

Deployment
|> Repo.get_by(app_id: app_id, hash: hash)
|> Repo.get_by(app_id: app_id, hash: hash, channel: channel)
|> case do
nil ->
create(app, params)
Expand All @@ -60,17 +61,18 @@ defmodule Uplink.Packages.Deployment.Manager do

{:error,
%Ecto.Changeset{
changes: %{hash: hash},
changes: %{hash: hash, channel: channel},
errors: [
hash:
{_,
[
constraint: :unique,
constraint_name: "deployments_app_id_hash_index"
constraint_name: _
]}
]
}} ->
{:ok, Repo.get_by!(Deployment, app_id: app_id, hash: hash)}
{:ok,
Repo.get_by!(Deployment, app_id: app_id, hash: hash, channel: channel)}

error ->
error
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
defmodule Uplink.Repo.Migrations.ChangeDeploymentsHashUniqueIndex do
use Ecto.Migration

def change do
drop index(:deployments, [:app_id, :hash], unique: true)
create index(:deployments, [:app_id, :hash, :channel], unique: true)
end
end
67 changes: 67 additions & 0 deletions test/uplink/packages/deployment/router_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,73 @@ defmodule Uplink.Packages.Deployment.RouterTest do
end
end

describe "deployment with same hash different channel" do
setup do
signature =
:crypto.mac(:hmac, :sha256, Uplink.Secret.get(), @valid_body)
|> Base.encode16()
|> String.downcase()

conn(:post, "/", @valid_body)
|> put_req_header("x-uplink-signature-256", "sha256=#{signature}")
|> put_req_header("content-type", "application/json")
|> Router.call(@opts)

deployment =
Repo.get_by(Uplink.Packages.Deployment,
hash: "some-hash",
channel: "develop"
)

{:ok, signature: signature, deployment: deployment}
end

test "return 201 for deployment with same hash different channel", %{
deployment: existing_deployment
} do
%{
"deployment" =>
%{"metadata" => %{"channel" => channel} = metadata} = deployment
} = body = Jason.decode!(@valid_body)

channel = Map.put(channel, "slug", "master")

metadata = Map.put(metadata, "channel", channel)

deployment =
deployment
|> Map.put("channel", "master")
|> Map.put("metadata", metadata)

body =
body
|> Map.put("deployment", deployment)
|> Jason.encode!()

new_signature =
:crypto.mac(:hmac, :sha256, Uplink.Secret.get(), body)
|> Base.encode16()
|> String.downcase()

conn =
conn(:post, "/", body)
|> put_req_header("x-uplink-signature-256", "sha256=#{new_signature}")
|> put_req_header("content-type", "application/json")
|> Router.call(@opts)

assert conn.status == 201

assert %{"data" => %{"id" => deployment_id}} =
Jason.decode!(conn.resp_body)

deployment = Uplink.Repo.get(Uplink.Packages.Deployment, deployment_id)

assert deployment.id != existing_deployment.id

assert deployment.current_state == "preparing"
end
end

describe "repeated deployment push with different installation_id" do
setup do
original_signature =
Expand Down

0 comments on commit de3ddd0

Please sign in to comment.