mirror of
				https://github.com/actions/checkout.git
				synced 2025-11-04 04:44:21 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			94 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			94 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
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 * as urlHelper from './url-helper'
 | 
						|
import {default as uuid} from 'uuid/v4'
 | 
						|
import {ReposGetArchiveLinkParams} from '@octokit/rest'
 | 
						|
 | 
						|
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 = new github.GitHub(authToken, {baseUrl: urlHelper.getApiUrl()})
 | 
						|
  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
 | 
						|
}
 |