Skip to content

Commit

Permalink
update error handling
Browse files Browse the repository at this point in the history
Signed-off-by: Savitha Raghunathan <[email protected]>
  • Loading branch information
savitharaghunathan committed Jan 21, 2025
1 parent b42043d commit d0d21d3
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 120 deletions.
154 changes: 84 additions & 70 deletions scripts/_download.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,21 @@ const GITHUB_API = "https://api.github.com";
* @returns {object}
*/
export async function getGitHubReleaseMetadata(org, repo, releaseTag) {
const url = `${GITHUB_API}/repos/${org}/${repo}/releases/tags/${releaseTag}`;
console.log(
`Fetching GitHub release metadata for ${yellow(`${org}/${repo}`)} release: ${yellow(releaseTag)}`,
);

const response = await fetch(url);
if (!response.ok) {
throw new Error(`Failed to fetch release metadata: ${response.statusText}`);
}
try {
const url = `${GITHUB_API}/repos/${org}/${repo}/releases/tags/${releaseTag}`;
console.log(
`Fetching GitHub release metadata for ${yellow(`${org}/${repo}`)} release: ${yellow(releaseTag)}`,
);

return await response.json();
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Failed to fetch release metadata: ${response.statusText}`);
}

return await response.json();
} catch (error) {
throw new Error(`Error in getGitHubReleaseMetadata: ${error.message}`);
}
}

/**
Expand All @@ -44,14 +48,22 @@ export async function getGitHubReleaseMetadata(org, repo, releaseTag) {
* @returns The release tag's commit sha
*/
export async function getGitHubReleaseTagSha(org, repo, releaseTag) {
const url = `${GITHUB_API}/repos/${org}/${repo}/commits/${releaseTag}`;
const response = await fetch(url, {
headers: {
Accept: "application/vnd.github.sha",
},
});

return await response.text();
try {
const url = `${GITHUB_API}/repos/${org}/${repo}/commits/${releaseTag}`;
const response = await fetch(url, {
headers: {
Accept: "application/vnd.github.sha",
},
});

if (!response.ok) {
throw new Error(`Failed to fetch release tag sha: ${response.statusText}`);
}

return await response.text();
} catch (error) {
throw new Error(`Error in getGitHubReleaseTagSha: ${error.message}`);
}
}

/**
Expand All @@ -60,22 +72,22 @@ export async function getGitHubReleaseTagSha(org, repo, releaseTag) {
* @returns {Promise<string>} sha256 hash of the response data
*/
async function streamResponseToFile(targetFile, fetchResponse) {
const reader = Readable.fromWeb(fetchResponse.body);
try {
const reader = Readable.fromWeb(fetchResponse.body);

// setup stream to file
const fileStream = fs.createWriteStream(targetFile);
const pipeToFile = pipeline(reader, fileStream);
// setup stream to file
const fileStream = fs.createWriteStream(targetFile);
const pipeToFile = pipeline(reader, fileStream);

// setup stream to calculate the sha256 hash of the file
const hash = createHash("sha256");
const pipeToHash = pipeline(reader, hash);
// setup stream to calculate the sha256 hash of the file
const hash = createHash("sha256");
const pipeToHash = pipeline(reader, hash);

// run them both, reject if either rejects, resolve with the hash
try {
// run them both, reject if either rejects, resolve with the hash
await Promise.all([pipeToFile, pipeToHash]);
return Promise.resolve(hash.digest("hex"));
} catch (e) {
return Promise.reject(e);
return hash.digest("hex");
} catch (error) {
throw new Error(`Error in streamResponseToFile: ${error.message}`);
}
}

Expand All @@ -86,31 +98,35 @@ export async function downloadAndExtractGitHubAsset(
arch,
chmod = false,
) {
const assetDir = join(target, `${platform}-${arch}`);
const assetFileName = join(assetDir, gitHubReleaseAsset.name);

await fs.ensureDir(assetDir);
try {
const assetDir = join(target, `${platform}-${arch}`);
const assetFileName = join(assetDir, gitHubReleaseAsset.name);

console.log(`Downloading asset: ${gitHubReleaseAsset.name}`);
const response = await fetch(gitHubReleaseAsset.browser_download_url);
if (!response.ok) {
throw new Error(`Failed to download ${gitHubReleaseAsset.name}: ${response.statusText}`);
}
const sha256 = await streamResponseToFile(assetFileName, response);
await fs.ensureDir(assetDir);

console.log(`Asset sha256: ${green(sha256)}`);
console.log(`Extracting to: ${assetDir}`);
const zipFile = await unzipper.Open.file(assetFileName);
await zipFile.extract({ path: assetDir });
console.log(`Downloading asset: ${gitHubReleaseAsset.name}`);
const response = await fetch(gitHubReleaseAsset.browser_download_url);
if (!response.ok) {
throw new Error(`Failed to download ${gitHubReleaseAsset.name}: ${response.statusText}`);
}
const sha256 = await streamResponseToFile(assetFileName, response);

const extractedFiles = await fs.readdir(assetDir);
extractedFiles.forEach(async (file) => {
if (chmod && extname(file) !== ".zip") {
chmodOwnerPlusX(join(assetDir, file));
console.log(`Asset sha256: ${green(sha256)}`);
console.log(`Extracting to: ${assetDir}`);
const zipFile = await unzipper.Open.file(assetFileName);
await zipFile.extract({ path: assetDir });

const extractedFiles = await fs.readdir(assetDir);
for (const file of extractedFiles) {
if (chmod && extname(file) !== ".zip") {
chmodOwnerPlusX(join(assetDir, file));
}
}
});

console.log(`Extracted: ${gitHubReleaseAsset.name}`);
console.log(`Extracted: ${gitHubReleaseAsset.name}`);
} catch (error) {
throw new Error(`Error in downloadAndExtractGitHubAsset: ${error.message}`);
}
}

export async function downloadGitHubRelease({
Expand Down Expand Up @@ -160,7 +176,7 @@ export async function downloadGitHubRelease({
console.log(`Metadata written to ${metaFile}`);
console.log(`All assets downloaded to: ${targetDirectory}`);
} catch (error) {
console.error("Error downloading the release:", error.message);
throw new Error(`Error in downloadGitHubRelease: ${error.message}`);
}
}

Expand All @@ -183,25 +199,21 @@ export async function downloadAndExtractTarGz({ targetDirectory, url, sha256 })

// If a sha256 is provided, verify against the downloaded file
console.log(`Asset sha256: ${green(downloadSha256)}`);
if (sha256) {
if (downloadSha256 === sha256) {
console.log(`${green("Verified!")} Asset's sha256 matches expected`);
} else {
throw new Error(
`Downloaded file ${targetFile} sha256 ${downloadSha256} does not match the expected sha256 ${sha256}`,
);
}
if (sha256 && downloadSha256 !== sha256) {
throw new Error(
`Downloaded file ${targetFile} sha256 ${downloadSha256} does not match the expected sha256 ${sha256}`,
);
}

// Extract the tar.gz file
console.log(`Extracting to ${targetDirectory}`);
tar.extract({
await tar.extract({
f: targetFile,
z: true,
cwd: targetDirectory,
});
} catch (error) {
console.error("Error downloading/extracting tar.gz:", error);
throw new Error(`Error in downloadAndExtractTarGz: ${error.message}`);
} finally {
console.groupEnd();
}
Expand Down Expand Up @@ -240,8 +252,7 @@ export async function downloadArtifact(url, name, outputDir, token) {
console.log(`Downloaded ${name} to ${assetFileName}`);
return assetFileName;
} catch (error) {
console.error(`Error downloading artifact ${name}:`, error.message);
throw error;
throw new Error(`Error in downloadArtifact: ${error.message}`);
}
}

Expand Down Expand Up @@ -284,8 +295,8 @@ export async function extractArtifact(filePath, tempDir, finalDir) {

console.log(`Extraction complete: ${filePath} -> ${finalDir}`);
} catch (error) {
console.error(`Error extracting artifact ${filePath}:`, error.message);
throw error;
console.error(`Error extracting artifact at ${filePath}:`, error.message);
throw new Error(`Failed to extract artifact: ${error.message}`);
}
}

