2023-05-25 18:22:24 +00:00
import * as core from '@actions/core'
2023-07-18 09:44:59 +00:00
import * as github from '@actions/github'
2023-05-25 18:22:24 +00:00
import path from 'path'
2023-06-23 17:20:13 +00:00
import {
2023-09-16 11:44:37 +00:00
processChangedFiles ,
2023-07-19 07:50:59 +00:00
ChangeTypeEnum ,
2023-06-23 17:20:13 +00:00
getAllDiffFiles ,
getChangedFilesFromGithubAPI ,
getRenamedFiles
} from './changedFiles'
2023-06-14 18:45:32 +00:00
import {
DiffResult ,
2023-08-22 03:11:59 +00:00
getSHAForNonPullRequestEvent ,
getSHAForPullRequestEvent
2023-05-25 18:22:24 +00:00
} from './commitSha'
2023-06-23 17:20:13 +00:00
import { Env , getEnv } from './env'
import { getInputs , Inputs } from './inputs'
2023-05-25 18:22:24 +00:00
import {
getFilePatterns ,
2023-07-19 07:50:59 +00:00
getRecoverFilePatterns ,
2023-05-25 18:22:24 +00:00
getSubmodulePath ,
2023-06-16 06:17:13 +00:00
getYamlFilePatterns ,
2023-06-23 17:20:13 +00:00
hasLocalGitDirectory ,
2023-05-25 18:22:24 +00:00
isRepoShallow ,
2023-07-19 07:50:59 +00:00
recoverDeletedFiles ,
2023-05-25 18:22:24 +00:00
setOutput ,
submoduleExists ,
updateGitGlobalConfig ,
verifyMinimumGitVersion
} from './utils'
2023-09-16 11:44:37 +00:00
const getChangedFilesFromLocalGitHistory = async ( {
2023-06-23 17:20:13 +00:00
inputs ,
env ,
2023-07-09 09:19:14 +00:00
workingDirectory ,
filePatterns ,
yamlFilePatterns
2023-06-23 17:20:13 +00:00
} : {
inputs : Inputs
env : Env
workingDirectory : string
2023-07-09 09:19:14 +00:00
filePatterns : string [ ]
yamlFilePatterns : Record < string , string [ ] >
2023-06-23 17:20:13 +00:00
} ) : Promise < void > = > {
2023-05-25 18:22:24 +00:00
await verifyMinimumGitVersion ( )
let quotePathValue = 'on'
if ( ! inputs . quotePath ) {
quotePathValue = 'off'
}
await updateGitGlobalConfig ( {
name : 'core.quotepath' ,
value : quotePathValue
} )
if ( inputs . diffRelative ) {
await updateGitGlobalConfig ( {
name : 'diff.relative' ,
value : 'true'
} )
}
const isShallow = await isRepoShallow ( { cwd : workingDirectory } )
const hasSubmodule = await submoduleExists ( { cwd : workingDirectory } )
2023-06-14 19:22:47 +00:00
let gitFetchExtraArgs = [ '--no-tags' , '--prune' , '--recurse-submodules' ]
2023-05-25 18:22:24 +00:00
const isTag = env . GITHUB_REF ? . startsWith ( 'refs/tags/' )
2023-06-14 19:59:31 +00:00
const outputRenamedFilesAsDeletedAndAdded =
inputs . outputRenamedFilesAsDeletedAndAdded
2023-05-25 21:53:58 +00:00
let submodulePaths : string [ ] = [ ]
2023-05-25 21:43:31 +00:00
if ( hasSubmodule ) {
2023-05-25 21:53:58 +00:00
submodulePaths = await getSubmodulePath ( { cwd : workingDirectory } )
2023-05-25 21:43:31 +00:00
}
2023-05-25 18:22:24 +00:00
if ( isTag ) {
2023-06-14 19:22:47 +00:00
gitFetchExtraArgs = [ '--prune' , '--no-recurse-submodules' ]
2023-05-25 18:22:24 +00:00
}
let diffResult : DiffResult
2023-07-18 09:44:59 +00:00
if ( ! github . context . payload . pull_request ? . base ? . ref ) {
core . info ( ` Running on a ${ github . context . eventName || 'push' } event... ` )
2023-07-24 21:40:48 +00:00
diffResult = await getSHAForNonPullRequestEvent (
2023-05-25 18:22:24 +00:00
inputs ,
env ,
workingDirectory ,
isShallow ,
hasSubmodule ,
2023-06-14 19:22:47 +00:00
gitFetchExtraArgs ,
2023-05-25 18:22:24 +00:00
isTag
)
} else {
2023-06-08 12:12:03 +00:00
core . info (
2023-07-18 09:44:59 +00:00
` Running on a ${ github . context . eventName || 'pull_request' } ( ${
github . context . payload . action
2023-06-16 06:17:13 +00:00
} ) event . . . `
2023-06-08 12:12:03 +00:00
)
2023-05-25 18:22:24 +00:00
diffResult = await getSHAForPullRequestEvent (
inputs ,
env ,
workingDirectory ,
isShallow ,
hasSubmodule ,
2023-06-14 19:22:47 +00:00
gitFetchExtraArgs
2023-05-25 18:22:24 +00:00
)
}
2023-05-26 16:48:32 +00:00
if ( diffResult . initialCommit ) {
core . info ( 'This is the first commit for this repository; exiting...' )
core . endGroup ( )
return
}
2023-05-25 18:22:24 +00:00
core . info (
` Retrieving changes between ${ diffResult . previousSha } ( ${ diffResult . targetBranch } ) → ${ diffResult . currentSha } ( ${ diffResult . currentBranch } ) `
)
2023-06-14 18:45:32 +00:00
const allDiffFiles = await getAllDiffFiles ( {
2023-05-25 18:22:24 +00:00
workingDirectory ,
hasSubmodule ,
diffResult ,
2023-06-14 19:59:31 +00:00
submodulePaths ,
2023-08-26 03:00:53 +00:00
outputRenamedFilesAsDeletedAndAdded ,
2023-08-30 20:51:36 +00:00
fetchSubmoduleHistory : inputs.fetchSubmoduleHistory ,
failOnInitialDiffError : inputs.failOnInitialDiffError ,
failOnSubmoduleDiffError : inputs.failOnSubmoduleDiffError
2023-05-25 18:22:24 +00:00
} )
2023-06-14 18:45:32 +00:00
core . debug ( ` All diff files: ${ JSON . stringify ( allDiffFiles ) } ` )
2023-06-16 06:17:13 +00:00
core . info ( 'All Done!' )
core . endGroup ( )
2023-06-14 18:45:32 +00:00
2023-07-19 07:50:59 +00:00
if ( inputs . recoverDeletedFiles ) {
let recoverPatterns = getRecoverFilePatterns ( { inputs } )
2023-05-25 18:22:24 +00:00
2023-07-19 07:50:59 +00:00
if ( recoverPatterns . length > 0 && filePatterns . length > 0 ) {
core . info ( 'No recover patterns found; defaulting to file patterns' )
recoverPatterns = filePatterns
2023-06-16 06:17:13 +00:00
}
2023-05-25 18:22:24 +00:00
2023-07-19 07:50:59 +00:00
await recoverDeletedFiles ( {
2023-06-17 02:33:42 +00:00
inputs ,
workingDirectory ,
2023-07-19 07:50:59 +00:00
deletedFiles : allDiffFiles [ ChangeTypeEnum . Deleted ] ,
recoverPatterns ,
2023-12-10 07:14:44 +00:00
diffResult ,
hasSubmodule ,
submodulePaths
2023-06-16 06:17:13 +00:00
} )
}
2023-05-25 18:22:24 +00:00
2023-09-16 11:44:37 +00:00
await processChangedFiles ( {
2023-07-19 07:50:59 +00:00
filePatterns ,
allDiffFiles ,
inputs ,
2023-09-22 02:47:12 +00:00
yamlFilePatterns ,
workingDirectory
2023-07-19 07:50:59 +00:00
} )
2023-05-25 18:22:24 +00:00
if ( inputs . includeAllOldNewRenamedFiles ) {
2023-06-16 06:17:13 +00:00
core . startGroup ( 'changed-files-all-old-new-renamed-files' )
2023-05-25 18:22:24 +00:00
const allOldNewRenamedFiles = await getRenamedFiles ( {
inputs ,
workingDirectory ,
hasSubmodule ,
diffResult ,
submodulePaths
} )
core . debug ( ` All old new renamed files: ${ allOldNewRenamedFiles } ` )
await setOutput ( {
key : 'all_old_new_renamed_files' ,
2023-06-17 03:13:40 +00:00
value : allOldNewRenamedFiles.paths ,
2023-09-04 20:03:32 +00:00
writeOutputFiles : inputs.writeOutputFiles ,
outputDir : inputs.outputDir ,
2023-12-22 21:07:32 +00:00
json : inputs.json ,
safeOutput : inputs.safeOutput
2023-06-17 03:13:40 +00:00
} )
await setOutput ( {
key : 'all_old_new_renamed_files_count' ,
value : allOldNewRenamedFiles.count ,
2023-09-04 20:03:32 +00:00
writeOutputFiles : inputs.writeOutputFiles ,
outputDir : inputs.outputDir ,
json : inputs.json
2023-05-25 18:22:24 +00:00
} )
2023-06-16 06:17:13 +00:00
core . info ( 'All Done!' )
core . endGroup ( )
2023-05-25 18:22:24 +00:00
}
}
2023-06-23 17:20:13 +00:00
const getChangedFilesFromRESTAPI = async ( {
inputs ,
2023-07-09 09:19:14 +00:00
filePatterns ,
yamlFilePatterns
2023-06-23 17:20:13 +00:00
} : {
inputs : Inputs
2023-07-09 09:19:14 +00:00
filePatterns : string [ ]
yamlFilePatterns : Record < string , string [ ] >
2023-06-23 17:20:13 +00:00
} ) : Promise < void > = > {
const allDiffFiles = await getChangedFilesFromGithubAPI ( {
2023-07-18 09:44:59 +00:00
inputs
2023-06-23 17:20:13 +00:00
} )
core . debug ( ` All diff files: ${ JSON . stringify ( allDiffFiles ) } ` )
core . info ( 'All Done!' )
2023-09-16 11:44:37 +00:00
await processChangedFiles ( {
2023-07-19 07:50:59 +00:00
filePatterns ,
allDiffFiles ,
inputs ,
yamlFilePatterns
} )
2023-06-23 17:20:13 +00:00
}
export async function run ( ) : Promise < void > {
core . startGroup ( 'changed-files' )
const env = await getEnv ( )
core . debug ( ` Env: ${ JSON . stringify ( env , null , 2 ) } ` )
2023-07-09 09:19:14 +00:00
2023-06-23 17:20:13 +00:00
const inputs = getInputs ( )
core . debug ( ` Inputs: ${ JSON . stringify ( inputs , null , 2 ) } ` )
2023-07-09 09:19:14 +00:00
2023-07-19 07:50:59 +00:00
core . debug ( ` Github Context: ${ JSON . stringify ( github . context , null , 2 ) } ` )
2023-07-18 09:44:59 +00:00
2023-06-23 17:20:13 +00:00
const workingDirectory = path . resolve (
env . GITHUB_WORKSPACE || process . cwd ( ) ,
inputs . path
)
2023-07-09 09:19:14 +00:00
core . debug ( ` Working directory: ${ workingDirectory } ` )
2023-06-23 17:20:13 +00:00
const hasGitDirectory = await hasLocalGitDirectory ( { workingDirectory } )
2023-07-09 09:19:14 +00:00
core . debug ( ` Has git directory: ${ hasGitDirectory } ` )
const filePatterns = await getFilePatterns ( {
inputs ,
workingDirectory
} )
core . debug ( ` File patterns: ${ filePatterns } ` )
const yamlFilePatterns = await getYamlFilePatterns ( {
inputs ,
workingDirectory
} )
core . debug ( ` Yaml file patterns: ${ JSON . stringify ( yamlFilePatterns ) } ` )
2023-06-23 17:20:13 +00:00
2024-01-13 08:48:42 +00:00
if ( inputs . useRestApi && ! github . context . payload . pull_request ? . number ) {
throw new Error (
"Only pull_request* events are supported when using GitHub's REST API."
)
}
2023-06-23 17:20:13 +00:00
if (
inputs . token &&
2023-07-18 09:44:59 +00:00
github . context . payload . pull_request ? . number &&
2024-01-13 08:48:42 +00:00
( ! hasGitDirectory || inputs . useRestApi )
2023-06-23 17:20:13 +00:00
) {
core . info ( "Using GitHub's REST API to get changed files" )
const unsupportedInputs : ( keyof Inputs ) [ ] = [
'sha' ,
'baseSha' ,
'since' ,
'until' ,
2024-01-13 08:48:42 +00:00
'path' ,
'quotePath' ,
'diffRelative' ,
2023-06-23 17:20:13 +00:00
'sinceLastRemoteCommit' ,
'recoverDeletedFiles' ,
'recoverDeletedFilesToDestination' ,
2023-08-22 03:11:59 +00:00
'recoverFiles' ,
2024-01-13 08:48:42 +00:00
'recoverFilesSeparator' ,
2023-08-22 03:11:59 +00:00
'recoverFilesIgnore' ,
2024-01-13 08:48:42 +00:00
'recoverFilesIgnoreSeparator' ,
2023-08-22 03:11:59 +00:00
'includeAllOldNewRenamedFiles' ,
2024-01-13 08:48:42 +00:00
'oldNewSeparator' ,
'oldNewFilesSeparator' ,
2023-08-23 21:04:44 +00:00
'skipInitialFetch' ,
2023-09-25 00:10:27 +00:00
'fetchSubmoduleHistory' ,
'dirNamesDeletedFilesIncludeOnlyDeletedDirs'
2023-06-23 17:20:13 +00:00
]
for ( const input of unsupportedInputs ) {
if ( inputs [ input ] ) {
core . warning (
` Input " ${ input } " is not supported when using GitHub's REST API to get changed files `
)
}
}
2023-07-09 09:19:14 +00:00
await getChangedFilesFromRESTAPI ( {
inputs ,
filePatterns ,
yamlFilePatterns
} )
2023-06-23 17:20:13 +00:00
} else {
if ( ! hasGitDirectory ) {
2024-01-12 17:28:21 +00:00
core . info ( ` Running on a ${ github . context . eventName } event... ` )
2024-01-13 08:48:42 +00:00
throw new Error (
"Can't find local .git directory. Please run actions/checkout before this action (Make sure the path specified in the 'path' input is correct). If you intend to use Github's REST API note that only pull_request* events are supported."
2023-06-23 17:20:13 +00:00
)
}
core . info ( 'Using local .git directory' )
2023-09-16 11:44:37 +00:00
await getChangedFilesFromLocalGitHistory ( {
2023-07-09 09:19:14 +00:00
inputs ,
env ,
workingDirectory ,
filePatterns ,
yamlFilePatterns
} )
2023-06-23 17:20:13 +00:00
}
}
2023-05-25 18:22:24 +00:00
/* istanbul ignore if */
if ( ! process . env . TESTING ) {
// eslint-disable-next-line github/no-then
run ( ) . catch ( e = > {
core . setFailed ( e . message || e )
2024-01-13 08:48:42 +00:00
process . exit ( 1 )
2023-05-25 18:22:24 +00:00
} )
}