mirror of
				https://hub.gitmirror.com/https://github.com/actions/checkout.git
				synced 2025-10-31 18:10:02 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			93 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			93 lines
		
	
	
		
			2.9 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 {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)
 | |
|   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
 | |
| }
 | 
