# Resource modules
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](pagination.md) guide). The wrapped
endpoints (Search, Actions runs/workflows/jobs, Checks) unwrap their array key
for you.
```elixir
# 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.
```elixir
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.
```elixir
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.
```elixir
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.
```elixir
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"`).
```elixir
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.
```elixir
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`.
```elixir
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`.
```elixir
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.
```elixir
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](testing.md) guide for the full handler pattern.
```elixir
with :ok <- GhEx.Webhooks.verify(body, signature, secret),
{:ok, payload} <- GhEx.Webhooks.parse(body) do
handle(event_name, payload)
end
```