Expand All @@ -294,9 +305,10 @@ export async function extractArtifact(filePath, tempDir, finalDir) {
*
* @param {string} targetDirectory - Directory to store downloaded artifacts
* @param {string} metaFile - Path to the metadata file
* @param {string} url - Base URL of the GitHub repository
* @param {string} org - GH org
* @param {string} repo - GH repo
* @param {string} workflow - Name of the workflow file
* @param {Array} assets - List of assets to downloa
* @param {Array} assets - List of assets to download
*/
export async function downloadWorkflowArtifacts({
targetDirectory,
Expand All @@ -309,8 +321,9 @@ export async function downloadWorkflowArtifacts({
const GITHUB_TOKEN = process.env.GITHUB_TOKEN;

if (!GITHUB_TOKEN) {
console.error("Error: GITHUB_TOKEN environment variable is not set.");
process.exit(1);
const errorMessage = "GITHUB_TOKEN environment variable is not set.";
console.error(errorMessage);
throw new Error(errorMessage);
}

try {
Expand Down Expand Up @@ -373,13 +386,14 @@ export async function downloadWorkflowArtifacts({
});
} catch (error) {
console.error(`Error processing artifact [${name}]:`, error.message);
throw new Error(`Failed to process artifact ${name}: ${error.message}`);
}
}

await fs.writeJson(metaFile, metadata, { spaces: 2 });
console.log(`Metadata written to ${metaFile}`);
} catch (error) {
console.error("Error downloading workflow artifacts:", error.message);
process.exit(1);
throw new Error(`Failed to download workflow artifacts: ${error.message}`);
}
}
97 changes: 47 additions & 50 deletions scripts/collect-assets.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,58 +16,55 @@ cwdToProjectRoot();
const DOWNLOAD_DIR = resolve("downloaded_assets");
await ensureDir(DOWNLOAD_DIR);

if (process.env.WORKFLOW && process.env.WORKFLOW !== "False") {
console.log("WORKFLOW environment variable is set. Downloading workflow artifacts...");
try {
if (process.env.WORKFLOW && process.env.WORKFLOW !== "False") {
console.log("WORKFLOW environment variable is set. Downloading workflow artifacts...");

// Download Kai assets via workflow artifacts
await downloadWorkflowArtifacts({
targetDirectory: join(DOWNLOAD_DIR, "kai/"),
metaFile: join(DOWNLOAD_DIR, "kai", "collect.json"),
org: "konveyor",
repo: "kai",
workflow: "build-and-push-binaries.yml",
assets: [
{ name: "java-deps.zip", chmod: false },
{ name: "kai-rpc-server.linux-aarch64.zip", platform: "linux", arch: "arm64", chmod: true },
{ name: "kai-rpc-server.linux-x86_64.zip", platform: "linux", arch: "x64", chmod: true },
{ name: "kai-rpc-server.macos-arm64.zip", platform: "darwin", arch: "arm64", chmod: true },
{ name: "kai-rpc-server.macos-x86_64.zip", platform: "darwin", arch: "x64", chmod: true },
{ name: "kai-rpc-server.windows-X64.zip", platform: "win32", arch: "x64", chmod: false },
],
});
} else {
console.log("WORKFLOW environment variable is not set. Downloading GitHub release assets...");

// Download Kai assets from GitHub release
await downloadGitHubRelease({
targetDirectory: join(DOWNLOAD_DIR, "kai/"),
metaFile: join(DOWNLOAD_DIR, "kai", "collect.json"),
// Download Kai assets via workflow artifacts
await downloadWorkflowArtifacts({
targetDirectory: join(DOWNLOAD_DIR, "kai/"),
metaFile: join(DOWNLOAD_DIR, "kai", "collect.json"),
org: "konveyor",
repo: "kai",
workflow: "build-and-push-binaries.yml",
assets: [
{ name: "java-deps.zip", chmod: false },
{ name: "kai-rpc-server.linux-aarch64.zip", platform: "linux", arch: "arm64", chmod: true },
{ name: "kai-rpc-server.linux-x86_64.zip", platform: "linux", arch: "x64", chmod: true },
{ name: "kai-rpc-server.macos-arm64.zip", platform: "darwin", arch: "arm64", chmod: true },
{ name: "kai-rpc-server.macos-x86_64.zip", platform: "darwin", arch: "x64", chmod: true },
{ name: "kai-rpc-server.windows-X64.zip", platform: "win32", arch: "x64", chmod: false },
],
});
} else {
console.log("WORKFLOW environment variable is not set. Downloading GitHub release assets...");

org: "konveyor",
repo: "kai",
releaseTag: "v0.0.4",
// Download Kai assets from GitHub release
await downloadGitHubRelease({
targetDirectory: join(DOWNLOAD_DIR, "kai/"),
metaFile: join(DOWNLOAD_DIR, "kai", "collect.json"),
org: "konveyor",
repo: "kai",
releaseTag: "v0.0.5",
assets: [
{ name: "java-deps.zip" },
{ name: "kai-rpc-server.linux-x86_64.zip", platform: "linux", arch: "x64", chmod: true },
{ name: "kai-rpc-server.linux-aarch64.zip", platform: "linux", arch: "arm64", chmod: true },
{ name: "kai-rpc-server.macos-x86_64.zip", platform: "darwin", arch: "x64", chmod: true },
{ name: "kai-rpc-server.macos-arm64.zip", platform: "darwin", arch: "arm64", chmod: true },
{ name: "kai-rpc-server.windows-x64.zip", platform: "win32", arch: "x64" },
{ name: "kai-rpc-server.windows-arm64.zip", platform: "win32", arch: "arm64" },
],
});
}

/*
Release asset filenames and nodejs equivalent platform/arch
platform: https://nodejs.org/docs/latest-v22.x/api/process.html#processplatform
arch: https://nodejs.org/docs/latest-v22.x/api/process.html#processarch
*/
assets: [
{ name: "java-deps.zip" },
{ name: "kai-rpc-server.linux-x86_64.zip", platform: "linux", arch: "x64", chmod: true },
{ name: "kai-rpc-server.linux-aarch64.zip", platform: "linux", arch: "arm64", chmod: true },
{ name: "kai-rpc-server.macos-x86_64.zip", platform: "darwin", arch: "x64", chmod: true },
{ name: "kai-rpc-server.macos-arm64.zip", platform: "darwin", arch: "arm64", chmod: true },
{ name: "kai-rpc-server.windows-x64.zip", platform: "win32", arch: "x64" },
{ name: "kai-rpc-server.windows-arm64.zip", platform: "win32", arch: "arm64" },
],
// Download jdt.ls
await downloadAndExtractTarGz({
targetDirectory: join(DOWNLOAD_DIR, "jdt.ls-1.38.0/"),
url: "https://download.eclipse.org/jdtls/milestones/1.38.0/jdt-language-server-1.38.0-202408011337.tar.gz",
sha256: "ba697788a19f2ba57b16302aba6b343c649928c95f76b0d170494ac12d17ac78",
});
} catch (error) {
console.error("Error during asset collection:", error.message);
process.exit(1);
}

// Download jdt.ls
// Base release url: https://download.eclipse.org/jdtls/milestones/1.38.0/
await downloadAndExtractTarGz({
targetDirectory: join(DOWNLOAD_DIR, "jdt.ls-1.38.0/"),
url: "https://download.eclipse.org/jdtls/milestones/1.38.0/jdt-language-server-1.38.0-202408011337.tar.gz",
sha256: "ba697788a19f2ba57b16302aba6b343c649928c95f76b0d170494ac12d17ac78",
});

0 comments on commit d0d21d3

Please sign in to comment.