123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- import * as assert from 'assert'
- import * as core from '@actions/core'
- import * as fs from 'fs'
- import * as github from '@actions/github'
- import * as io from '@actions/io'
- import * as path from 'path'
- import * as retryHelper from './retry-helper'
- import * as toolCache from '@actions/tool-cache'
- import {default as uuid} from 'uuid/v4'
- import {ReposGetArchiveLinkParams} from '@octokit/rest'
- import HttpsProxyAgent from 'https-proxy-agent'
- const IS_WINDOWS = process.platform === 'win32'
- export async function downloadRepository(
- authToken: string,
- owner: string,
- repo: string,
- ref: string,
- commit: string,
- repositoryPath: string
- ): Promise<void> {
- // Download the archive
- let archiveData = await retryHelper.execute(async () => {
- core.info('Downloading the archive')
- return await downloadArchive(authToken, owner, repo, ref, commit)
- })
- // Write archive to disk
- core.info('Writing archive to disk')
- const uniqueId = uuid()
- const archivePath = path.join(repositoryPath, `${uniqueId}.tar.gz`)
- await fs.promises.writeFile(archivePath, archiveData)
- archiveData = Buffer.from('') // Free memory
- // Extract archive
- core.info('Extracting the archive')
- const extractPath = path.join(repositoryPath, uniqueId)
- await io.mkdirP(extractPath)
- if (IS_WINDOWS) {
- await toolCache.extractZip(archivePath, extractPath)
- } else {
- await toolCache.extractTar(archivePath, extractPath)
- }
- io.rmRF(archivePath)
- // Determine the path of the repository content. The archive contains
- // a top-level folder and the repository content is inside.
- const archiveFileNames = await fs.promises.readdir(extractPath)
- assert.ok(
- archiveFileNames.length == 1,
- 'Expected exactly one directory inside archive'
- )
- const archiveVersion = archiveFileNames[0] // The top-level folder name includes the short SHA
- core.info(`Resolved version ${archiveVersion}`)
- const tempRepositoryPath = path.join(extractPath, archiveVersion)
- // Move the files
- for (const fileName of await fs.promises.readdir(tempRepositoryPath)) {
- const sourcePath = path.join(tempRepositoryPath, fileName)
- const targetPath = path.join(repositoryPath, fileName)
- if (IS_WINDOWS) {
- await io.cp(sourcePath, targetPath, {recursive: true}) // Copy on Windows (Windows Defender may have a lock)
- } else {
- await io.mv(sourcePath, targetPath)
- }
- }
- io.rmRF(extractPath)
- }
- async function downloadArchive(
- authToken: string,
- owner: string,
- repo: string,
- ref: string,
- commit: string
- ): Promise<Buffer> {
- const octokit = createOctokit(authToken)
- const params: ReposGetArchiveLinkParams = {
- owner: owner,
- repo: repo,
- archive_format: IS_WINDOWS ? 'zipball' : 'tarball',
- ref: commit || ref
- }
- const response = await octokit.repos.getArchiveLink(params)
- if (response.status != 200) {
- throw new Error(
- `Unexpected response from GitHub API. Status: ${response.status}, Data: ${response.data}`
- )
- }
- return Buffer.from(response.data) // response.data is ArrayBuffer
- }
- function createOctokit(authToken: string): github.GitHub {
- let proxyVar: string =
- process.env['https_proxy'] || process.env['HTTPS_PROXY'] || ''
- if (!proxyVar) {
- return new github.GitHub(authToken)
- }
- let noProxy: string = process.env['no_proxy'] || process.env['NO_PROXY'] || ''
- let bypass: boolean = false
- if (noProxy) {
- let bypassList = noProxy.split(',')
- for (let i = 0; i < bypassList.length; i++) {
- let item = bypassList[i]
- if (
- item &&
- typeof item === 'string' &&
- item.trim().toLocaleLowerCase() === 'github.com'
- ) {
- bypass = true
- break
- }
- }
- }
- if (bypass) {
- return new github.GitHub(authToken)
- } else {
- return new github.GitHub(authToken, {
- request: {agent: new HttpsProxyAgent(proxyVar)}
- })
- }
- }
|