defmodule GitGud.Workflows.RerunCancelTest do
use GitGud.DataCase, async: false
alias GitGud.Repo
alias GitGud.Workflows
alias GitGud.Workflows.WorkflowJob
alias GitGud.Workflows.WorkflowRun
alias GitGud.Workflows.WorkflowStep
import GitGud.ForgeFixtures
setup do
{_user, repo} = repository_fixture()
{:ok, repo: repo}
end
defp insert_run(repo, status) do
workflow_doc = %{
"name" => "ci",
"on" => "push",
"jobs" => %{
"build" => %{
"runs-on" => "ubuntu-latest",
"steps" => [%{"run" => "echo hi"}]
}
}
}
run =
%WorkflowRun{repository_id: repo.id}
|> WorkflowRun.create_changeset(%{
"number" => 1,
"workflow_path" => ".forgejo/workflows/ci.yml",
"workflow_name" => "ci",
"trigger" => "push",
"head_ref" => "refs/heads/main",
"head_sha" => :crypto.strong_rand_bytes(20),
"workflow_doc" => workflow_doc
})
|> Repo.insert!()
# `create_changeset` doesn't cast `:status`; promote via the
# dedicated status changeset so the run starts in the desired
# state.
if status != "queued",
do: run |> WorkflowRun.status_changeset(status) |> Repo.update!(),
else: run
end
describe "rerun/1" do
test "creates a fresh run with a new number + the same workflow_doc", %{repo: repo} do
old = insert_run(repo, "failure")
assert {:ok, new_run} = Workflows.rerun(old)
assert new_run.id != old.id
assert new_run.number == old.number + 1
assert new_run.workflow_path == old.workflow_path
assert new_run.workflow_name == old.workflow_name
assert new_run.head_sha == old.head_sha
assert new_run.head_ref == old.head_ref
assert new_run.status == "queued"
jobs = Repo.all(from j in WorkflowJob, where: j.workflow_run_id == ^new_run.id)
assert length(jobs) == 1
assert hd(jobs).status == "queued"
end
end
describe "cancel/1" do
test "marks the run, its queued jobs, and pending steps as cancelled", %{repo: repo} do
old = insert_run(repo, "running")
# Add a queued job + pending step manually (rerun would normally
# create these; we set them up directly so the cancel logic has
# something to target).
job =
%WorkflowJob{workflow_run_id: old.id}
|> WorkflowJob.create_changeset(%{
job_id: "build",
runs_on: %{"value" => "ubuntu-latest"},
needs: [],
definition: %{}
})
|> Repo.insert!()
_step =
%WorkflowStep{workflow_job_id: job.id}
|> WorkflowStep.create_changeset(%{number: 1, name: "Build"})
|> Repo.insert!()
assert {:ok, cancelled} = Workflows.cancel(old)
assert cancelled.status == "cancelled"
assert Repo.get!(WorkflowJob, job.id).status == "cancelled"
[step] = Repo.all(from s in WorkflowStep, where: s.workflow_job_id == ^job.id)
assert step.status == "cancelled"
end
test "is a no-op on already-terminal runs", %{repo: repo} do
old = insert_run(repo, "success")
assert {:ok, same} = Workflows.cancel(old)
assert same.status == "success"
end
end
end
3.2 KiB · text
5af55d9