The convenience modules are thin wrappers over GhEx.REST that fill in the
endpoint path. Each function returns the same {:ok, body, meta} /
{:error, reason} shape as the core and passes opts through to Req (so
:params, headers, and a Req.Test plug all work). They cover the
common paths; for anything else, call GhEx.REST directly.
On the write wrappers (create, update, merge, and the like), the attrs
argument is the sole request body: each sets :json to attrs, so a :json
passed in opts is ignored.
The list_* functions return a single page. Each has a stream_* companion
that auto-paginates into a lazy Stream of individual items, following
Link: rel="next" (see the Pagination guide). The wrapped
endpoints (Search, Actions runs/workflows/jobs, Checks) unwrap their array key
for you.
# every open issue, not just the first page
client
|> GhEx.Issues.stream("elixir-lang", "elixir", params: [state: "open", per_page: 100])
|> Stream.map(& &1["number"])
|> Enum.to_list()For a path without a stream_* wrapper, call GhEx.REST.stream/3 directly with
the path and, for an object-wrapped response, the items: key.
Issues
GhEx.Issues — list, get, create, update, comment, label.
GhEx.Issues.list(client, "elixir-lang", "elixir", params: [state: "open"])
GhEx.Issues.create(client, "o", "r", %{title: "Bug", body: "..."})
GhEx.Issues.create_comment(client, "o", "r", 7, "thanks for the report")
GhEx.Issues.add_labels(client, "o", "r", 7, ["bug", "p1"])Pull requests
GhEx.PullRequests — list, get, create, update, merge, files, reviews.
GhEx.PullRequests.create(client, "o", "r", %{title: "Fix", head: "fix", base: "main"})
GhEx.PullRequests.list_files(client, "o", "r", 42)
GhEx.PullRequests.merge(client, "o", "r", 42, %{merge_method: "squash"})
GhEx.PullRequests.create_review(client, "o", "r", 42, %{event: "APPROVE"})Repositories and contents
GhEx.Repositories — get, list (org/user), create, update, delete, commits,
branches. GhEx.Contents — read and write files.
GhEx.Repositories.get(client, "elixir-lang", "elixir")
GhEx.Repositories.list_for_org(client, "elixir-lang", params: [type: "public"])
{:ok, file, _meta} = GhEx.Contents.get(client, "o", "r", "mix.exs", params: [ref: "main"])
GhEx.Contents.create_or_update_file(client, "o", "r", "NOTES.md", %{
message: "add notes",
content: Base.encode64("hello"),
sha: file["sha"]
})content is Base64-encoded, and updating an existing file needs its blob sha.
Releases
GhEx.Releases — list, get, get_latest, get_by_tag, create, update, delete.
GhEx.Releases.get_latest(client, "o", "r")
GhEx.Releases.create(client, "o", "r", %{
tag_name: "v1.0.0",
name: "v1.0.0",
generate_release_notes: true
})Actions
GhEx.Actions — workflows, runs, dispatch. A workflow is its numeric id or its
file name ("ci.yml").
GhEx.Actions.list_workflows(client, "o", "r")
GhEx.Actions.dispatch_workflow(client, "o", "r", "ci.yml", %{ref: "main", inputs: %{env: "prod"}})
GhEx.Actions.list_runs(client, "o", "r", params: [branch: "main", status: "failure"])
GhEx.Actions.rerun(client, "o", "r", run_id)Checks and statuses
GhEx.Checks — check runs. GhEx.Statuses — commit statuses.
GhEx.Checks.create_run(client, "o", "r", %{name: "lint", head_sha: sha, status: "in_progress"})
GhEx.Checks.list_for_ref(client, "o", "r", sha)
GhEx.Statuses.create(client, "o", "r", sha, %{state: "success", context: "ci/lint"})
GhEx.Statuses.get_combined(client, "o", "r", "main")Search
GhEx.Search — repositories, code, issues_and_pull_requests, users, commits. The
first argument is the q query; pass params: for sort and order.
GhEx.Search.repositories(client, "tetris language:elixir", params: [sort: "stars"])
GhEx.Search.issues_and_pull_requests(client, "repo:o/r is:open label:bug")Users, organizations, and teams
GhEx.Users, GhEx.Organizations, GhEx.Teams.
GhEx.Users.get_authenticated(client)
GhEx.Users.get(client, "joshrotenberg")
GhEx.Organizations.list_members(client, "elixir-lang")
GhEx.Teams.list(client, "elixir-lang")Gists
GhEx.Gists — list, get, create, update, delete.
GhEx.Gists.create(client, %{
description: "example",
public: false,
files: %{"hello.txt" => %{content: "hi"}}
})Webhooks
GhEx.Webhooks is the receiving side: verify a delivery signature and parse the
payload. See the Testing guide for the full handler pattern.
with :ok <- GhEx.Webhooks.verify(body, signature, secret),
{:ok, payload} <- GhEx.Webhooks.parse(body) do
handle(event_name, payload)
end