Setup
Register the provider next to your cloud’s:
import * as GitHub from "alchemy/GitHub";
providers: Layer.mergeAll(Cloudflare.providers(), GitHub.providers()),The next alchemy login adds a GitHub step with three options:
ghCLI — shells out togh auth token(recommended).- Environment variables — reads
GITHUB_ACCESS_TOKEN, falling back toGITHUB_TOKEN(good for CI). - Stored PAT — a personal access token entered interactively,
saved under
~/.alchemy/credentials/<profile>/.
When CI=true, the login step skips the prompt and selects the
environment-variables method automatically.
See Profiles for how credentials are stored and switched.
GitHub Enterprise
Section titled “GitHub Enterprise”All three methods work against GitHub Enterprise Server and GitHub
Enterprise Cloud with data residency. alchemy login --configure
prompts for the host — leave it blank for github.com, or enter your
enterprise host (e.g. github.example.com or acme.ghe.com).
The host is normalized into the REST API base URL automatically:
github.example.com→https://github.example.com/api/v3(GHES)acme.ghe.com→https://api.acme.ghe.com(data residency)- an explicit URL like
https://github.example.com/api/v3is used as-is
Alternatively, set the host in the environment — GITHUB_BASE_URL,
GITHUB_API_URL (set automatically on GitHub Actions runners), or
GH_HOST — and every method picks it up without reconfiguring. On an
enterprise host, the environment-variables method also honors the gh
CLI’s GH_ENTERPRISE_TOKEN / GITHUB_ENTERPRISE_TOKEN before falling
back to GITHUB_ACCESS_TOKEN / GITHUB_TOKEN, and the gh CLI method
runs gh auth token --hostname <host> (run
gh auth login --hostname <host> once first).
Pin the host in code
Section titled “Pin the host in code”To fix the host for the whole app — independent of profile
configuration or the environment — pass it to providers():
providers: GitHub.providers({ baseUrl: "github.example.com" }),The auth provider sees the pinned host too: alchemy login stops
prompting for it and authenticates against it directly.
Per-resource host override
Section titled “Per-resource host override”Every GitHub resource also takes its own baseUrl prop, so a single
stack can span github.com and an enterprise instance:
yield* GitHub.Repository("mirror", { owner: "my-org", name: "mirror", baseUrl: "github.example.com",});Resolution order is: resource baseUrl → providers({ baseUrl }) →
the host from the login profile or environment. Changing a resource’s
baseUrl replaces it — the same name on a different GitHub instance
is a different physical resource.
Token scopes
Section titled “Token scopes”repo— always required.workflow— when you manage Actions secrets and variables.delete_repo— only when you opt a repository into deletion viadestroy(). Repositories default to retain on removal, so most tokens never need it.
Programmatic credentials
Section titled “Programmatic credentials”Skip profiles entirely by building the credentials layer from a token you already have in hand — useful in tests:
Effect.provide(GitHub.fromToken(token))fromToken accepts a plain string or a Redacted value, plus an
optional baseUrl for GitHub Enterprise:
Effect.provide(GitHub.fromToken(token, { baseUrl: "github.example.com" }))To read from the environment instead, GitHub.fromEnv() builds the
same layer from GITHUB_ACCESS_TOKEN or GITHUB_TOKEN (and resolves
the enterprise host from GITHUB_BASE_URL / GITHUB_API_URL /
GH_HOST when set).
Next steps
Section titled “Next steps”- GitHub overview — resources and compositions.