2023-05-25 12:22:24 -06:00
import * as core from '@actions/core'
2023-07-18 03:44:59 -06:00
import * as github from '@actions/github'
2023-05-25 12:22:24 -06:00
import path from 'path'
2023-06-23 11:20:13 -06:00
import {
2023-09-16 05:44:37 -06:00
processChangedFiles ,
2023-07-19 01:50:59 -06:00
ChangeTypeEnum ,
2023-06-23 11:20:13 -06:00
getAllDiffFiles ,
getChangedFilesFromGithubAPI ,
getRenamedFiles
} from './changedFiles'
2023-06-14 12:45:32 -06:00
import {
DiffResult ,
2023-08-21 21:11:59 -06:00
getSHAForNonPullRequestEvent ,
getSHAForPullRequestEvent
2023-05-25 12:22:24 -06:00
} from './commitSha'
2023-06-23 11:20:13 -06:00
import { Env , getEnv } from './env'
import { getInputs , Inputs } from './inputs'
2023-05-25 12:22:24 -06:00
import {
getFilePatterns ,
2023-07-19 01:50:59 -06:00
getRecoverFilePatterns ,
2023-05-25 12:22:24 -06:00
getSubmodulePath ,
2023-06-16 00:17:13 -06:00
getYamlFilePatterns ,
2023-06-23 11:20:13 -06:00
hasLocalGitDirectory ,
2023-05-25 12:22:24 -06:00
isRepoShallow ,
2023-07-19 01:50:59 -06:00
recoverDeletedFiles ,
2023-05-25 12:22:24 -06:00
setOutput ,
submoduleExists ,
updateGitGlobalConfig ,
2024-01-13 14:53:17 -07:00
verifyMinimumGitVersion ,
warnUnsupportedRESTAPIInputs
2023-05-25 12:22:24 -06:00
} from './utils'
2023-09-16 05:44:37 -06:00
const getChangedFilesFromLocalGitHistory = async ( {
2023-06-23 11:20:13 -06:00
inputs ,
env ,
2023-07-09 03:19:14 -06:00
workingDirectory ,
filePatterns ,
yamlFilePatterns
2023-06-23 11:20:13 -06:00
} : {
inputs : Inputs
env : Env
workingDirectory : string
2023-07-09 03:19:14 -06:00
filePatterns : string [ ]
yamlFilePatterns : Record < string , string [ ] >
2023-06-23 11:20:13 -06:00
} ) : Promise < void > = > {
2023-05-25 12:22:24 -06:00
await verifyMinimumGitVersion ( )
2024-01-13 14:53:17 -07:00
let quotepathValue = 'on'
2023-05-25 12:22:24 -06:00
2024-01-13 14:53:17 -07:00
if ( ! inputs . quotepath ) {
quotepathValue = 'off'
2023-05-25 12:22:24 -06:00
}
await updateGitGlobalConfig ( {
name : 'core.quotepath' ,
2024-01-13 14:53:17 -07:00
value : quotepathValue
2023-05-25 12:22:24 -06:00
} )
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 13:22:47 -06:00
let gitFetchExtraArgs = [ '--no-tags' , '--prune' , '--recurse-submodules' ]
2023-05-25 12:22:24 -06:00
const isTag = env . GITHUB_REF ? . startsWith ( 'refs/tags/' )
2023-06-14 13:59:31 -06:00
const outputRenamedFilesAsDeletedAndAdded =
inputs . outputRenamedFilesAsDeletedAndAdded
2023-05-25 15:53:58 -06:00
let submodulePaths : string [ ] = [ ]
2023-05-25 15:43:31 -06:00
if ( hasSubmodule ) {
2023-05-25 15:53:58 -06:00
submodulePaths = await getSubmodulePath ( { cwd : workingDirectory } )
2023-05-25 15:43:31 -06:00
}
2023-05-25 12:22:24 -06:00
if ( isTag ) {
2023-06-14 13:22:47 -06:00
gitFetchExtraArgs = [ '--prune' , '--no-recurse-submodules' ]
2023-05-25 12:22:24 -06:00
}
let diffResult : DiffResult
2023-07-18 03:44:59 -06:00
if ( ! github . context . payload . pull_request ? . base ? . ref ) {
core . info ( ` Running on a ${ github . context . eventName || 'push' } event... ` )
2023-07-24 15:40:48 -06:00
diffResult = await getSHAForNonPullRequestEvent (
2023-05-25 12:22:24 -06:00
inputs ,
env ,
workingDirectory ,
isShallow ,
hasSubmodule ,
2023-06-14 13:22:47 -06:00
gitFetchExtraArgs ,
2023-05-25 12:22:24 -06:00
isTag
)
} else {
2023-06-08 06:12:03 -06:00
core . info (
2023-07-18 03:44:59 -06:00
` Running on a ${ github . context . eventName || 'pull_request' } ( ${
github . context . payload . action
2023-06-16 00:17:13 -06:00
} ) event . . . `
2023-06-08 06:12:03 -06:00
)
2023-05-25 12:22:24 -06:00
diffResult = await getSHAForPullRequestEvent (
inputs ,
env ,
workingDirectory ,
isShallow ,
hasSubmodule ,
2023-06-14 13:22:47 -06:00
gitFetchExtraArgs
2023-05-25 12:22:24 -06:00
)
}
2023-05-26 10:48:32 -06:00
if ( diffResult . initialCommit ) {
core . info ( 'This is the first commit for this repository; exiting...' )
core . endGroup ( )
return
}
2023-05-25 12:22:24 -06:00
core . info (
` Retrieving changes between ${ diffResult . previousSha } ( ${ diffResult . targetBranch } ) → ${ diffResult . currentSha } ( ${ diffResult . currentBranch } ) `
)
2023-06-14 12:45:32 -06:00
const allDiffFiles = await getAllDiffFiles ( {
2023-05-25 12:22:24 -06:00
workingDirectory ,
hasSubmodule ,
diffResult ,
2023-06-14 13:59:31 -06:00
submodulePaths ,
2023-08-25 21:00:53 -06:00
outputRenamedFilesAsDeletedAndAdded ,
2024-01-13 14:53:17 -07:00
fetchAdditionalSubmoduleHistory : inputs.fetchAdditionalSubmoduleHistory ,
2023-08-30 14:51:36 -06:00
failOnInitialDiffError : inputs.failOnInitialDiffError ,
failOnSubmoduleDiffError : inputs.failOnSubmoduleDiffError
2023-05-25 12:22:24 -06:00
} )
2023-06-14 12:45:32 -06:00
core . debug ( ` All diff files: ${ JSON . stringify ( allDiffFiles ) } ` )
2023-06-16 00:17:13 -06:00
core . info ( 'All Done!' )
core . endGroup ( )
2023-06-14 12:45:32 -06:00
2023-07-19 01:50:59 -06:00
if ( inputs . recoverDeletedFiles ) {
let recoverPatterns = getRecoverFilePatterns ( { inputs } )
2023-05-25 12:22:24 -06:00
2023-07-19 01:50:59 -06:00
if ( recoverPatterns . length > 0 && filePatterns . length > 0 ) {
core . info ( 'No recover patterns found; defaulting to file patterns' )
recoverPatterns = filePatterns
2023-06-16 00:17:13 -06:00
}
2023-05-25 12:22:24 -06:00
2023-07-19 01:50:59 -06:00
await recoverDeletedFiles ( {
2023-06-16 20:33:42 -06:00
inputs ,
workingDirectory ,
2023-07-19 01:50:59 -06:00
deletedFiles : allDiffFiles [ ChangeTypeEnum . Deleted ] ,
recoverPatterns ,
2023-12-10 00:14:44 -07:00
diffResult ,
hasSubmodule ,
submodulePaths
2023-06-16 00:17:13 -06:00
} )
}
2023-05-25 12:22:24 -06:00
2023-09-16 05:44:37 -06:00
await processChangedFiles ( {
2023-07-19 01:50:59 -06:00
filePatterns ,
allDiffFiles ,
inputs ,
2023-09-21 20:47:12 -06:00
yamlFilePatterns ,
workingDirectory
2023-07-19 01:50:59 -06:00
} )
2023-05-25 12:22:24 -06:00
if ( inputs . includeAllOldNewRenamedFiles ) {
2023-06-16 00:17:13 -06:00
core . startGroup ( 'changed-files-all-old-new-renamed-files' )
2023-05-25 12:22:24 -06: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-16 21:13:40 -06:00
value : allOldNewRenamedFiles.paths ,
2023-09-04 14:03:32 -06:00
writeOutputFiles : inputs.writeOutputFiles ,
outputDir : inputs.outputDir ,
2023-12-22 22:07:32 +01:00
json : inputs.json ,
safeOutput : inputs.safeOutput
2023-06-16 21:13:40 -06:00
} )
await setOutput ( {
key : 'all_old_new_renamed_files_count' ,
value : allOldNewRenamedFiles.count ,
2023-09-04 14:03:32 -06:00
writeOutputFiles : inputs.writeOutputFiles ,
outputDir : inputs.outputDir ,
json : inputs.json
2023-05-25 12:22:24 -06:00
} )
2023-06-16 00:17:13 -06:00
core . info ( 'All Done!' )
core . endGroup ( )
2023-05-25 12:22:24 -06:00
}
}
2023-06-23 11:20:13 -06:00
const getChangedFilesFromRESTAPI = async ( {
inputs ,
2023-07-09 03:19:14 -06:00
filePatterns ,
yamlFilePatterns
2023-06-23 11:20:13 -06:00
} : {
inputs : Inputs
2023-07-09 03:19:14 -06:00
filePatterns : string [ ]
yamlFilePatterns : Record < string , string [ ] >
2023-06-23 11:20:13 -06:00
} ) : Promise < void > = > {
const allDiffFiles = await getChangedFilesFromGithubAPI ( {
2023-07-18 03:44:59 -06:00
inputs
2023-06-23 11:20:13 -06:00
} )
core . debug ( ` All diff files: ${ JSON . stringify ( allDiffFiles ) } ` )
core . info ( 'All Done!' )
2023-09-16 05:44:37 -06:00
await processChangedFiles ( {
2023-07-19 01:50:59 -06:00
filePatterns ,
allDiffFiles ,
inputs ,
yamlFilePatterns
} )
2023-06-23 11:20:13 -06: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 03:19:14 -06:00
2023-06-23 11:20:13 -06:00
const inputs = getInputs ( )
core . debug ( ` Inputs: ${ JSON . stringify ( inputs , null , 2 ) } ` )
2023-07-09 03:19:14 -06:00
2023-07-19 01:50:59 -06:00
core . debug ( ` Github Context: ${ JSON . stringify ( github . context , null , 2 ) } ` )
2023-07-18 03:44:59 -06:00
2023-06-23 11:20:13 -06:00
const workingDirectory = path . resolve (
env . GITHUB_WORKSPACE || process . cwd ( ) ,
2024-01-15 11:54:08 -07:00
inputs . useRestApi ? '.' : inputs . path
2023-06-23 11:20:13 -06:00
)
2023-07-09 03:19:14 -06:00
core . debug ( ` Working directory: ${ workingDirectory } ` )
2023-06-23 11:20:13 -06:00
const hasGitDirectory = await hasLocalGitDirectory ( { workingDirectory } )
2023-07-09 03:19:14 -06: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 11:20:13 -06:00
2024-01-13 01:48:42 -07: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 11:20:13 -06:00
if (
inputs . token &&
2023-07-18 03:44:59 -06:00
github . context . payload . pull_request ? . number &&
2024-01-13 01:48:42 -07:00
( ! hasGitDirectory || inputs . useRestApi )
2023-06-23 11:20:13 -06:00
) {
core . info ( "Using GitHub's REST API to get changed files" )
2024-01-13 14:53:17 -07:00
if ( process . env . GITHUB_ACTION_PATH ) {
await warnUnsupportedRESTAPIInputs ( {
2024-01-17 00:20:30 -07:00
actionPath : path.join ( process . env . GITHUB_ACTION_PATH , 'action.yml' ) ,
2024-01-13 14:53:17 -07:00
inputs
} )
2023-06-23 11:20:13 -06:00
}
2023-07-09 03:19:14 -06:00
await getChangedFilesFromRESTAPI ( {
inputs ,
filePatterns ,
yamlFilePatterns
} )
2023-06-23 11:20:13 -06:00
} else {
if ( ! hasGitDirectory ) {
2024-01-12 10:28:21 -07:00
core . info ( ` Running on a ${ github . context . eventName } event... ` )
2024-01-13 01:48:42 -07:00
throw new Error (
2024-01-15 11:54:08 -07:00
` Can't find local .git in ${ workingDirectory } directory. Please run actions/checkout before this action (Make sure 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 11:20:13 -06:00
)
}
core . info ( 'Using local .git directory' )
2023-09-16 05:44:37 -06:00
await getChangedFilesFromLocalGitHistory ( {
2023-07-09 03:19:14 -06:00
inputs ,
env ,
workingDirectory ,
filePatterns ,
yamlFilePatterns
} )
2023-06-23 11:20:13 -06:00
}
}
2023-05-25 12:22:24 -06: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 01:48:42 -07:00
process . exit ( 1 )
2023-05-25 12:22:24 -06:00
} )
}