GitHub
Use the Elsa.DevOps.GitHub extension to call GitHub from workflows in Elsa 3.8.0.
The Elsa.DevOps.GitHub extension adds server-side activities that call the GitHub REST API through Octokit, plus one activity for sending a GraphQL query. Use it when a workflow needs to inspect or update repositories, issues, pull requests, comments, labels, users, organizations, milestones, or gists.
The extension is host-side functionality. It does not add a GitHub connection editor or token-management page to Elsa Studio. If the Elsa Server connected to Studio registers the extension, the server can expose its activity descriptors to the generic activity picker.
Release boundary:
release/3.8.0includes three GitHub event watcher descriptors, but their execution path throwsNotImplementedException. Do not useWatchBranches,WatchIssues, orWatchPullRequestsas production triggers in this release. Use an HTTP webhook workflow and your own webhook validation instead.
Install and register the extension
Install the server-side package:
dotnet add package Elsa.DevOps.GitHubRegister it while composing Elsa:
builder.Services.AddElsa(elsa =>
{
elsa.UseGitHub();
});UseGitHub registers the extension feature and its singleton GitHubClientFactory. It does not configure a global token. Each GitHub activity receives its token through its Token input.
Provide the token safely
Every concrete GitHub activity inherits a Token input of type string. The runtime passes that value to the client factory, which creates an Octokit client with GitHub credentials and caches the client by the token value.
For code-first workflows, the shape is:
using Elsa.DevOps.GitHub.Activities.Issues;
using Elsa.Workflows;
using Elsa.Workflows.Activities;
using Elsa.Workflows.Contracts;
using Elsa.Workflows.Models;
public class CreateIssueWorkflow : WorkflowBase
{
protected override void Build(IWorkflowBuilder builder)
{
builder.Root = new Sequence
{
Activities =
{
new CreateIssue
{
Token = new Input<string>("token-from-your-secret-store"),
Owner = new Input<string>("elsa-workflows"),
Repository = new Input<string>("elsa-extensions"),
Title = new Input<string>("Created by Elsa"),
Body = new Input<string>("Created by a workflow.")
}
}
};
}
}The placeholder above is only a shape example. Do not commit a real token in a workflow definition or source file. Resolve it from your application's secret store and pass it as an expression or other protected input. See Secrets Management for Elsa's secret-reference and picker behavior.
Because the cache is process-local and keyed by the raw token, token ownership, tenant isolation, rotation, and eviction remain application concerns. Avoid logging the Token input or interpolating it into workflow output. Grant the token only the GitHub permissions required by the activities that the workflow can execute.
Choose an activity
The release includes these concrete activities. Their inputs and outputs are described by the activity descriptors, so the same names can appear in the generic Studio picker when the server exposes them.
Issues:
CreateIssue,GetIssue,UpdateIssue,DeleteIssue, andSearchIssues.DeleteIssuecloses the issue; GitHub does not permit this activity to delete it.Comments:
CreateComment,GetComment,UpdateComment, andDeleteCommentfor issue or pull-request comments.Labels:
AddLabelsandDeleteLabelfor issue or pull-request labels.Pull requests:
GetPullRequestandSearchPullRequests.Repositories:
GetRepository,GetBranch, andSearchBranches.Users:
AddAssignees,DeleteAssignees,GetAssignee,GetUser, andSearchAssignees.Organizations:
GetOrganizationandSearchOrganizationMembers.Milestones:
GetMilestoneandSearchMilestones.Gists:
GetGistandSearchGists.GraphQL:
ExecuteGraphQLQuery.
Most activities take Owner and Repository plus a resource-specific input, and return a typed Octokit model or search result. GetUser and the gist activities use their own identifiers; inspect the activity descriptor when binding expressions in Studio.
Example: create an issue
CreateIssue sends an issue creation request and exposes the created Issue as CreatedIssue. Its optional inputs include Body, Labels, MilestoneId, and Assignees.
In Studio, set these inputs as literals or expressions:
Set
Tokento a protected secret expression.Set
Owner,Repository, andTitle.Add
Body, labels, a milestone ID, or assignee usernames when needed.Use the
CreatedIssueoutput in a later activity or branch.
The same pattern applies to update, comment, label, and assignee activities: the activity calls GitHub during execution and exposes the returned Octokit model through its output.
Search and pagination
SearchIssues and SearchPullRequests accept GitHub search syntax through Query. They also expose optional Page, PageSize, Sort, and SortDirection inputs. SearchPullRequests uses GitHub's issue search API and adds type:pr to the query when it is not already present.
SearchBranches loads the repository's branches and applies its optional NameFilter in memory using a case-insensitive partial match. It is not a server-side GitHub search query.
Treat search results as paged external data. Choose a page size deliberately, and do not assume that one activity invocation returns every matching item.
Execute a GraphQL query
ExecuteGraphQLQuery sends an authorized POST request to GitHub's fixed https://api.github.com/graphql endpoint. It accepts a query string and an optional Variables string, then exposes the response root as the JsonElement output QueryResult.
For example, a query without variables can be shaped like this:
The release implementation serializes Variables as a JSON string property in the request object; it does not parse that input into a JSON object. Verify the payload against GitHub's GraphQL contract before relying on variables in a production workflow. The activity also does not expose a configurable GraphQL base URL.
Webhook watchers: visible, but not executable in 3.8.0
The package contains these trigger descriptors:
WatchBrancheswithOwner,Repository, andBranchEvent.WatchIssueswithOwner,Repository, andIssueEvent.WatchPullRequestswithOwner,Repository, andPullRequestEvent.
They inherit from GitHubTriggerActivity, whose ExecuteAsync method throws NotImplementedException("Event subscription requires WebHook implementation."). The descriptors and README therefore do not represent a working webhook subscription implementation in this release. For a working inbound design, receive the GitHub webhook through an Elsa HTTP Endpoint, authenticate and validate the GitHub signature in your host or front door, then map the payload into workflow inputs. Review HTTP endpoint security before publishing that endpoint.
Errors, rate limits, and retries
The built-in activities await Octokit calls directly and do not catch or translate GitHub API errors. Authentication failures, missing permissions, missing resources, validation errors, network failures, and rate-limit responses therefore surface through normal Elsa activity fault handling.
Use workflow error handling and an explicit retry policy for transient failures. Do not blindly retry mutations such as issue creation or comment creation: combine retries with an application-level idempotency strategy when a duplicate GitHub change would be harmful. Monitor GitHub's rate-limit response headers and keep search page sizes within the limits of your GitHub plan.
Studio and deployment boundaries
The extension is registered on the Elsa Server, not in a standalone Studio client.
The release contains no GitHub-specific Studio administration or connection editor.
A server that does not register
UseGitHubcannot execute these activity types, even if a workflow definition contains them.The package's
GitHubDevOpsShellFeatureis not a working Studio setup path in this release; its service configuration throwsNotImplementedException.The release package contains no
GetReleaseorSearchReleasesactivity, despite those names appearing in the bundled README. Do not build a 3.8.0 workflow around those names.
Troubleshooting
The activities are missing from Studio
Confirm that Elsa.DevOps.GitHub is installed and UseGitHub() is called by the Elsa Server. Then check the server's activity descriptor response and ensure Studio is connected to that server. Registering a package only in the Studio client does not make the activity executable.
GitHub returns 401 or 403
Check that the token is resolved to a non-empty value at runtime, has access to the target repository, and has the permissions required by the operation. For organization-owned repositories, also check organization policies and token approval requirements.
A watcher faults immediately
That is expected for release/3.8.0: the watcher base class is intentionally unimplemented. Replace it with an authenticated HTTP webhook workflow or implement and register a separate custom trigger.
A search misses results
Check the GitHub search syntax, Page, PageSize, sort inputs, and rate-limit responses. For pull requests, remember that the activity adds type:pr to the query when needed.
Release source
This guide is validated against elsa-extensions release/3.8.0 at 335a264. The key implementation points are:
Last updated