diff --git a/dist/index.js b/dist/index.js index 5d50de4..bad1e73 100644 --- a/dist/index.js +++ b/dist/index.js @@ -8358,6 +8358,7 @@ const core = __importStar(__webpack_require__(470)); const exec = __importStar(__webpack_require__(986)); const fs = __importStar(__webpack_require__(747)); const github = __importStar(__webpack_require__(469)); +const https = __importStar(__webpack_require__(211)); const io = __importStar(__webpack_require__(1)); const path = __importStar(__webpack_require__(622)); const refHelper = __importStar(__webpack_require__(227)); @@ -8370,49 +8371,63 @@ function downloadRepository(accessToken, owner, repo, ref, commit, repositoryPat const runnerTemp = process.env['RUNNER_TEMP']; assert.ok(runnerTemp, 'RUNNER_TEMP not defined'); const archivePath = path.join(runnerTemp, 'checkout.tar.gz'); - // Ensure file does not exist - core.debug(`Ensuring archive file does not exist: ${archivePath}`); - yield io.rmRF(archivePath); - // Download the archive - let archiveData = yield retryHelper.execute(() => __awaiter(this, void 0, void 0, function* () { - core.info('Downloading the archive using the REST API'); - return yield downloadArchive(accessToken, owner, repo, ref, commit); + // await fs.promises.writeFile(archivePath, raw) + // Get the archive URL using the REST API + yield retryHelper.execute(() => __awaiter(this, void 0, void 0, function* () { + // Prepare the archive stream + core.debug(`Preparing the archive stream: ${archivePath}`); + yield io.rmRF(archivePath); + const fileStream = fs.createWriteStream(archivePath); + const fileStreamClosed = getFileClosedPromise(fileStream); + try { + // Get the archive URL using the GitHub REST API + core.info('Getting archive URL from GitHub REST API'); + const octokit = new github.GitHub(accessToken); + const params = { + method: 'HEAD', + archive_format: IS_WINDOWS ? 'zipball' : 'tarball', + owner: owner, + repo: repo, + ref: refHelper.getDownloadRef(ref, commit) + }; + const response = yield octokit.repos.getArchiveLink(params); + console.log('GOT THE RESPONSE'); + if (response.status != 302) { + throw new Error(`Unexpected response from GitHub API. Status: '${response.status}'`); + } + console.log('GETTING THE LOCATION'); + const archiveUrl = response.headers['Location']; // Do not print the archive URL because it has an embedded token + assert.ok(archiveUrl, `Expected GitHub API response to contain 'Location' header`); + // Download the archive + core.info('Downloading the archive'); // Do not print the archive URL because it has an embedded token + yield downloadFile(archiveUrl, fileStream); + } + finally { + yield fileStreamClosed; + } + // return Buffer.from(response.data) // response.data is ArrayBuffer })); - // Write archive to disk - core.info('Writing archive to disk'); - yield fs.promises.writeFile(archivePath, archiveData); - archiveData = Buffer.from(''); // Free memory - // // Get the archive URL using the REST API - // await retryHelper.execute(async () => { - // // Prepare the archive stream - // core.debug(`Preparing the archive stream: ${archivePath}`) - // await io.rmRF(archivePath) - // const fileStream = fs.createWriteStream(archivePath) - // const fileStreamClosed = getFileClosedPromise(fileStream) - // try { - // // Get the archive URL - // core.info('Getting archive URL') - // const archiveUrl = await getArchiveUrl( - // accessToken, - // owner, - // repo, - // ref, - // commit - // ) - // // Download the archive - // core.info('Downloading the archive') // Do not print the archive URL because it has an embedded token - // await downloadFile(archiveUrl, fileStream) - // } finally { - // fileStream.end() - // await fileStreamClosed - // } - // }) + // // Download the archive + // core.info('Downloading the archive') // Do not print the URL since it contains a token to download the archive + // await downloadFile(archiveUrl, archivePath) + // // console.log(`status=${response.status}`) + // // console.log(`headers=${JSON.stringify(response.headers)}`) + // // console.log(`data=${response.data}`) + // // console.log(`data=${JSON.stringify(response.data)}`) + // // for (const key of Object.keys(response.data)) { + // // console.log(`data['${key}']=${response.data[key]}`) + // // } + // // Write archive to file + // const runnerTemp = process.env['RUNNER_TEMP'] as string + // assert.ok(runnerTemp, 'RUNNER_TEMP not defined') + // const archivePath = path.join(runnerTemp, 'checkout.tar.gz') + // await io.rmRF(archivePath) // await fs.promises.writeFile(archivePath, raw) // // await exec.exec(`ls -la "${archiveFile}"`, [], { // // cwd: repositoryPath // // } as ExecOptions) // Extract archive - const extractPath = path.join(runnerTemp, `checkout`); + const extractPath = path.join(runnerTemp, `checkout-archive${IS_WINDOWS ? '.zip' : '.tar.gz'}`); yield io.rmRF(extractPath); yield io.mkdirP(extractPath); if (IS_WINDOWS) { @@ -8442,93 +8457,42 @@ function downloadRepository(accessToken, owner, repo, ref, commit, repositoryPat }); } exports.downloadRepository = downloadRepository; -function downloadArchive(accessToken, owner, repo, ref, commit) { - return __awaiter(this, void 0, void 0, function* () { - const octokit = new github.GitHub(accessToken); - const params = { - owner: owner, - repo: repo, - archive_format: IS_WINDOWS ? 'zipball' : 'tarball', - ref: refHelper.getDownloadRef(ref, commit) - }; - const response = yield octokit.repos.getArchiveLink(params); - console.log('GOT THE RESPONSE'); - console.log(`status=${response.status}`); - console.log(`headers=${JSON.stringify(response.headers)}`); - console.log(`data=${JSON.stringify(response.data)}`); - if (response.status != 200) { - throw new Error(`Unexpected response from GitHub API. Status: '${response.status}'`); +function downloadFile(url, fileStream) { + return new Promise((resolve, reject) => { + try { + https.get(url, (response) => { + if (response.statusCode != 200) { + reject(`Request failed with status '${response.statusCode}'`); + response.resume(); // Consume response data to free up memory + return; + } + response.on('data', chunk => { + fileStream.write(chunk); + }); + response.on('end', () => { + resolve(); + }); + response.on('error', err => { + reject(err); + }); + // response.pipe(fileStream) + }); + } + catch (err) { + reject(err); } - return Buffer.from(response.data); // response.data is ArrayBuffer }); } -// async function getArchiveUrl( -// accessToken: string, -// owner: string, -// repo: string, -// ref: string, -// commit: string -// ): Promise { -// const octokit = new github.GitHub(accessToken) -// const params: RequestOptions & ReposGetArchiveLinkParams = { -// method: 'HEAD', -// owner: owner, -// repo: repo, -// archive_format: IS_WINDOWS ? 'zipball' : 'tarball', -// ref: refHelper.getDownloadRef(ref, commit) -// } -// const response = await octokit.repos.getArchiveLink(params) -// console.log('GOT THE RESPONSE') -// console.log(`status=${response.status}`) -// console.log(`headers=${JSON.stringify(response.headers)}`) -// console.log(`data=${JSON.stringify(response.data)}`) -// if (response.status != 200) { -// throw new Error( -// `Unexpected response from GitHub API. Status: '${response.status}'` -// ) -// } -// console.log('GETTING THE LOCATION') -// const archiveUrl = response.headers['Location'] // Do not print the archive URL because it has an embedded token -// assert.ok( -// archiveUrl, -// `Expected GitHub API response to contain 'Location' header` -// ) -// return archiveUrl -// } -// function downloadFile(url: string, fileStream: WriteStream): Promise { -// return new Promise((resolve, reject) => { -// try { -// https.get(url, (response: IncomingMessage) => { -// if (response.statusCode != 200) { -// reject(`Request failed with status '${response.statusCode}'`) -// response.resume() // Consume response data to free up memory -// return -// } -// response.on('data', chunk => { -// fileStream.write(chunk) -// }) -// response.on('end', () => { -// resolve() -// }) -// response.on('error', err => { -// reject(err) -// }) -// }) -// } catch (err) { -// reject(err) -// } -// }) -// } -// function getFileClosedPromise(stream: WriteStream): Promise { -// return new Promise((resolve, reject) => { -// stream.on('error', err => { -// reject(err) -// }) -// stream.on('finish', () => { -// resolve() -// }) -// }) -// } +function getFileClosedPromise(stream) { + return new Promise((resolve, reject) => { + stream.on('error', err => { + reject(err); + }); + stream.on('finish', () => { + resolve(); + }); + }); +} /***/ }), diff --git a/src/github-api-helper.ts b/src/github-api-helper.ts index dc30870..f4aa8a8 100644 --- a/src/github-api-helper.ts +++ b/src/github-api-helper.ts @@ -11,7 +11,8 @@ import * as retryHelper from './retry-helper' import * as toolCache from '@actions/tool-cache' import {ExecOptions} from '@actions/exec/lib/interfaces' import {IncomingMessage} from 'http' -import {RequestOptions, ReposGetArchiveLinkParams} from '@octokit/rest' +import {ReposGetArchiveLinkParams} from '@octokit/rest' +import {RequestOptions} from 'https' import {WriteStream} from 'fs' const IS_WINDOWS = process.platform === 'win32' @@ -28,52 +29,78 @@ export async function downloadRepository( const runnerTemp = process.env['RUNNER_TEMP'] as string assert.ok(runnerTemp, 'RUNNER_TEMP not defined') const archivePath = path.join(runnerTemp, 'checkout.tar.gz') + // await fs.promises.writeFile(archivePath, raw) - // Ensure file does not exist - core.debug(`Ensuring archive file does not exist: ${archivePath}`) - await io.rmRF(archivePath) + // Get the archive URL using the REST API + await retryHelper.execute(async () => { + // Prepare the archive stream + core.debug(`Preparing the archive stream: ${archivePath}`) + await io.rmRF(archivePath) + const fileStream = fs.createWriteStream(archivePath) + const fileStreamClosed = getFileClosedPromise(fileStream) - // Download the archive - let archiveData = await retryHelper.execute(async () => { - core.info('Downloading the archive using the REST API') - return await downloadArchive(accessToken, owner, repo, ref, commit) + try { + // Get the archive URL using the GitHub REST API + core.info('Getting archive URL from GitHub REST API') + const octokit = new github.GitHub(accessToken) + const params: RequestOptions & ReposGetArchiveLinkParams = { + method: 'HEAD', + archive_format: IS_WINDOWS ? 'zipball' : 'tarball', + owner: owner, + repo: repo, + ref: refHelper.getDownloadRef(ref, commit) + } + const response = await octokit.repos.getArchiveLink(params) + console.log('GOT THE RESPONSE') + if (response.status != 302) { + throw new Error( + `Unexpected response from GitHub API. Status: '${response.status}'` + ) + } + console.log('GETTING THE LOCATION') + const archiveUrl = response.headers['Location'] // Do not print the archive URL because it has an embedded token + assert.ok( + archiveUrl, + `Expected GitHub API response to contain 'Location' header` + ) + + // Download the archive + core.info('Downloading the archive') // Do not print the archive URL because it has an embedded token + await downloadFile(archiveUrl, fileStream) + } finally { + await fileStreamClosed + } + + // return Buffer.from(response.data) // response.data is ArrayBuffer }) - // Write archive to disk - core.info('Writing archive to disk') - await fs.promises.writeFile(archivePath, archiveData) - archiveData = Buffer.from('') // Free memory + // // Download the archive + // core.info('Downloading the archive') // Do not print the URL since it contains a token to download the archive + // await downloadFile(archiveUrl, archivePath) - // // Get the archive URL using the REST API - // await retryHelper.execute(async () => { - // // Prepare the archive stream - // core.debug(`Preparing the archive stream: ${archivePath}`) - // await io.rmRF(archivePath) - // const fileStream = fs.createWriteStream(archivePath) - // const fileStreamClosed = getFileClosedPromise(fileStream) + // // console.log(`status=${response.status}`) + // // console.log(`headers=${JSON.stringify(response.headers)}`) + // // console.log(`data=${response.data}`) + // // console.log(`data=${JSON.stringify(response.data)}`) + // // for (const key of Object.keys(response.data)) { + // // console.log(`data['${key}']=${response.data[key]}`) + // // } - // try { - // // Get the archive URL - // core.info('Getting archive URL') - // const archiveUrl = await getArchiveUrl( - // accessToken, - // owner, - // repo, - // ref, - // commit - // ) - - // // Download the archive - // core.info('Downloading the archive') // Do not print the archive URL because it has an embedded token - // await downloadFile(archiveUrl, fileStream) - // } finally { - // fileStream.end() - // await fileStreamClosed - // } - // }) + // // Write archive to file + // const runnerTemp = process.env['RUNNER_TEMP'] as string + // assert.ok(runnerTemp, 'RUNNER_TEMP not defined') + // const archivePath = path.join(runnerTemp, 'checkout.tar.gz') + // await io.rmRF(archivePath) + // await fs.promises.writeFile(archivePath, raw) + // // await exec.exec(`ls -la "${archiveFile}"`, [], { + // // cwd: repositoryPath + // // } as ExecOptions) // Extract archive - const extractPath = path.join(runnerTemp, `checkout`) + const extractPath = path.join( + runnerTemp, + `checkout-archive${IS_WINDOWS ? '.zip' : '.tar.gz'}` + ) await io.rmRF(extractPath) await io.mkdirP(extractPath) if (IS_WINDOWS) { @@ -81,6 +108,9 @@ export async function downloadRepository( } else { await toolCache.extractTar(archivePath, extractPath) } + // await exec.exec(`tar -xzf "${archiveFile}"`, [], { + // cwd: extractPath + // } as ExecOptions) // Determine the real directory to copy (ignore extra dir at root of the archive) const archiveFileNames = await fs.promises.readdir(extractPath) @@ -104,101 +134,40 @@ export async function downloadRepository( } as ExecOptions) } -async function downloadArchive( - accessToken: string, - owner: string, - repo: string, - ref: string, - commit: string -): Promise { - const octokit = new github.GitHub(accessToken) - const params: ReposGetArchiveLinkParams = { - owner: owner, - repo: repo, - archive_format: IS_WINDOWS ? 'zipball' : 'tarball', - ref: refHelper.getDownloadRef(ref, commit) - } - const response = await octokit.repos.getArchiveLink(params) - console.log('GOT THE RESPONSE') - console.log(`status=${response.status}`) - console.log(`headers=${JSON.stringify(response.headers)}`) - console.log(`data=${JSON.stringify(response.data)}`) - if (response.status != 200) { - throw new Error( - `Unexpected response from GitHub API. Status: '${response.status}'` - ) - } +function downloadFile(url: string, fileStream: WriteStream): Promise { + return new Promise((resolve, reject) => { + try { + https.get(url, (response: IncomingMessage) => { + if (response.statusCode != 200) { + reject(`Request failed with status '${response.statusCode}'`) + response.resume() // Consume response data to free up memory + return + } - return Buffer.from(response.data) // response.data is ArrayBuffer + response.on('data', chunk => { + fileStream.write(chunk) + }) + response.on('end', () => { + resolve() + }) + response.on('error', err => { + reject(err) + }) + // response.pipe(fileStream) + }) + } catch (err) { + reject(err) + } + }) } -// async function getArchiveUrl( -// accessToken: string, -// owner: string, -// repo: string, -// ref: string, -// commit: string -// ): Promise { -// const octokit = new github.GitHub(accessToken) -// const params: RequestOptions & ReposGetArchiveLinkParams = { -// method: 'HEAD', -// owner: owner, -// repo: repo, -// archive_format: IS_WINDOWS ? 'zipball' : 'tarball', -// ref: refHelper.getDownloadRef(ref, commit) -// } -// const response = await octokit.repos.getArchiveLink(params) -// console.log('GOT THE RESPONSE') -// console.log(`status=${response.status}`) -// console.log(`headers=${JSON.stringify(response.headers)}`) -// console.log(`data=${JSON.stringify(response.data)}`) -// if (response.status != 200) { -// throw new Error( -// `Unexpected response from GitHub API. Status: '${response.status}'` -// ) -// } -// console.log('GETTING THE LOCATION') -// const archiveUrl = response.headers['Location'] // Do not print the archive URL because it has an embedded token -// assert.ok( -// archiveUrl, -// `Expected GitHub API response to contain 'Location' header` -// ) -// return archiveUrl -// } - -// function downloadFile(url: string, fileStream: WriteStream): Promise { -// return new Promise((resolve, reject) => { -// try { -// https.get(url, (response: IncomingMessage) => { -// if (response.statusCode != 200) { -// reject(`Request failed with status '${response.statusCode}'`) -// response.resume() // Consume response data to free up memory -// return -// } - -// response.on('data', chunk => { -// fileStream.write(chunk) -// }) -// response.on('end', () => { -// resolve() -// }) -// response.on('error', err => { -// reject(err) -// }) -// }) -// } catch (err) { -// reject(err) -// } -// }) -// } - -// function getFileClosedPromise(stream: WriteStream): Promise { -// return new Promise((resolve, reject) => { -// stream.on('error', err => { -// reject(err) -// }) -// stream.on('finish', () => { -// resolve() -// }) -// }) -// } +function getFileClosedPromise(stream: WriteStream): Promise { + return new Promise((resolve, reject) => { + stream.on('error', err => { + reject(err) + }) + stream.on('finish', () => { + resolve() + }) + }) +}