defmodule GitGud.Workflows.PullRequestActivityTest do
@moduledoc """
`pull_request` `closed`, `edited`, `labeled` and `unlabeled`: dispatched
from where they happen, and run only by a workflow whose `types:` asks.
"""
use GitGud.DataCase, async: false
alias GitGud.PullRequests
alias GitGud.Repositories.Repository
alias GitGud.Workflows.WorkflowRun
alias GitGud.Workflows.WorkflowSchedule
import GitGud.ForgeFixtures
import GitGud.WorkflowGitHelpers
@moduletag :capture_log
@wf ".forgejo/workflows/ci.yml"
defp workflow(types) do
"""
name: ci
on:
pull_request:
types: [#{Enum.join(types, ", ")}]
schedule:
- cron: "0 3 * * *"
jobs:
build:
runs-on: self-hosted
steps:
- run: echo hello
"""
end
@default_types """
name: ci
on: pull_request
jobs:
build:
runs-on: self-hosted
steps:
- run: echo hello
"""
setup do
{user, repo} = repository_fixture()
{:ok, repo: repo, user: user}
end
defp open_pr!(repo, user, contents) do
main = commit!(repo, %{"README" => "hi\n"}, [])
git!(repo.disk_path, ["update-ref", "refs/heads/main", main])
feature = commit!(repo, %{"README" => "hi\n", @wf => contents}, [main])
git!(repo.disk_path, ["update-ref", "refs/heads/feature", feature])
{:ok, pr} = PullRequests.create_pull_request(repo, user, pr_attrs("feature", "main"))
drain!()
pr
end
defp drain!, do: Oban.drain_queue(queue: :ci)
defp actions(%Repository{id: rid}) do
from(r in WorkflowRun,
where: r.repository_id == ^rid and r.trigger == "pull_request",
order_by: r.id
)
|> Repo.all()
|> Enum.map(& &1.event_payload["action"])
end
defp last_payload(%Repository{id: rid}) do
from(r in WorkflowRun,
where: r.repository_id == ^rid and r.trigger == "pull_request",
order_by: [desc: r.id],
limit: 1
)
|> Repo.one!()
|> Map.fetch!(:event_payload)
end
test "types: [closed] fires on close, with merged false", %{repo: repo, user: user} do
pr = open_pr!(repo, user, workflow(["closed"]))
assert actions(repo) == []
{:ok, _closed} = PullRequests.set_state(pr, "closed", actor_id: user.id)
drain!()
assert actions(repo) == ["closed"]
payload = last_payload(repo)
assert payload["pull_request"]["merged"] == false
assert payload["pull_request"]["state"] == "closed"
assert payload["sender"]["login"] == user.handle
end
test "types: [closed] fires on merge, with merged true", %{repo: repo, user: user} do
pr = open_pr!(repo, user, workflow(["closed"]))
{:ok, merged} = PullRequests.merge!(pr, user)
# The schedule comes with the merge's push, played by the push worker.
Oban.drain_queue(queue: :git_cache)
drain!()
assert actions(repo) == ["closed"]
payload = last_payload(repo)
assert payload["pull_request"]["merged"] == true
assert payload["pull_request"]["state"] == "closed"
assert payload["pull_request"]["merge_commit_sha"] ==
GitGud.Git.to_hex(merged.merge_commit_sha)
# The merge brought the workflow onto the default branch, and with
# it the schedule.
assert [%WorkflowSchedule{cron: "0 3 * * *"}] =
Repo.all(from s in WorkflowSchedule, where: s.repository_id == ^repo.id)
end
test "the default types don't fire on close", %{repo: repo, user: user} do
pr = open_pr!(repo, user, @default_types)
assert actions(repo) == ["opened"]
{:ok, _closed} = PullRequests.set_state(pr, "closed")
drain!()
assert actions(repo) == ["opened"]
end
test "labeled carries the label; unlabeled too; re-adding a label isn't an event", %{
repo: repo,
user: user
} do
pr = open_pr!(repo, user, workflow(["labeled", "unlabeled"]))
label = label_fixture(repo, %{"name" => "deploy-preview"})
:ok = PullRequests.attach_label(pr, label)
:ok = PullRequests.attach_label(pr, label)
drain!()
assert actions(repo) == ["labeled"]
assert last_payload(repo)["label"]["name"] == "deploy-preview"
:ok = PullRequests.detach_label(pr, label)
:ok = PullRequests.detach_label(pr, label)
drain!()
assert actions(repo) == ["labeled", "unlabeled"]
assert last_payload(repo)["label"]["name"] == "deploy-preview"
end
test "editing the title or body fires edited; other fields don't", %{
repo: repo,
user: user
} do
pr = open_pr!(repo, user, workflow(["edited"]))
{:ok, pr} = PullRequests.update_pull_request(pr, %{"title" => "A new title"})
drain!()
assert actions(repo) == ["edited"]
assert last_payload(repo)["pull_request"]["title"] == "A new title"
{:ok, pr} = PullRequests.update_pull_request(pr, %{"title" => "A new title"})
drain!()
assert actions(repo) == ["edited"]
{:ok, _pr} = PullRequests.update_pull_request(pr, %{"body" => "More words"})
drain!()
assert actions(repo) == ["edited", "edited"]
end
test "a closed pull request still runs nothing but closed", %{repo: repo, user: user} do
pr = open_pr!(repo, user, workflow(["labeled", "closed"]))
{:ok, closed} = PullRequests.set_state(pr, "closed")
drain!()
assert actions(repo) == ["closed"]
:ok = PullRequests.attach_label(closed, label_fixture(repo))
drain!()
assert actions(repo) == ["closed"]
end
end
neiam
/gitgud
Git Gud
public · Issues · Pulls · Labels · Forks · Compare · Actions success · Badges · Packages
⭐
1
Log in to mark this repository.
5.3 KiB · text
History
b868907