Canarys HAPI: GITHUB
This guide covers all 88 implemented Canarys GITHUB HAPI functions available in the ScriptFabric Execution Console.
1. Authentication & Token Configuration
To access the GitHub API, you must configure a Personal Access Token (PAT) with appropriate scopes (e.g. repo, admin:org, workflow).
A) Configuring Token in Code (Local / Single Run)
At the very top of your script, you can set the token directly on the git namespace:
// Provide your token directly in the script:
git.token = "ghp_your_personal_access_token_here";
// The HAPI calls below will automatically use this token
const me = await git.getMe();
return me;
B) Configuring Token via Script Variable (Global / Secure)
This is the recommended approach to keep your token secure and encrypted:
- Go to Apps → ScriptFabric → Script Variables inside Jira.
- Create a new variable:
- Key:
GITHUB_TOKEN(must be exactly this case) - Value: Your actual GitHub PAT (e.g.,
ghp_...) - Scope:
global - Encrypt: Enabled (stores the token encrypted in the DB)
- Key:
- Save the variable.
The HAPI layer automatically loads and decrypts this token, allowing you to call
git.*methods directly without any setup at the top of your console scripts!
2. API Reference & Code Examples
Every function listed below is asynchronous, so remember to use await.
Repositories
git.getRepo(owner, repo)— Get detailed information about a single repository.const repo = await git.getRepo("owner", "repo-name"); return { name: repo.full_name, stars: repo.stargazers_count };git.listOrgRepos(org)— List all repositories in an organization.const repos = await git.listOrgRepos("org-name"); return repos.map(r => r.name);git.listUserRepos(username)— List public repositories for a user.const repos = await git.listUserRepos("octocat"); return repos.map(r => r.name);git.listMyRepos()— List repositories for the authenticated user.const repos = await git.listMyRepos(); return repos.map(r => r.full_name);git.createRepo(org, name, opts)— Create a new repository in an organization.const repo = await git.createRepo("org-name", "new-repo", { private: true, description: "Created via ScriptFabric" }); return repo.html_url;git.deleteRepo(owner, repo)— Delete a repository (requires delete repository scopes).await git.deleteRepo("owner", "repo-name"); return "Deleted successfully";git.updateRepo(owner, repo, opts)— Update repository settings.const repo = await git.updateRepo("owner", "repo-name", { has_wiki: false }); return repo;git.forkRepo(owner, repo)— Fork a repository.const fork = await git.forkRepo("owner", "repo-name"); return fork.html_url;git.listForks(owner, repo)— List forks of a repository.const forks = await git.listForks("owner", "repo-name"); return forks.map(f => f.full_name);git.getTopics(owner, repo)— Get repository topics.const topics = await git.getTopics("owner", "repo-name"); return topics.names;
Issues
git.listIssues(owner, repo, state)— List issues in a repository (state:open,closed,all).const issues = await git.listIssues("owner", "repo-name", "open"); return issues.map(i => ({ number: i.number, title: i.title }));git.getIssue(owner, repo, number)— Get details of a single issue.const issue = await git.getIssue("owner", "repo-name", 42); return issue.body;git.createIssue(owner, repo, title, body, opts)— Create a new issue.const issue = await git.createIssue("owner", "repo-name", "Bug: Button is broken", "Details of the issue...", { labels: ["bug"] }); return issue.number;git.updateIssue(owner, repo, number, opts)— Update an issue.const issue = await git.updateIssue("owner", "repo-name", 42, { title: "Updated bug title" }); return issue;git.closeIssue(owner, repo, number)— Close an issue.const issue = await git.closeIssue("owner", "repo-name", 42); return issue.state;git.listIssueComments(owner, repo, number)— List comments on an issue.const comments = await git.listIssueComments("owner", "repo-name", 42); return comments.map(c => c.body);git.addIssueComment(owner, repo, number, body)— Add a comment to an issue.const comment = await git.addIssueComment("owner", "repo-name", 42, "Checking on this issue..."); return comment.id;git.addIssueLabels(owner, repo, number, labels)— Add labels to an issue.const res = await git.addIssueLabels("owner", "repo-name", 42, ["priority:high"]); return res;git.assignIssue(owner, repo, number, assignees)— Assign users to an issue.const res = await git.assignIssue("owner", "repo-name", 42, ["username1"]); return res;
Pull Requests
git.listPRs(owner, repo, state)— List pull requests.const prs = await git.listPRs("owner", "repo-name", "open"); return prs.map(p => p.title);git.getPR(owner, repo, number)— Get pull request details.const pr = await git.getPR("owner", "repo-name", 101); return pr.mergeable;git.createPR(owner, repo, title, head, base, body)— Create a pull request.const pr = await git.createPR("owner", "repo-name", "Feature: Login", "feature-branch", "main", "PR body..."); return pr.number;git.mergePR(owner, repo, number, method)— Merge a pull request (method:merge,squash,rebase).const res = await git.mergePR("owner", "repo-name", 101, "squash"); return res.message;git.closePR(owner, repo, number)— Close a pull request.const pr = await git.closePR("owner", "repo-name", 101); return pr.state;git.listPRFiles(owner, repo, number)— List files changed in a PR.const files = await git.listPRFiles("owner", "repo-name", 101); return files.map(f => f.filename);git.listPRReviews(owner, repo, number)— List PR reviews.const reviews = await git.listPRReviews("owner", "repo-name", 101); return reviews.map(r => r.state);git.addPRReview(owner, repo, number, body, event)— Add a PR review (event:APPROVE,REQUEST_CHANGES,COMMENT).const review = await git.addPRReview("owner", "repo-name", 101, "Looks great!", "APPROVE"); return review.id;git.requestPRReviewers(owner, repo, number, reviewers)— Request reviewers for a PR.const res = await git.requestPRReviewers("owner", "repo-name", 101, ["reviewer-username"]); return res;
Branches
git.listBranches(owner, repo)— List all branches in a repository.const branches = await git.listBranches("owner", "repo-name"); return branches.map(b => b.name);git.getBranch(owner, repo, branch)— Get branch details.const branch = await git.getBranch("owner", "repo-name", "main"); return branch.commit.sha;git.createBranch(owner, repo, name, fromSha)— Create a new branch from a SHA.const ref = await git.createBranch("owner", "repo-name", "new-feature", "abcdef1234567890..."); return ref.ref;git.deleteBranch(owner, repo, branch)— Delete a branch.await git.deleteBranch("owner", "repo-name", "old-feature"); return "Branch deleted";git.protectBranch(owner, repo, branch, opts)— Protect a branch.const rules = await git.protectBranch("owner", "repo-name", "main", { required_status_checks: { strict: true, contexts: ["build-test"] }, enforce_admins: true, required_pull_request_reviews: { dismiss_stale_reviews: true } }); return rules;git.getDefaultBranch(owner, repo)— Get the default branch name (e.g.mainormaster).const branchName = await git.getDefaultBranch("owner", "repo-name"); return branchName; // Returns "main"
Commits
git.listCommits(owner, repo, branch)— List recent commits on a branch.const commits = await git.listCommits("owner", "repo-name", "main"); return commits.map(c => c.commit.message);git.getCommit(owner, repo, sha)— Get details of a single commit.const commit = await git.getCommit("owner", "repo-name", "abcdef..."); return commit.files.map(f => f.filename);git.compareCommits(owner, repo, base, head)— Compare two commits/branches.const comparison = await git.compareCommits("owner", "repo-name", "main", "feature"); return { status: comparison.status, totalCommits: comparison.total_commits };git.getCommitStatuses(owner, repo, sha)— Get CI/CD build statuses for a commit.const statuses = await git.getCommitStatuses("owner", "repo-name", "abcdef..."); return statuses.map(s => `${s.context}: ${s.state}`);
Releases
git.listReleases(owner, repo)— List all releases.const releases = await git.listReleases("owner", "repo-name"); return releases.map(r => r.name);git.getLatestRelease(owner, repo)— Get the latest release.const release = await git.getLatestRelease("owner", "repo-name"); return release.tag_name;git.getRelease(owner, repo, id)— Get a release by its ID.const release = await git.getRelease("owner", "repo-name", 123456); return release.body;git.createRelease(owner, repo, tag, name, body, opts)— Create a release.const release = await git.createRelease("owner", "repo-name", "v1.0.0", "Release 1.0", "Release notes...", { draft: false }); return release.id;git.deleteRelease(owner, repo, id)— Delete a release by ID.await git.deleteRelease("owner", "repo-name", 123456); return "Release deleted";
Labels & Milestones
git.listLabels(owner, repo)— List all labels.const labels = await git.listLabels("owner", "repo-name"); return labels.map(l => l.name);git.createLabel(owner, repo, name, color, desc)— Create a label.const label = await git.createLabel("owner", "repo-name", "priority:urgent", "ff0000", "Critical action required"); return label.name;git.deleteLabel(owner, repo, name)— Delete a label.await git.deleteLabel("owner", "repo-name", "priority:urgent"); return "Label deleted";git.listMilestones(owner, repo)— List milestones.const milestones = await git.listMilestones("owner", "repo-name"); return milestones.map(m => m.title);git.createMilestone(owner, repo, title, opts)— Create a milestone.const milestone = await git.createMilestone("owner", "repo-name", "Sprint 1", { description: "First sprint goals" }); return milestone.number;git.closeMilestone(owner, repo, number)— Close a milestone.const milestone = await git.closeMilestone("owner", "repo-name", 1); return milestone.state;
GitHub Actions (Workflows)
git.listWorkflows(owner, repo)— List all GitHub Action workflows.const workflows = await git.listWorkflows("owner", "repo-name"); return workflows.workflows.map(w => w.name);git.listWorkflowRuns(owner, repo, workflowId)— List runs for a workflow.const runs = await git.listWorkflowRuns("owner", "repo-name", "build.yml"); return runs.workflow_runs.map(r => `${r.id}: ${r.status}`);git.getWorkflowRun(owner, repo, runId)— Get detailed status of a run.const run = await git.getWorkflowRun("owner", "repo-name", 987654); return { status: run.status, conclusion: run.conclusion };git.triggerWorkflow(owner, repo, workflowId, ref, inputs)— Trigger aworkflow_dispatchrun.await git.triggerWorkflow("owner", "repo-name", "deploy.yml", "main", { environment: "staging" }); return "Workflow triggered successfully";git.cancelWorkflowRun(owner, repo, runId)— Cancel a running workflow.await git.cancelWorkflowRun("owner", "repo-name", 987654); return "Workflow run cancelled";git.listRunArtifacts(owner, repo, runId)— List artifacts from a run.const artifacts = await git.listRunArtifacts("owner", "repo-name", 987654); return artifacts.artifacts.map(a => a.name);git.listSecrets(owner, repo)— List repository Action secrets (names only).const secrets = await git.listSecrets("owner", "repo-name"); return secrets.secrets.map(s => s.name);
Organizations & Teams
git.getOrg(org)— Get organization details.const org = await git.getOrg("org-name"); return org.description;git.listOrgMembers(org)— List members in an organization.const members = await git.listOrgMembers("org-name"); return members.map(m => m.login);git.listTeams(org)— List teams in an organization.const teams = await git.listTeams("org-name"); return teams.map(t => t.slug);git.getTeam(org, slug)— Get a team slug details.const team = await git.getTeam("org-name", "dev-team"); return team.description;git.listTeamMembers(org, slug)— List members of a team.const members = await git.listTeamMembers("org-name", "dev-team"); return members.map(m => m.login);git.listTeamRepos(org, slug)— List repositories a team has access to.const repos = await git.listTeamRepos("org-name", "dev-team"); return repos.map(r => r.full_name);git.addTeamMember(org, slug, username)— Add a member to a team.const res = await git.addTeamMember("org-name", "dev-team", "github-username"); return res.state;git.removeTeamMember(org, slug, username)— Remove a member from a team.await git.removeTeamMember("org-name", "dev-team", "github-username"); return "Removed from team";
Users
git.getMe()— Get profile of the authenticated user.const profile = await git.getMe(); return { username: profile.login, name: profile.name };git.getUser(username)— Get a user's public profile details.const user = await git.getUser("octocat"); return user.company;git.listFollowers(username)— List followers.const followers = await git.listFollowers("octocat"); return followers.map(f => f.login);git.listFollowing(username)— List who a user follows.const following = await git.listFollowing("octocat"); return following.map(f => f.login);git.checkFollowing(username, target)— Check if user follows target.const isFollowing = await git.checkFollowing("octocat", "github-username"); return isFollowing;
File Contents
git.getFile(owner, repo, path, ref)— Get file metadata and base64 content.const file = await git.getFile("owner", "repo-name", "README.md", "main"); return file.sha;git.getFileDecoded(owner, repo, path, ref)— Get decoded file content directly.const content = await git.getFileDecoded("owner", "repo-name", "README.md", "main"); console.log("README content:\n" + content); return content;git.createFile(owner, repo, path, message, content, branch)— Create a file.const file = await git.createFile("owner", "repo-name", "src/hello.txt", "Initial commit", "Hello World!", "main"); return file.content.sha;git.updateFile(owner, repo, path, message, content, sha, branch)— Update a file (requires file SHA).const file = await git.updateFile("owner", "repo-name", "src/hello.txt", "Update content", "New Content", "file-sha-here...", "main"); return file.content.sha;git.deleteFile(owner, repo, path, message, sha, branch)— Delete a file.await git.deleteFile("owner", "repo-name", "src/hello.txt", "Deleting file", "file-sha-here...", "main"); return "File deleted";git.listDirectory(owner, repo, path, ref)— List directory contents.const items = await git.listDirectory("owner", "repo-name", "src", "main"); return items.map(i => `${i.type}: ${i.name}`);
Search
git.searchRepos(query)— Search for repositories.const res = await git.searchRepos("topic:jira"); return res.items.map(r => r.full_name);git.searchIssues(query)— Search for issues & PRs.const res = await git.searchIssues("repo:owner/repo state:open label:bug"); return res.items.map(i => i.title);git.searchCode(query)— Search code.const res = await git.searchCode("filename:package.json lodash"); return res.items.map(i => i.repository.full_name);git.searchUsers(query)— Search users.const res = await git.searchUsers("location:bangalore"); return res.items.map(u => u.login);git.searchCommits(query)— Search commits.const res = await git.searchCommits("org:org-name merge:true"); return res.items.map(c => c.commit.message);
Webhooks
git.listWebhooks(owner, repo)— List webhooks.const hooks = await git.listWebhooks("owner", "repo-name"); return hooks.map(h => h.config.url);git.createWebhook(owner, repo, url, events, secret)— Create a webhook.const hook = await git.createWebhook("owner", "repo-name", "https://example.com/webhook", ["push", "pull_request"], "secret-token"); return hook.id;git.deleteWebhook(owner, repo, hookId)— Delete a webhook.await git.deleteWebhook("owner", "repo-name", 123456); return "Webhook deleted";git.pingWebhook(owner, repo, hookId)— Ping/Test a webhook.await git.pingWebhook("owner", "repo-name", 123456); return "Webhook pinged";
Deployments
git.listDeployments(owner, repo)— List deployments.const deployments = await git.listDeployments("owner", "repo-name"); return deployments.map(d => `${d.id}: ${d.environment}`);git.createDeployment(owner, repo, ref, env, opts)— Create a deployment.const deploy = await git.createDeployment("owner", "repo-name", "main", "production", { description: "Deploying main to prod" }); return deploy.id;git.getDeploymentStatuses(owner, repo, deployId)— Get deployment statuses.const statuses = await git.getDeploymentStatuses("owner", "repo-name", 123456); return statuses.map(s => s.state);git.createDeploymentStatus(owner, repo, deployId, state)— Create a deployment status (success,failure,inactive, etc.).const status = await git.createDeploymentStatus("owner", "repo-name", 123456, "success"); return status.id;