Skip to content

GitHub.Issue reference

Source: packages/github/src/Comment.ts

A GitHub issue or pull request comment.

Comment manages the lifecycle of a single comment on an issue or pull request. Comments are created on the first deploy and updated in place on subsequent deploys when the body changes. By default, comments are never deleted to preserve discussion history — set allowDelete: true to opt in.

Authentication is resolved in order: explicit token prop, GITHUB_ACCESS_TOKEN env var, GITHUB_TOKEN env var. The token needs repo scope for private repositories or public_repo for public ones.

Comment on an Issue

const comment = yield* GitHub.Comment("issue-comment", {
owner: "my-org",
repository: "my-repo",
issueNumber: 123,
body: "This is a comment created by Alchemy!",
});

Comment on a Pull Request

const prComment = yield* GitHub.Comment("pr-comment", {
owner: "my-org",
repository: "my-repo",
issueNumber: 456,
body: "## Deployment Status\n\nSuccessfully deployed to staging!",
});

Deploy with the same logical ID and a different body to update the existing comment in place rather than creating a new one.

const comment = yield* GitHub.Comment("status-comment", {
owner: "my-org",
repository: "my-repo",
issueNumber: 789,
body: "Deployment completed successfully!",
});
const comment = yield* GitHub.Comment("temp-comment", {
owner: "my-org",
repository: "my-repo",
issueNumber: 123,
body: "This comment can be deleted",
allowDelete: true,
});

A common pattern is posting a preview-deployment URL on every pull request. The comment auto-updates on each push because the logical ID stays the same.

if (process.env.PULL_REQUEST) {
yield* GitHub.Comment("preview-comment", {
owner: "my-org",
repository: "my-repo",
issueNumber: Number(process.env.PULL_REQUEST),
body: Output.interpolate`
## Preview Deployed
**URL:** ${website.url}
`,
});
}

Source: packages/github/src/CreateIssue.ts

Open an issue in the bound repository (issues.create).

Provide GitHub.CreateIssueHttp on a Worker or Function, or GitHub.CreateIssueLocal on an Action.

const createIssue = yield* GitHub.CreateIssue(yield* Repo);
const issue = yield* createIssue({
title: "Deploy failed",
body: "See the logs for details.",
labels: ["incident"],
});

Source: packages/github/src/CreateIssueComment.ts

Comment on an issue or pull request (issues.createComment). Pass a pull request’s number as issue_number.

Provide GitHub.CreateIssueCommentHttp on a Worker or Function, or GitHub.CreateIssueCommentLocal on an Action.

const createComment = yield* GitHub.CreateIssueComment(yield* Repo);
yield* createComment({ issue_number: 7, body: "On it." });

Source: packages/github/src/CreateIssueCommentHttp.ts Kind: Layer · Provides: GitHub.CreateIssueComment

Token-backed implementation of CreateIssueComment. Provide it on a Worker or Function: it captures a GitHub.PersonalAccessToken for the host and binds the token and the repository into it.

Source: packages/github/src/CreateIssueCommentLocal.ts Kind: Layer · Provides: GitHub.CreateIssueComment

Implementation of CreateIssueComment with the provider’s current credentials. Provide it on an Action or another deploy-time Effect.

Source: packages/github/src/CreateIssueHttp.ts Kind: Layer · Provides: GitHub.CreateIssue

Token-backed implementation of CreateIssue. Provide it on a Worker or Function: it captures a GitHub.PersonalAccessToken for the host and binds the token and the repository into it.

Source: packages/github/src/CreateIssueLocal.ts Kind: Layer · Provides: GitHub.CreateIssue

Implementation of CreateIssue with the provider’s current credentials. Provide it on an Action or another deploy-time Effect.

Source: packages/github/src/GetIssue.ts

Get one issue by number (issues.get). A missing issue fails with the typed IssueNotFound.

Provide GitHub.GetIssueHttp on a Worker or Function, or GitHub.GetIssueLocal on an Action.

const getIssue = yield* GitHub.GetIssue(yield* Repo);
const issue = yield* getIssue({ issue_number: 7 }).pipe(
Effect.catchTag("IssueNotFound", () => Effect.succeed(undefined)),
);

Source: packages/github/src/GetIssueHttp.ts Kind: Layer · Provides: GitHub.GetIssue

Token-backed implementation of GetIssue. Provide it on a Worker or Function: it captures a GitHub.PersonalAccessToken for the host and binds the token and the repository into it.

Source: packages/github/src/GetIssueLocal.ts Kind: Layer · Provides: GitHub.GetIssue

Implementation of GetIssue with the provider’s current credentials. Provide it on an Action or another deploy-time Effect.

Source: packages/github/src/Issue.ts

A GitHub repository issue.

Issue manages the lifecycle of a single issue in a repository. Issues are created on the first deploy and updated in place on subsequent deploys when properties change. By default, issues are retained on destruction to preserve discussion history. Pipe the resource through destroy() to close the issue on destruction instead; its discussion remains on GitHub.

Authentication is resolved via the GitHub Credentials service supplied by GitHub.providers() (env, stored PAT, gh CLI, or OAuth). The token needs repo scope for private repositories or public_repo for public ones.

