From 806f2f658c61e7a4db8492ef6d49916f776d2df0 Mon Sep 17 00:00:00 2001 From: Kir_Antipov Date: Fri, 21 Apr 2023 11:34:09 +0000 Subject: [PATCH] Made class for easier access to GitHub-specific environment variables --- src/platforms/github/github-context.ts | 107 +++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 src/platforms/github/github-context.ts diff --git a/src/platforms/github/github-context.ts b/src/platforms/github/github-context.ts new file mode 100644 index 0000000..43e28b2 --- /dev/null +++ b/src/platforms/github/github-context.ts @@ -0,0 +1,107 @@ +import { getEnvironmentVariable } from "@/utils/environment"; +import { readFileSync } from "node:fs"; +import { GITHUB_API_URL as DEFAULT_GITHUB_API_URL } from "./github-api-client"; +import { GitHubRepositoryIdentifier } from "./github-repository"; +import { GitHubWebhookPayload } from "./github-webhook-payload"; + +/** + * The name of the environment variable that contains the path to the GitHub webhook payload file. + */ +const GITHUB_PAYLOAD_PATH = "GITHUB_EVENT_PATH"; + +/** + * The name of the environment variable that contains the repository name in the format "owner/repo". + */ +const GITHUB_REPOSITORY = "GITHUB_REPOSITORY"; + +/** + * The name of the environment variable that contains the GitHub API url. + */ +const GITHUB_API_URL = "GITHUB_API_URL"; + +/** + * The name of the environment variable that contains the Git ref associated with the workflow run. + */ +const GITHUB_REF = "GITHUB_REF"; + +/** + * The prefix for Git tag refs in the format "refs/tags/". + */ +const GITHUB_REF_TAG_PREFIX = "refs/tags/"; + +/** + * Represents an execution context of a GitHub action. + */ +export class GitHubContext { + /** + * A container for environment variables. + */ + private readonly _env: Record; + + /** + * Cached payload associated with the context. + */ + private _payload?: GitHubWebhookPayload; + + /** + * Constructs a new {@link GitHubContext} instance. + * + * @param env - An optional object containing environment variables. + */ + constructor(env?: Record) { + this._env = env; + } + + /** + * Gets the ref associated with the context, if available. + */ + get ref(): string | undefined { + return getEnvironmentVariable(GITHUB_REF, this._env); + } + + /** + * Gets the tag associated with the context, if available. + */ + get tag(): string | undefined { + const ref = this.ref; + return ref?.startsWith(GITHUB_REF_TAG_PREFIX) && ref.substring(GITHUB_REF_TAG_PREFIX.length); + } + + /** + * Gets the repository associated with the context, if available. + */ + get repo(): GitHubRepositoryIdentifier | undefined { + const repository = getEnvironmentVariable(GITHUB_REPOSITORY, this._env); + if (repository?.includes("/")) { + const [owner, repo] = repository.split("/"); + return { owner, repo }; + } + + return undefined; + } + + /** + * Gets the URL for the GitHub API associated with this context, if available; + * otherwise using the base URL (`"https://api.github.com"`). + */ + get apiUrl(): string { + return getEnvironmentVariable(GITHUB_API_URL, this._env) || DEFAULT_GITHUB_API_URL; + } + + /** + * Gets the payload associated with the context. + */ + get payload(): GitHubWebhookPayload { + if (this._payload) { + return this._payload; + } + + const path = getEnvironmentVariable(GITHUB_PAYLOAD_PATH, this._env); + try { + this._payload = JSON.parse(readFileSync(path, "utf8")); + } catch { + this._payload = {}; + } + return this._payload; + } +}