Skip to content

Commit d863f36

Browse files
authored
feat(git): support GITHUB_TOKEN env var as netrc auth fallback (#1156)
* feat(git): support GITHUB_TOKEN env var as netrc auth fallback Adds a third auth path to setupGithubTokenNetrc, publish, and ensureGit so platforms that inject a pre-provisioned installation token (e.g. freestyle) can use HTTPS git auth without needing GITHUB_APP_CONFIGURED or GITHUB_APP_KEY. Priority order: 1. GITHUB_APP_CONFIGURED — self-provisions scoped tokens via GitHub App 2. GITHUB_APP_KEY — fetches token via admin API 3. GITHUB_TOKEN — writes the env var directly to ~/.netrc Made-with: Cursor * fix: let admin API token failure fall through to GITHUB_TOKEN When GITHUB_APP_KEY is set but getGitHubToken() returns undefined (e.g. admin API unavailable), the early return was silently skipping the GITHUB_TOKEN fallback. Invert the check so a successful token short-circuits while undefined falls through to the next branch. Made-with: Cursor
1 parent 4d91771 commit d863f36

1 file changed

Lines changed: 17 additions & 6 deletions

File tree

daemon/git.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const SOURCE_PATH = Deno.env.get("SOURCE_ASSET_PATH");
1818
const DEFAULT_TRACKING_BRANCH = Deno.env.get("DECO_TRACKING_BRANCH") ?? "main";
1919
const REPO_URL = Deno.env.get("DECO_REPO_URL");
2020
const GITHUB_APP_KEY = Deno.env.get("GITHUB_APP_KEY");
21+
const GITHUB_TOKEN = Deno.env.get("GITHUB_TOKEN");
2122
const BUILD_FILES_DIR = Deno.env.get("BUILD_FILES_DIR");
2223
const ADMIN_DOMAIN = "https://admin.deco.cx";
2324

@@ -249,7 +250,7 @@ export const publish = ({ build }: Options): Handler => {
249250
const author = body.author || { name: "decobot", email: "capy@deco.cx" };
250251
const message = body.message || `New release by ${author.name}`;
251252

252-
if (GITHUB_APP_CONFIGURED || GITHUB_APP_KEY) {
253+
if (GITHUB_APP_CONFIGURED || GITHUB_APP_KEY || GITHUB_TOKEN) {
253254
// Re-read the remote URL so we refresh the token for the correct repo
254255
// (important for self-hosted / external repos).
255256
const remoteUrl = await git.remote(["get-url", "origin"]).catch(
@@ -514,10 +515,20 @@ export const setupGithubTokenNetrc = async (
514515
}
515516

516517
// Fallback: fetch token via admin API
517-
const token = await getGitHubToken();
518-
if (token === undefined) return;
518+
if (GITHUB_APP_KEY) {
519+
const token = await getGitHubToken();
520+
if (token !== undefined) {
521+
await updateNetrc(token);
522+
return;
523+
}
524+
// token is undefined (e.g. admin API unavailable) — fall through to GITHUB_TOKEN
525+
}
519526

520-
await updateNetrc(token);
527+
// Fallback: use a pre-provisioned GITHUB_TOKEN injected by the platform
528+
// (e.g. freestyle environments where a scoped installation token is passed directly).
529+
if (GITHUB_TOKEN) {
530+
await updateNetrc(GITHUB_TOKEN);
531+
}
521532
};
522533

523534
/**
@@ -677,7 +688,7 @@ export const ensureGit = async ({
677688
? parseGitHubOwnerRepo(effectiveRepoUrl) ?? undefined
678689
: undefined;
679690

680-
if (GITHUB_APP_CONFIGURED || GITHUB_APP_KEY) {
691+
if (GITHUB_APP_CONFIGURED || GITHUB_APP_KEY || GITHUB_TOKEN) {
681692
await setupGithubTokenNetrc(repoOverride);
682693
}
683694

@@ -686,7 +697,7 @@ export const ensureGit = async ({
686697
return;
687698
}
688699

689-
const useHttps = GITHUB_APP_CONFIGURED || GITHUB_APP_KEY;
700+
const useHttps = GITHUB_APP_CONFIGURED || GITHUB_APP_KEY || GITHUB_TOKEN;
690701
const cloneUrl = repoUrl ??
691702
REPO_URL ??
692703
(useHttps

0 commit comments

Comments
 (0)