Skip to content

Commit 944b187

Browse files
authored
feat: gather deployment git meta from the build server (#2392)
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.
1 parent a5dd638 commit 944b187

File tree

2 files changed

+59
-49
lines changed

2 files changed

+59
-49
lines changed

packages/cli-v3/src/utilities/gitMeta.ts

Lines changed: 54 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ import { x } from "tinyexec";
66
import { GitMeta } from "@trigger.dev/core/v3";
77

88
export async function createGitMeta(directory: string): Promise<GitMeta | undefined> {
9-
// First try to get metadata from GitHub Actions environment
10-
const githubMeta = await getGitHubActionsMeta();
11-
if (githubMeta) {
12-
return githubMeta;
9+
if (isGitHubApp()) {
10+
return getGitHubAppMeta();
11+
}
12+
13+
if (isGitHubActions()) {
14+
return getGitHubActionsMeta();
1315
}
1416

1517
// Fall back to git commands for local development
@@ -31,19 +33,14 @@ export async function createGitMeta(directory: string): Promise<GitMeta | undefi
3133
const dirty = dirtyResult.value;
3234
const commit = commitResult.value;
3335

34-
// Get the pull request number from process.env (GitHub Actions)
35-
const pullRequestNumber: number | undefined = process.env.GITHUB_PULL_REQUEST_NUMBER
36-
? parseInt(process.env.GITHUB_PULL_REQUEST_NUMBER)
37-
: undefined;
38-
3936
return {
37+
source: "local",
4038
remoteUrl: remoteUrl ?? undefined,
4139
commitAuthorName: commit.author.name,
4240
commitMessage: commit.subject,
4341
commitRef: commit.branch,
4442
commitSha: commit.hash,
4543
dirty,
46-
pullRequestNumber,
4744
};
4845
}
4946

@@ -86,27 +83,6 @@ async function parseGitConfig(configPath: string) {
8683
}
8784
}
8885

89-
function pluckRemoteUrls(gitConfig: { [key: string]: any }): { [key: string]: string } | undefined {
90-
const remoteUrls: { [key: string]: string } = {};
91-
92-
for (const key of Object.keys(gitConfig)) {
93-
if (key.includes("remote")) {
94-
// ex. remote "origin" — matches origin
95-
const remoteName = key.match(/(?<=").*(?=")/g)?.[0];
96-
const remoteUrl = gitConfig[key]?.url;
97-
if (remoteName && remoteUrl) {
98-
remoteUrls[remoteName] = remoteUrl;
99-
}
100-
}
101-
}
102-
103-
if (Object.keys(remoteUrls).length === 0) {
104-
return;
105-
}
106-
107-
return remoteUrls;
108-
}
109-
11086
function pluckOriginUrl(gitConfig: { [key: string]: any }): string | undefined {
11187
// Assuming "origin" is the remote url that the user would want to use
11288
return gitConfig['remote "origin"']?.url;
@@ -129,40 +105,39 @@ function errorToString(err: unknown): string {
129105
return err instanceof Error ? err.message : String(err);
130106
}
131107

132-
function isGitHubActions(): boolean {
133-
return process.env.GITHUB_ACTIONS === "true";
108+
function isGitHubActions() {
109+
// GH Actions CI sets these env variables
110+
return (
111+
process.env.GITHUB_ACTIONS === "true" &&
112+
process.env.GITHUB_SHA !== undefined &&
113+
process.env.GITHUB_REF !== undefined
114+
);
134115
}
135116

136-
async function getGitHubActionsMeta(): Promise<GitMeta | undefined> {
137-
if (!isGitHubActions()) {
138-
return undefined;
139-
}
140-
141-
// Required fields that should always be present in GitHub Actions
142-
if (!process.env.GITHUB_SHA || !process.env.GITHUB_REF) {
143-
return undefined;
144-
}
145-
117+
async function getGitHubActionsMeta(): Promise<GitMeta> {
146118
const remoteUrl =
147119
process.env.GITHUB_SERVER_URL && process.env.GITHUB_REPOSITORY
148120
? `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}.git`
149121
: undefined;
150122

151-
let commitRef = process.env.GITHUB_REF;
123+
// GITHUB_SHA and GITHUB_REF are both set in GH Actions CI
124+
const githubSha = process.env.GITHUB_SHA ?? "";
125+
const githubRef = process.env.GITHUB_REF ?? "";
126+
127+
// For push events, GITHUB_REF is fully qualified, e.g., "refs/heads/main"
128+
let commitRef = githubRef.replace(/^refs\/(heads|tags)\//, "");
152129
let commitMessage: string | undefined;
130+
let commitSha = githubSha;
153131
let pullRequestNumber: number | undefined;
154132
let pullRequestTitle: string | undefined;
155133
let pullRequestState: "open" | "closed" | "merged" | undefined;
156-
let commitSha = process.env.GITHUB_SHA;
157134

158135
if (process.env.GITHUB_EVENT_PATH) {
159136
try {
160137
const eventData = JSON.parse(await fs.readFile(process.env.GITHUB_EVENT_PATH, "utf8"));
161138

162139
if (process.env.GITHUB_EVENT_NAME === "push") {
163140
commitMessage = eventData.head_commit?.message;
164-
// For push events, GITHUB_REF will be like "refs/heads/main"
165-
commitRef = process.env.GITHUB_REF.replace(/^refs\/(heads|tags)\//, "");
166141
} else if (process.env.GITHUB_EVENT_NAME === "pull_request") {
167142
// For PRs, use the head commit info
168143
pullRequestTitle = eventData.pull_request?.title;
@@ -189,11 +164,11 @@ async function getGitHubActionsMeta(): Promise<GitMeta | undefined> {
189164
}
190165
} else {
191166
console.debug("No GITHUB_EVENT_PATH found");
192-
// If we can't read the event payload, at least try to clean up the ref
193-
commitRef = process.env.GITHUB_REF.replace(/^refs\/(heads|tags)\//, "");
194167
}
195168

196169
return {
170+
provider: "github",
171+
source: "github_actions",
197172
remoteUrl,
198173
commitSha,
199174
commitRef,
@@ -212,6 +187,36 @@ async function getGitHubActionsMeta(): Promise<GitMeta | undefined> {
212187
};
213188
}
214189

190+
function isGitHubApp() {
191+
// we set this env variable in our build server
192+
return process.env.TRIGGER_GITHUB_APP === "true";
193+
}
194+
195+
function getGitHubAppMeta(): GitMeta {
196+
return {
197+
provider: "github",
198+
source: "trigger_github_app",
199+
remoteUrl: process.env.GITHUB_REPOSITORY_URL,
200+
commitSha: process.env.GITHUB_HEAD_COMMIT_SHA,
201+
commitRef: process.env.GITHUB_REF?.replace(/^refs\/(heads|tags)\//, ""),
202+
commitMessage: process.env.GITHUB_HEAD_COMMIT_MESSAGE,
203+
commitAuthorName: process.env.GITHUB_HEAD_COMMIT_AUTHOR_NAME,
204+
pullRequestNumber: process.env.GITHUB_PULL_REQUEST_NUMBER
205+
? parseInt(process.env.GITHUB_PULL_REQUEST_NUMBER)
206+
: undefined,
207+
pullRequestTitle: process.env.GITHUB_PULL_REQUEST_TITLE,
208+
pullRequestState: process.env.GITHUB_PULL_REQUEST_STATE as
209+
| "open"
210+
| "closed"
211+
| "merged"
212+
| undefined,
213+
// the workspace is always clean as we clone the repo in the build server
214+
dirty: false,
215+
ghUsername: process.env.GITHUB_USERNAME,
216+
ghUserAvatarUrl: process.env.GITHUB_USER_AVATAR_URL,
217+
};
218+
}
219+
215220
async function getCommitMessage(
216221
directory: string,
217222
sha: string,

packages/core/src/v3/schemas/common.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,12 @@ export const TaskRun = z.object({
235235

236236
export type TaskRun = z.infer<typeof TaskRun>;
237237

238+
// newly added fields need to be optional for backwards compatibility
238239
export const GitMeta = z.object({
240+
provider: z.string().optional(),
241+
source: z.enum(["trigger_github_app", "github_actions", "local"]).optional(),
242+
ghUsername: z.string().optional(),
243+
ghUserAvatarUrl: z.string().optional(),
239244
commitAuthorName: z.string().optional(),
240245
commitMessage: z.string().optional(),
241246
commitRef: z.string().optional(),

0 commit comments

Comments
 (0)