Skip to content
@deckyard/gitlab

@deckyard/gitlab

A client for the GitLab REST API (/api/v4), for gitlab.com or a self-managed instance. call reaches any endpoint, getAll follows the pages of a list and graphql runs a GraphQL query. Typed verbs cover the daily work: projects, groups and subgroups, members and hooks; issues, notes, labels and milestones; merge requests, approvals and merging; releases with their links and the generic package registry; branches, tags, files and the repository tree; commits, commit statuses, pipelines and CI/CD variables.

Conventions

Snippets assume this import:

jennifer
import "@deckyard/gitlab/" as gitlab;

def c as gitlab.Client init gitlab.client("gitlab.com");
$c = gitlab.withToken($c, fs.readString("/run/secrets/gitlab"));
io.printf("%s\n", gitlab.currentUser($c).username);

A Client is a value. withToken and the other with* functions return a changed copy, so assign the result back to $c.

A project is its numeric id ("278964") or its full path ("group/subgroup/name", as many levels as it has); the deck checks a path and encodes it, so pass it as it appears in the project's URL. Issues and merge requests are addressed by their iid, the number shown in the web interface (#12, !15). States use GitLab's words: opened, closed, merged. Times are the RFC 3339 strings GitLab sends.

Errors

Every failure is a gitlab.GitlabError (kind "gitlab"). The message names the request, the HTTP status and GitLab's reason; the status is the status field, so a handler branches on it rather than on the text:

text
gitlab: GET /projects/me%2Fmissing: HTTP 404: Project Not Found
gitlab: POST /projects: HTTP 400: name has already been taken; path has already been taken
jennifer
try {
    def p as gitlab.Project init gitlab.project($c, "me/missing");
} catch (e) {
    if ($e.kind == "gitlab" and $e.status == 404) {
        io.printf("no such project, or not visible to this token\n");
    } else {
        throw $e;
    }
}

A refused value (a malformed project path, an empty title, an id or iid below 1) is a GitlabError with status 0, thrown before anything is sent. A list past MAX_PAGES pages, or a reply over its size cap, is kind "limit"; a deadline is "timeout"; a cancelled task stays "cancelled". These are plain Errors. A network failure (refused, reset, unreachable, DNS, TLS) is the net.NetError the interpreter raised, kind "net", passed on unchanged: its reason says what failed, and sent false means GitLab never got the request.

Requirements

Jennifer 0.26.0 or newer, the default jennifer binary, and the net capability.