Create a Basic Issue

const issue = yield* GitHub.Issue("bug-report", {
owner: "my-org",
repository: "my-repo",
title: "Bug: Application crashes on startup",
body: "## Description\n\nThe application crashes when...",
})

Issue with Labels and Assignees

const issue = yield* GitHub.Issue("feature-request", {
owner: "my-org",
repository: "my-repo",
title: "Feature: Add dark mode",
body: "Users have requested...",
labels: ["enhancement", "ui"],
assignees: ["developer1"],
})

Deploy with the same logical ID and different properties to update the existing issue in place rather than creating a new one.

const issue = yield* GitHub.Issue("resolved-bug", {
owner: "my-org",
repository: "my-repo",
title: "Bug: Application crashes on startup",
body: "This has been resolved.",
state: "closed",
})
const issue = yield* GitHub.Issue("v1-task", {
owner: "my-org",
repository: "my-repo",
title: "Implement authentication",
milestone: 1,
})

A common pattern is creating issues to track infrastructure changes or deployment status.

yield* GitHub.Issue("infra-status", {
owner: "my-org",
repository: "my-repo",
title: "Infrastructure Status",
body: Output.interpolate`
## Current Status
**Database:** ${database.endpoint}
**Cache:** ${cache.endpoint}
`,
labels: ["infrastructure"],
})

Source: packages/github/src/Label.ts

A GitHub repository label.

Label manages repository labels for categorizing issues and pull requests. Labels are created on first deploy and updated in place on subsequent deploys when properties change.

Authentication is resolved via the GitHub Credentials service supplied by GitHub.providers() (env, stored PAT, gh CLI, or OAuth). The token needs repo scope for private repositories or public_repo for public ones.

Basic Label

const bug = yield* GitHub.Label("bug", {
owner: "my-org",
repository: "my-repo",
name: "bug",
color: "d73a4a",
description: "Something isn't working",
});

Multiple Labels

yield* GitHub.Label("feature", {
owner: "my-org",
repository: "my-repo",
name: "feature",
color: "a2eeef",
description: "New feature or request",
});
yield* GitHub.Label("documentation", {
owner: "my-org",
repository: "my-repo",
name: "documentation",
color: "0075ca",
description: "Improvements or additions to documentation",
});

Deploy with the same logical ID and different properties to update the existing label in place.

yield* GitHub.Label("priority-high", {
owner: "my-org",
repository: "my-repo",
name: "priority: high",
color: "ff0000",
description: "Updated: Critical issues requiring immediate attention",
});

GitHub uses 6-character hex codes without the # prefix. Common colors:

  • d73a4a - Red (bugs)
  • 0075ca - Blue (documentation)
  • a2eeef - Light blue (features)
  • 7057ff - Purple (good first issue)
  • 008672 - Green (improvement)
  • e4e669 - Yellow (question)
const labels = [
{ name: "bug", color: "d73a4a", description: "Something isn't working" },
{ name: "enhancement", color: "a2eeef", description: "New feature" },
{ name: "documentation", color: "0075ca", description: "Documentation" },
];
for (const { name, color, description } of labels) {
yield* GitHub.Label(name, {
owner: "my-org",
repository: "my-repo",
name,
color,
description,
});
}

Changing the name creates a new label and deletes the old one.

// First deploy creates "wip"
const label = yield* GitHub.Label("work", {
owner: "my-org",
repository: "my-repo",
name: "wip",
color: "fbca04",
});
// Later deploy with same logical ID but different name replaces it
const label = yield* GitHub.Label("work", {
owner: "my-org",
repository: "my-repo",
name: "in-progress",
color: "fbca04",
});
const repo = yield* GitHub.Repository("api", {
owner: "my-org",
name: "api",
autoInit: true,
});
yield* GitHub.Label("bug", {
owner: repo.owner!,
repository: repo.name!,
name: "bug",
color: "d73a4a",
});

Source: packages/github/src/ListIssueComments.ts

List one page of the comments on an issue or pull request (issues.listComments), oldest first. Pass a pull request’s number as issue_number.

Provide GitHub.ListIssueCommentsHttp on a Worker or Function, or GitHub.ListIssueCommentsLocal on an Action.

ListIssueComments: Listing Comments at Runtime

Section titled “ListIssueComments: Listing Comments at Runtime”
const listComments = yield* GitHub.ListIssueComments(yield* Repo);
const comments = yield* listComments({ issue_number: 7, per_page: 100 });

Source: packages/github/src/ListIssueCommentsHttp.ts Kind: Layer · Provides: GitHub.ListIssueComments

Token-backed implementation of ListIssueComments. Provide it on a Worker or Function: it captures a GitHub.PersonalAccessToken for the host and binds the token and the repository into it.

Source: packages/github/src/ListIssueCommentsLocal.ts Kind: Layer · Provides: GitHub.ListIssueComments

Implementation of ListIssueComments with the provider’s current credentials. Provide it on an Action or another deploy-time Effect.

Source: packages/github/src/ListIssues.ts

