mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-12 21:03:05 -07:00
use github release artifacts instead of cloning repos when available (#9147)
This commit is contained in:
@@ -103,11 +103,11 @@ export function parseGitHubRepoForReleases(source: string): {
|
|||||||
return { owner, repo };
|
return { owner, repo };
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchFromGithub(
|
async function fetchReleaseFromGithub(
|
||||||
owner: string,
|
owner: string,
|
||||||
repo: string,
|
repo: string,
|
||||||
ref?: string,
|
ref?: string,
|
||||||
): Promise<{ assets: Asset[]; tag_name: string }> {
|
): Promise<GithubReleaseData> {
|
||||||
const endpoint = ref ? `releases/tags/${ref}` : 'releases/latest';
|
const endpoint = ref ? `releases/tags/${ref}` : 'releases/latest';
|
||||||
const url = `https://api.github.com/repos/${owner}/${repo}/${endpoint}`;
|
const url = `https://api.github.com/repos/${owner}/${repo}/${endpoint}`;
|
||||||
return await fetchJson(url);
|
return await fetchJson(url);
|
||||||
@@ -199,7 +199,7 @@ export async function checkForExtensionUpdate(
|
|||||||
}
|
}
|
||||||
const { owner, repo } = parseGitHubRepoForReleases(source);
|
const { owner, repo } = parseGitHubRepoForReleases(source);
|
||||||
|
|
||||||
const releaseData = await fetchFromGithub(
|
const releaseData = await fetchReleaseFromGithub(
|
||||||
owner,
|
owner,
|
||||||
repo,
|
repo,
|
||||||
installMetadata.ref,
|
installMetadata.ref,
|
||||||
@@ -228,7 +228,7 @@ export async function downloadFromGitHubRelease(
|
|||||||
const { owner, repo } = parseGitHubRepoForReleases(source);
|
const { owner, repo } = parseGitHubRepoForReleases(source);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const releaseData = await fetchFromGithub(owner, repo, ref);
|
const releaseData = await fetchReleaseFromGithub(owner, repo, ref);
|
||||||
if (!releaseData) {
|
if (!releaseData) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`No release data found for ${owner}/${repo} at tag ${ref}`,
|
`No release data found for ${owner}/${repo} at tag ${ref}`,
|
||||||
@@ -236,24 +236,36 @@ export async function downloadFromGitHubRelease(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const asset = findReleaseAsset(releaseData.assets);
|
const asset = findReleaseAsset(releaseData.assets);
|
||||||
if (!asset) {
|
let archiveUrl: string | undefined;
|
||||||
// If there are no release assets, then we just clone the repo using the
|
let isTar = false;
|
||||||
// ref the release points to.
|
let isZip = false;
|
||||||
await cloneFromGit(
|
if (asset) {
|
||||||
{
|
archiveUrl = asset.browser_download_url;
|
||||||
...installMetadata,
|
} else {
|
||||||
ref: releaseData.tag_name,
|
if (releaseData.tarball_url) {
|
||||||
},
|
archiveUrl = releaseData.tarball_url;
|
||||||
destination,
|
isTar = true;
|
||||||
|
} else if (releaseData.zipball_url) {
|
||||||
|
archiveUrl = releaseData.zipball_url;
|
||||||
|
isZip = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!archiveUrl) {
|
||||||
|
throw new Error(
|
||||||
|
`No assets found for release with tag ${releaseData.tag_name}`,
|
||||||
);
|
);
|
||||||
return releaseData.tag_name;
|
}
|
||||||
|
let downloadedAssetPath = path.join(
|
||||||
|
destination,
|
||||||
|
path.basename(new URL(archiveUrl).pathname),
|
||||||
|
);
|
||||||
|
if (isTar && !downloadedAssetPath.endsWith('.tar.gz')) {
|
||||||
|
downloadedAssetPath += '.tar.gz';
|
||||||
|
} else if (isZip && !downloadedAssetPath.endsWith('.zip')) {
|
||||||
|
downloadedAssetPath += '.zip';
|
||||||
}
|
}
|
||||||
|
|
||||||
const downloadedAssetPath = path.join(
|
await downloadFile(archiveUrl, downloadedAssetPath);
|
||||||
destination,
|
|
||||||
path.basename(asset.browser_download_url),
|
|
||||||
);
|
|
||||||
await downloadFile(asset.browser_download_url, downloadedAssetPath);
|
|
||||||
|
|
||||||
extractFile(downloadedAssetPath, destination);
|
extractFile(downloadedAssetPath, destination);
|
||||||
|
|
||||||
@@ -284,6 +296,13 @@ export async function downloadFromGitHubRelease(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface GithubReleaseData {
|
||||||
|
assets: Asset[];
|
||||||
|
tag_name: string;
|
||||||
|
tarball_url?: string;
|
||||||
|
zipball_url?: string;
|
||||||
|
}
|
||||||
|
|
||||||
interface Asset {
|
interface Asset {
|
||||||
name: string;
|
name: string;
|
||||||
browser_download_url: string;
|
browser_download_url: string;
|
||||||
@@ -326,9 +345,7 @@ export function findReleaseAsset(assets: Asset[]): Asset | undefined {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchJson(
|
async function fetchJson<T>(url: string): Promise<T> {
|
||||||
url: string,
|
|
||||||
): Promise<{ assets: Asset[]; tag_name: string }> {
|
|
||||||
const headers: { 'User-Agent': string; Authorization?: string } = {
|
const headers: { 'User-Agent': string; Authorization?: string } = {
|
||||||
'User-Agent': 'gemini-cli',
|
'User-Agent': 'gemini-cli',
|
||||||
};
|
};
|
||||||
@@ -348,7 +365,7 @@ async function fetchJson(
|
|||||||
res.on('data', (chunk) => chunks.push(chunk));
|
res.on('data', (chunk) => chunks.push(chunk));
|
||||||
res.on('end', () => {
|
res.on('end', () => {
|
||||||
const data = Buffer.concat(chunks).toString();
|
const data = Buffer.concat(chunks).toString();
|
||||||
resolve(JSON.parse(data) as { assets: Asset[]; tag_name: string });
|
resolve(JSON.parse(data) as T);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.on('error', reject);
|
.on('error', reject);
|
||||||
|
|||||||
Reference in New Issue
Block a user