Skip to content

Commit

Permalink
Avoid job duplication by Github webhooks
Browse files Browse the repository at this point in the history
Signed-off-by: Tallys Martins <tallysmartins@gmail.com>
  • Loading branch information
tallysmartins committed Jun 28, 2018
1 parent c2cdb06 commit 5de6bef
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 1 deletion.
22 changes: 22 additions & 0 deletions lib/elixir_bench/benchmarks/benchmarks.ex
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@ defmodule ElixirBench.Benchmarks do
Repo.fetch(where(Job, uuid: ^uuid))
end

def fetch_running_job_by_reference(branch_name, commit_sha) do
query =
Job
|> last
|> Job.unfinished()
|> where(branch_name: ^branch_name, commit_sha: ^commit_sha)

Repo.fetch(query)
end

def list_benchmarks_by_repo_id(repo_ids) do
Repo.all(from(b in Benchmark, where: b.repo_id in ^repo_ids))
end
Expand All @@ -63,6 +73,18 @@ defmodule ElixirBench.Benchmarks do
Repo.all(Job)
end

def get_or_create_job(repo, attrs) do
%{branch_name: branch_name, commit_sha: commit_sha} = attrs

case fetch_running_job_by_reference(branch_name, commit_sha) do
{:ok, job} ->
{:ok, job}

{:error, :not_found} ->
create_job(repo, attrs)
end
end

def create_job(repo, attrs) do
changeset = Job.create_changeset(%Job{repo_id: repo.id}, attrs)

Expand Down
5 changes: 5 additions & 0 deletions lib/elixir_bench/benchmarks/job.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ defmodule ElixirBench.Benchmarks.Job do
use Ecto.Schema

import Ecto.Changeset
import Ecto.Query, only: [from: 1, from: 2]

alias ElixirBench.Repos
alias ElixirBench.Benchmarks.{Runner, Job, Config}
Expand Down Expand Up @@ -66,4 +67,8 @@ defmodule ElixirBench.Benchmarks.Job do
|> validate_required(@submit_fields)
|> put_change(:completed_at, DateTime.utc_now())
end

def unfinished(query) do
from(j in query, where: is_nil(j.completed_at))
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ defmodule ElixirBenchWeb.Github.WebHooks do

with {:ok, %Repos.Repo{} = repo} <- Repos.fetch_repo_by_slug(slug),
{:ok, job} <-
Benchmarks.create_job(repo, %{branch_name: branch_name, commit_sha: commit_sha}) do
Benchmarks.get_or_create_job(repo, %{branch_name: branch_name, commit_sha: commit_sha}) do
conn
|> render(ElixirBenchWeb.JobView, "show.json", job: job, repo: repo)
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,30 @@ defmodule ElixirBenchWeb.Github.WebHooksControllerTest do
assert 200 = response.status
end

# This scenario happens when there is a branch with an open pull request
# So Github sends requests for both events, pull request and push.
test "not duplicate job for same branch and commit references", context do
insert(:repo, @github_repo_attrs)
push_params = %{"payload" => push_payload()}
pull_request = %{"payload" => pull_request_payload()}

assert_difference(Job, 1) do
{:ok, %{"data" => data}} =
context.conn
|> set_headers("pull_request")
|> post("/hooks/handle", pull_request)
|> decode_response_body

{:ok, %{"data" => ^data}} =
context.conn
|> set_headers("push")
|> post("/hooks/handle", push_params)
|> decode_response_body
end

assert %{"branch_name" => "changes", "repo_slug" => "baxterthehacker/public-repo"} = data
end

test "not break given unexpected pull request event payload scheme", context do
insert(:repo, @github_repo_attrs)
params = %{"payload" => ~s({"data": "some data"})}
Expand Down

0 comments on commit 5de6bef

Please sign in to comment.