From 4f555ae6bcb070af7fa9e245526011484286445c Mon Sep 17 00:00:00 2001 From: myftija Date: Wed, 13 Aug 2025 12:10:00 +0200 Subject: [PATCH] feat: gather deployment git meta from the build server This PR adapts the deployment command to also evaluate build server env variables when creating the git meta. The build server will initially only support deployments triggered by the github app, but we might add other git providers in the future. Sticking to the GH actions naming convention for the env variables set by the build server in favor of consistency. --- packages/cli-v3/src/utilities/gitMeta.ts | 103 ++++++++++++----------- packages/core/src/v3/schemas/common.ts | 5 ++ 2 files changed, 59 insertions(+), 49 deletions(-) diff --git a/packages/cli-v3/src/utilities/gitMeta.ts b/packages/cli-v3/src/utilities/gitMeta.ts index 91e59a8781..90ced43920 100644 --- a/packages/cli-v3/src/utilities/gitMeta.ts +++ b/packages/cli-v3/src/utilities/gitMeta.ts @@ -6,10 +6,12 @@ import { x } from "tinyexec"; import { GitMeta } from "@trigger.dev/core/v3"; export async function createGitMeta(directory: string): Promise { - // First try to get metadata from GitHub Actions environment - const githubMeta = await getGitHubActionsMeta(); - if (githubMeta) { - return githubMeta; + if (isGitHubApp()) { + return getGitHubAppMeta(); + } + + if (isGitHubActions()) { + return getGitHubActionsMeta(); } // Fall back to git commands for local development @@ -31,19 +33,14 @@ export async function createGitMeta(directory: string): Promise { - if (!isGitHubActions()) { - return undefined; - } - - // Required fields that should always be present in GitHub Actions - if (!process.env.GITHUB_SHA || !process.env.GITHUB_REF) { - return undefined; - } - +async function getGitHubActionsMeta(): Promise { const remoteUrl = process.env.GITHUB_SERVER_URL && process.env.GITHUB_REPOSITORY ? `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}.git` : undefined; - let commitRef = process.env.GITHUB_REF; + // GITHUB_SHA and GITHUB_REF are both set in GH Actions CI + const githubSha = process.env.GITHUB_SHA ?? ""; + const githubRef = process.env.GITHUB_REF ?? ""; + + // For push events, GITHUB_REF is fully qualified, e.g., "refs/heads/main" + let commitRef = githubRef.replace(/^refs\/(heads|tags)\//, ""); let commitMessage: string | undefined; + let commitSha = githubSha; let pullRequestNumber: number | undefined; let pullRequestTitle: string | undefined; let pullRequestState: "open" | "closed" | "merged" | undefined; - let commitSha = process.env.GITHUB_SHA; if (process.env.GITHUB_EVENT_PATH) { try { @@ -161,8 +138,6 @@ async function getGitHubActionsMeta(): Promise { if (process.env.GITHUB_EVENT_NAME === "push") { commitMessage = eventData.head_commit?.message; - // For push events, GITHUB_REF will be like "refs/heads/main" - commitRef = process.env.GITHUB_REF.replace(/^refs\/(heads|tags)\//, ""); } else if (process.env.GITHUB_EVENT_NAME === "pull_request") { // For PRs, use the head commit info pullRequestTitle = eventData.pull_request?.title; @@ -189,11 +164,11 @@ async function getGitHubActionsMeta(): Promise { } } else { console.debug("No GITHUB_EVENT_PATH found"); - // If we can't read the event payload, at least try to clean up the ref - commitRef = process.env.GITHUB_REF.replace(/^refs\/(heads|tags)\//, ""); } return { + provider: "github", + source: "github_actions", remoteUrl, commitSha, commitRef, @@ -212,6 +187,36 @@ async function getGitHubActionsMeta(): Promise { }; } +function isGitHubApp() { + // we set this env variable in our build server + return process.env.TRIGGER_GITHUB_APP === "true"; +} + +function getGitHubAppMeta(): GitMeta { + return { + provider: "github", + source: "trigger_github_app", + remoteUrl: process.env.GITHUB_REPOSITORY_URL, + commitSha: process.env.GITHUB_HEAD_COMMIT_SHA, + commitRef: process.env.GITHUB_REF?.replace(/^refs\/(heads|tags)\//, ""), + commitMessage: process.env.GITHUB_HEAD_COMMIT_MESSAGE, + commitAuthorName: process.env.GITHUB_HEAD_COMMIT_AUTHOR_NAME, + pullRequestNumber: process.env.GITHUB_PULL_REQUEST_NUMBER + ? parseInt(process.env.GITHUB_PULL_REQUEST_NUMBER) + : undefined, + pullRequestTitle: process.env.GITHUB_PULL_REQUEST_TITLE, + pullRequestState: process.env.GITHUB_PULL_REQUEST_STATE as + | "open" + | "closed" + | "merged" + | undefined, + // the workspace is always clean as we clone the repo in the build server + dirty: false, + ghUsername: process.env.GITHUB_USERNAME, + ghUserAvatarUrl: process.env.GITHUB_USER_AVATAR_URL, + }; +} + async function getCommitMessage( directory: string, sha: string, diff --git a/packages/core/src/v3/schemas/common.ts b/packages/core/src/v3/schemas/common.ts index 41a095648f..c1eb943fed 100644 --- a/packages/core/src/v3/schemas/common.ts +++ b/packages/core/src/v3/schemas/common.ts @@ -235,7 +235,12 @@ export const TaskRun = z.object({ export type TaskRun = z.infer; +// newly added fields need to be optional for backwards compatibility export const GitMeta = z.object({ + provider: z.string().optional(), + source: z.enum(["trigger_github_app", "github_actions", "local"]).optional(), + ghUsername: z.string().optional(), + ghUserAvatarUrl: z.string().optional(), commitAuthorName: z.string().optional(), commitMessage: z.string().optional(), commitRef: z.string().optional(),