List one page of the repository’s issues (issues.listForRepo). GitHub includes pull requests in this list; they carry a pull_request key.

Provide GitHub.ListIssuesHttp on a Worker or Function, or GitHub.ListIssuesLocal on an Action.

const listIssues = yield* GitHub.ListIssues(yield* Repo);
const open = yield* listIssues({ state: "open", per_page: 100 });
const issues = open.filter((issue) => issue.pull_request === undefined);

Source: packages/github/src/ListIssuesHttp.ts Kind: Layer · Provides: GitHub.ListIssues

Token-backed implementation of ListIssues. Provide it on a Worker or Function: it captures a GitHub.PersonalAccessToken for the host and binds the token and the repository into it.

Source: packages/github/src/ListIssuesLocal.ts Kind: Layer · Provides: GitHub.ListIssues

Implementation of ListIssues with the provider’s current credentials. Provide it on an Action or another deploy-time Effect.

Source: packages/github/src/Milestone.ts

A GitHub milestone.

Milestone manages repository milestones for tracking issues and pull requests. Milestones are created on first deploy and updated in place on subsequent deploys when properties change.

Authentication is resolved via the GitHub Credentials service supplied by GitHub.providers() (env, stored PAT, gh CLI, or OAuth). The token needs repo scope for private repositories or public_repo for public ones.

Basic Milestone

const v1 = yield* GitHub.Milestone("v1", {
owner: "my-org",
repository: "my-repo",
title: "v1.0.0",
description: "First stable release",
});

Milestone with Due Date

yield* GitHub.Milestone("sprint-1", {
owner: "my-org",
repository: "my-repo",
title: "Sprint 1",
description: "Complete user authentication",
dueOn: "2026-12-31",
});

Deploy with the same logical ID and different properties to update the existing milestone in place.

yield* GitHub.Milestone("v2", {
owner: "my-org",
repository: "my-repo",
title: "v2.0.0",
description: "Updated: API redesign and performance improvements",
dueOn: "2027-06-30",
});

Close a Milestone

yield* GitHub.Milestone("v1", {
owner: "my-org",
repository: "my-repo",
title: "v1.0.0",
state: "closed",
});

Reopen a Milestone

yield* GitHub.Milestone("v1", {
owner: "my-org",
repository: "my-repo",
title: "v1.0.0",
state: "open",
});

Changing the title creates a new milestone and deletes the old one.

// First deploy creates "Q1 2026"
const milestone = yield* GitHub.Milestone("q1", {
owner: "my-org",
repository: "my-repo",
title: "Q1 2026",
});
// Later deploy with same logical ID but different title replaces it
const milestone = yield* GitHub.Milestone("q1", {
owner: "my-org",
repository: "my-repo",
title: "Q1 2027",
});
import * as Output from "alchemy/Output";
const repo = yield* GitHub.Repository("api", {
owner: "my-org",
name: "api",
autoInit: true,
});
yield* GitHub.Milestone("launch", {
owner: repo.owner!,
repository: Output.map(repo.fullName, (fullName) => fullName.split("/")[1]!),
title: "Initial Launch",
dueOn: "2026-12-31",
});

Source: packages/github/src/SearchIssues.ts

Search issues and pull requests in the bound repository (search.issuesAndPullRequests). The binding prefixes q with repo:{owner}/{name}. GitHub’s search index lags writes by a few seconds.

Provide GitHub.SearchIssuesHttp on a Worker or Function, or GitHub.SearchIssuesLocal on an Action.

const searchIssues = yield* GitHub.SearchIssues(yield* Repo);
const { items } = yield* searchIssues({ q: "is:open label:bug crash in:title" });

Source: packages/github/src/SearchIssuesHttp.ts Kind: Layer · Provides: GitHub.SearchIssues

Token-backed implementation of SearchIssues. Provide it on a Worker or Function: it captures a GitHub.PersonalAccessToken for the host and binds the token and the repository into it.

Source: packages/github/src/SearchIssuesLocal.ts Kind: Layer · Provides: GitHub.SearchIssues

Implementation of SearchIssues with the provider’s current credentials. Provide it on an Action or another deploy-time Effect.

Source: packages/github/src/UpdateIssue.ts

Update one issue by number (issues.update): state, title, body, labels, assignees. A missing issue fails with the typed IssueNotFound.

Provide GitHub.UpdateIssueHttp on a Worker or Function, or GitHub.UpdateIssueLocal on an Action.

const updateIssue = yield* GitHub.UpdateIssue(yield* Repo);
yield* updateIssue({
issue_number: 7,
state: "closed",
state_reason: "completed",
});

Source: packages/github/src/UpdateIssueHttp.ts Kind: Layer · Provides: GitHub.UpdateIssue

Token-backed implementation of UpdateIssue. Provide it on a Worker or Function: it captures a GitHub.PersonalAccessToken for the host and binds the token and the repository into it.

Source: packages/github/src/UpdateIssueLocal.ts Kind: Layer · Provides: GitHub.UpdateIssue

Implementation of UpdateIssue with the provider’s current credentials. Provide it on an Action or another deploy-time Effect.