3
0
Fork 0
mirror of https://github.com/tj-actions/changed-files synced 2024-12-16 09:27:57 +00:00

feat: switch to use name status (#1230)

Co-authored-by: tj-actions[bot] <109116665+tj-actions-bot@users.noreply.github.com>
Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
Tonye Jack 2023-06-14 12:45:32 -06:00 committed by GitHub
parent 2d0b52f440
commit 174a2a6360
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 759 additions and 706 deletions

View file

@ -60,6 +60,8 @@
"@typescript-eslint/promise-function-async": "error",
"@typescript-eslint/require-array-sort-compare": "error",
"@typescript-eslint/restrict-plus-operands": "error",
"no-shadow": "off",
"@typescript-eslint/no-shadow": "error",
"semi": "off",
"filenames/match-regex": [
"error",

BIN
dist/index.js generated vendored

Binary file not shown.

BIN
dist/index.js.map generated vendored

Binary file not shown.

BIN
dist/licenses.txt generated vendored

Binary file not shown.

View file

@ -34,10 +34,12 @@
"dependencies": {
"@actions/core": "1.10.0",
"@actions/exec": "1.1.1",
"lodash": "^4.17.15",
"micromatch": "^4.0.5"
},
"devDependencies": {
"@types/jest": "29.5.2",
"@types/lodash": "^4.14.195",
"@types/micromatch": "^4.0.2",
"@types/node": "20.2.1",
"@types/uuid": "9.0.2",

View file

@ -4,11 +4,12 @@ import {DiffResult} from './commitSha'
import {Inputs} from './inputs'
import {
getDirnameMaxDepth,
gitDiff,
gitRenamedFiles,
gitSubmoduleDiffSHA,
jsonOutput
jsonOutput,
getAllChangedFiles
} from './utils'
import flatten from 'lodash/flatten'
export const getRenamedFiles = async ({
inputs,
@ -68,30 +69,37 @@ export const getRenamedFiles = async ({
return renamedFiles.join(inputs.oldNewFilesSeparator)
}
export const getDiffFiles = async ({
inputs,
export enum ChangeTypeEnum {
Added = 'A',
Copied = 'C',
Deleted = 'D',
Modified = 'M',
Renamed = 'R',
TypeChanged = 'T',
Unmerged = 'U',
Unknown = 'X'
}
export type ChangedFiles = {
[key in ChangeTypeEnum]: string[]
}
export const getAllDiffFiles = async ({
workingDirectory,
hasSubmodule,
diffResult,
diffFilter,
filePatterns = [],
submodulePaths
}: {
inputs: Inputs
workingDirectory: string
hasSubmodule: boolean
diffResult: DiffResult
diffFilter: string
filePatterns?: string[]
submodulePaths: string[]
}): Promise<string> => {
let files = await gitDiff({
}): Promise<ChangedFiles> => {
const files = await getAllChangedFiles({
cwd: workingDirectory,
sha1: diffResult.previousSha,
sha2: diffResult.currentSha,
diff: diffResult.diff,
diffFilter,
filePatterns
diff: diffResult.diff
})
if (hasSubmodule) {
@ -110,32 +118,107 @@ export const getDiffFiles = async ({
)
if (submoduleShaResult.currentSha && submoduleShaResult.previousSha) {
const submoduleFiles = await gitDiff({
const submoduleFiles = await getAllChangedFiles({
cwd: submoduleWorkingDirectory,
sha1: submoduleShaResult.previousSha,
sha2: submoduleShaResult.currentSha,
diff: diffResult.diff,
diffFilter,
isSubmodule: true,
filePatterns,
parentDir: submodulePath
})
files.push(...submoduleFiles)
for (const changeType of Object.keys(
submoduleFiles
) as ChangeTypeEnum[]) {
if (!files[changeType]) {
files[changeType] = []
}
files[changeType].push(...submoduleFiles[changeType])
}
}
}
}
if (inputs.dirNames) {
files = files.map(file =>
getDirnameMaxDepth({
pathStr: file,
dirNamesMaxDepth: inputs.dirNamesMaxDepth,
excludeCurrentDir:
inputs.dirNamesExcludeRoot || inputs.dirNamesExcludeCurrentDir
})
)
files = [...new Set(files)]
return files
}
function* getChangeTypeFilesGenerator({
inputs,
changedFiles,
changeTypes
}: {
inputs: Inputs
changedFiles: ChangedFiles
changeTypes: ChangeTypeEnum[]
}): Generator<string> {
for (const changeType of changeTypes) {
const files = changedFiles[changeType] || []
for (const file of files) {
if (inputs.dirNames) {
yield getDirnameMaxDepth({
pathStr: file,
dirNamesMaxDepth: inputs.dirNamesMaxDepth,
excludeCurrentDir:
inputs.dirNamesExcludeRoot || inputs.dirNamesExcludeCurrentDir
})
} else {
yield file
}
}
}
}
export const getChangeTypeFiles = async ({
inputs,
changedFiles,
changeTypes
}: {
inputs: Inputs
changedFiles: ChangedFiles
changeTypes: ChangeTypeEnum[]
}): Promise<string> => {
const files = [
...new Set(getChangeTypeFilesGenerator({inputs, changedFiles, changeTypes}))
]
if (inputs.json) {
return jsonOutput({value: files, shouldEscape: inputs.escapeJson})
}
return files.join(inputs.separator)
}
function* getAllChangeTypeFilesGenerator({
inputs,
changedFiles
}: {
inputs: Inputs
changedFiles: ChangedFiles
}): Generator<string> {
for (const file of flatten(Object.values(changedFiles))) {
if (inputs.dirNames) {
yield getDirnameMaxDepth({
pathStr: file,
dirNamesMaxDepth: inputs.dirNamesMaxDepth,
excludeCurrentDir:
inputs.dirNamesExcludeRoot || inputs.dirNamesExcludeCurrentDir
})
} else {
yield file
}
}
}
export const getAllChangeTypeFiles = async ({
inputs,
changedFiles
}: {
inputs: Inputs
changedFiles: ChangedFiles
}): Promise<string> => {
const files = [
...new Set(getAllChangeTypeFilesGenerator({inputs, changedFiles}))
]
if (inputs.json) {
return jsonOutput({value: files, shouldEscape: inputs.escapeJson})

View file

@ -370,11 +370,22 @@ export const getSHAForPullRequestEvent = async (
if (!previousSha) {
if (inputs.sinceLastRemoteCommit) {
previousSha = env.GITHUB_EVENT_BEFORE
previousSha =
env.GITHUB_EVENT_BEFORE ||
(await getRemoteBranchHeadSha({
cwd: workingDirectory,
branch: currentBranch
}))
if (
(await verifyCommitSha({sha: previousSha, cwd: workingDirectory})) !== 0
!previousSha ||
(previousSha &&
(await verifyCommitSha({sha: previousSha, cwd: workingDirectory})) !==
0)
) {
core.warning(
'Unable to locate the remote branch head sha. Falling back to the pull request base sha.'
)
previousSha = env.GITHUB_EVENT_PULL_REQUEST_BASE_SHA
}
} else {

View file

@ -1,15 +1,22 @@
import * as core from '@actions/core'
import path from 'path'
import {getDiffFiles, getRenamedFiles} from './changedFiles'
import {
getAllChangeTypeFiles,
getAllDiffFiles,
getChangeTypeFiles,
getRenamedFiles,
ChangeTypeEnum
} from './changedFiles'
import {
DiffResult,
getSHAForPullRequestEvent,
getSHAForPushEvent,
DiffResult
getSHAForPushEvent
} from './commitSha'
import {getEnv} from './env'
import {getInputs} from './inputs'
import {
getFilePatterns,
getFilteredChangedFiles,
getSubmodulePath,
isRepoShallow,
setOutput,
@ -105,16 +112,27 @@ export async function run(): Promise<void> {
inputs,
workingDirectory
})
core.debug(`File patterns: ${filePatterns}`)
const addedFiles = await getDiffFiles({
inputs,
const allDiffFiles = await getAllDiffFiles({
workingDirectory,
hasSubmodule,
diffResult,
diffFilter: 'A',
filePatterns,
submodulePaths
})
core.debug(`All diff files: ${JSON.stringify(allDiffFiles)}`)
const allFilteredDiffFiles = await getFilteredChangedFiles({
allDiffFiles,
filePatterns
})
core.debug(`All filtered diff files: ${JSON.stringify(allFilteredDiffFiles)}`)
const addedFiles = await getChangeTypeFiles({
inputs,
changedFiles: allFilteredDiffFiles,
changeTypes: [ChangeTypeEnum.Added]
})
core.debug(`Added files: ${addedFiles}`)
await setOutput({
key: 'added_files',
@ -122,14 +140,10 @@ export async function run(): Promise<void> {
inputs
})
const copiedFiles = await getDiffFiles({
const copiedFiles = await getChangeTypeFiles({
inputs,
workingDirectory,
hasSubmodule,
diffResult,
diffFilter: 'C',
filePatterns,
submodulePaths
changedFiles: allFilteredDiffFiles,
changeTypes: [ChangeTypeEnum.Copied]
})
core.debug(`Copied files: ${copiedFiles}`)
await setOutput({
@ -138,14 +152,10 @@ export async function run(): Promise<void> {
inputs
})
const modifiedFiles = await getDiffFiles({
const modifiedFiles = await getChangeTypeFiles({
inputs,
workingDirectory,
hasSubmodule,
diffResult,
diffFilter: 'M',
filePatterns,
submodulePaths
changedFiles: allFilteredDiffFiles,
changeTypes: [ChangeTypeEnum.Modified]
})
core.debug(`Modified files: ${modifiedFiles}`)
await setOutput({
@ -154,14 +164,10 @@ export async function run(): Promise<void> {
inputs
})
const renamedFiles = await getDiffFiles({
const renamedFiles = await getChangeTypeFiles({
inputs,
workingDirectory,
hasSubmodule,
diffResult,
diffFilter: 'R',
filePatterns,
submodulePaths
changedFiles: allFilteredDiffFiles,
changeTypes: [ChangeTypeEnum.Renamed]
})
core.debug(`Renamed files: ${renamedFiles}`)
await setOutput({
@ -170,14 +176,10 @@ export async function run(): Promise<void> {
inputs
})
const typeChangedFiles = await getDiffFiles({
const typeChangedFiles = await getChangeTypeFiles({
inputs,
workingDirectory,
hasSubmodule,
diffResult,
diffFilter: 'T',
filePatterns,
submodulePaths
changedFiles: allFilteredDiffFiles,
changeTypes: [ChangeTypeEnum.TypeChanged]
})
core.debug(`Type changed files: ${typeChangedFiles}`)
await setOutput({
@ -186,14 +188,10 @@ export async function run(): Promise<void> {
inputs
})
const unmergedFiles = await getDiffFiles({
const unmergedFiles = await getChangeTypeFiles({
inputs,
workingDirectory,
hasSubmodule,
diffResult,
diffFilter: 'U',
filePatterns,
submodulePaths
changedFiles: allFilteredDiffFiles,
changeTypes: [ChangeTypeEnum.Unmerged]
})
core.debug(`Unmerged files: ${unmergedFiles}`)
await setOutput({
@ -202,14 +200,10 @@ export async function run(): Promise<void> {
inputs
})
const unknownFiles = await getDiffFiles({
const unknownFiles = await getChangeTypeFiles({
inputs,
workingDirectory,
hasSubmodule,
diffResult,
diffFilter: 'X',
filePatterns,
submodulePaths
changedFiles: allFilteredDiffFiles,
changeTypes: [ChangeTypeEnum.Unknown]
})
core.debug(`Unknown files: ${unknownFiles}`)
await setOutput({
@ -218,14 +212,9 @@ export async function run(): Promise<void> {
inputs
})
const allChangedAndModifiedFiles = await getDiffFiles({
const allChangedAndModifiedFiles = await getAllChangeTypeFiles({
inputs,
workingDirectory,
hasSubmodule,
diffResult,
diffFilter: 'ACDMRTUX',
filePatterns,
submodulePaths
changedFiles: allFilteredDiffFiles
})
core.debug(`All changed and modified files: ${allChangedAndModifiedFiles}`)
await setOutput({
@ -234,14 +223,15 @@ export async function run(): Promise<void> {
inputs
})
const allChangedFiles = await getDiffFiles({
const allChangedFiles = await getChangeTypeFiles({
inputs,
workingDirectory,
hasSubmodule,
diffResult,
diffFilter: 'ACMR',
filePatterns,
submodulePaths
changedFiles: allFilteredDiffFiles,
changeTypes: [
ChangeTypeEnum.Added,
ChangeTypeEnum.Copied,
ChangeTypeEnum.Modified,
ChangeTypeEnum.Renamed
]
})
core.debug(`All changed files: ${allChangedFiles}`)
await setOutput({
@ -256,13 +246,15 @@ export async function run(): Promise<void> {
inputs
})
const allOtherChangedFiles = await getDiffFiles({
const allOtherChangedFiles = await getChangeTypeFiles({
inputs,
workingDirectory,
hasSubmodule,
diffResult,
diffFilter: 'ACMR',
submodulePaths
changedFiles: allDiffFiles,
changeTypes: [
ChangeTypeEnum.Added,
ChangeTypeEnum.Copied,
ChangeTypeEnum.Modified,
ChangeTypeEnum.Renamed
]
})
core.debug(`All other changed files: ${allOtherChangedFiles}`)
@ -289,14 +281,16 @@ export async function run(): Promise<void> {
inputs
})
const allModifiedFiles = await getDiffFiles({
const allModifiedFiles = await getChangeTypeFiles({
inputs,
workingDirectory,
hasSubmodule,
diffResult,
diffFilter: 'ACMRD',
filePatterns,
submodulePaths
changedFiles: allFilteredDiffFiles,
changeTypes: [
ChangeTypeEnum.Added,
ChangeTypeEnum.Copied,
ChangeTypeEnum.Modified,
ChangeTypeEnum.Renamed,
ChangeTypeEnum.Deleted
]
})
core.debug(`All modified files: ${allModifiedFiles}`)
await setOutput({
@ -311,13 +305,16 @@ export async function run(): Promise<void> {
inputs
})
const allOtherModifiedFiles = await getDiffFiles({
const allOtherModifiedFiles = await getChangeTypeFiles({
inputs,
workingDirectory,
hasSubmodule,
diffResult,
diffFilter: 'ACMRD',
submodulePaths
changedFiles: allDiffFiles,
changeTypes: [
ChangeTypeEnum.Added,
ChangeTypeEnum.Copied,
ChangeTypeEnum.Modified,
ChangeTypeEnum.Renamed,
ChangeTypeEnum.Deleted
]
})
const otherModifiedFiles = allOtherModifiedFiles
@ -343,14 +340,10 @@ export async function run(): Promise<void> {
inputs
})
const deletedFiles = await getDiffFiles({
const deletedFiles = await getChangeTypeFiles({
inputs,
workingDirectory,
hasSubmodule,
diffResult,
diffFilter: 'D',
filePatterns,
submodulePaths
changedFiles: allFilteredDiffFiles,
changeTypes: [ChangeTypeEnum.Deleted]
})
core.debug(`Deleted files: ${deletedFiles}`)
await setOutput({
@ -365,13 +358,10 @@ export async function run(): Promise<void> {
inputs
})
const allOtherDeletedFiles = await getDiffFiles({
const allOtherDeletedFiles = await getChangeTypeFiles({
inputs,
workingDirectory,
hasSubmodule,
diffResult,
diffFilter: 'D',
submodulePaths
changedFiles: allDiffFiles,
changeTypes: [ChangeTypeEnum.Deleted]
})
const otherDeletedFiles = allOtherDeletedFiles

View file

@ -5,6 +5,7 @@ import {createReadStream, promises as fs} from 'fs'
import mm from 'micromatch'
import * as path from 'path'
import {createInterface} from 'readline'
import {ChangedFiles, ChangeTypeEnum} from './changedFiles'
import {Inputs} from './inputs'
@ -403,32 +404,28 @@ export const gitRenamedFiles = async ({
})
}
export const gitDiff = async ({
export const getAllChangedFiles = async ({
cwd,
sha1,
sha2,
diff,
diffFilter,
filePatterns = [],
isSubmodule = false,
parentDir = ''
}: {
cwd: string
sha1: string
sha2: string
diffFilter: string
diff: string
filePatterns?: string[]
isSubmodule?: boolean
parentDir?: string
}): Promise<string[]> => {
}): Promise<ChangedFiles> => {
const {exitCode, stdout, stderr} = await exec.getExecOutput(
'git',
[
'diff',
'--name-only',
'--name-status',
'--ignore-submodules=all',
`--diff-filter=${diffFilter}`,
`--diff-filter=ACDMRTUX`,
`${sha1}${diff}${sha2}`
],
{
@ -437,6 +434,16 @@ export const gitDiff = async ({
silent: process.env.RUNNER_DEBUG !== '1'
}
)
const changedFiles: ChangedFiles = {
[ChangeTypeEnum.Added]: [],
[ChangeTypeEnum.Copied]: [],
[ChangeTypeEnum.Deleted]: [],
[ChangeTypeEnum.Modified]: [],
[ChangeTypeEnum.Renamed]: [],
[ChangeTypeEnum.TypeChanged]: [],
[ChangeTypeEnum.Unmerged]: [],
[ChangeTypeEnum.Unknown]: []
}
if (exitCode !== 0) {
if (isSubmodule) {
@ -453,28 +460,60 @@ export const gitDiff = async ({
)
}
return []
return changedFiles
}
const files = stdout
.split('\n')
.filter(Boolean)
.map((p: string) => {
if (isSubmodule) {
return normalizePath(path.join(parentDir, p))
}
return normalizePath(p)
})
const lines = stdout.split('\n').filter(Boolean)
if (filePatterns.length === 0) {
return files
for (const line of lines) {
const [changeType, filePath] = line.split('\t')
const normalizedFilePath = isSubmodule
? normalizePath(path.join(parentDir, filePath))
: normalizePath(filePath)
if (changeType.startsWith('R')) {
changedFiles[ChangeTypeEnum.Renamed].push(normalizedFilePath)
} else {
changedFiles[changeType as ChangeTypeEnum].push(normalizedFilePath)
}
}
return changedFiles
}
export const getFilteredChangedFiles = async ({
allDiffFiles,
filePatterns
}: {
allDiffFiles: ChangedFiles
filePatterns: string[]
}): Promise<ChangedFiles> => {
const changedFiles: ChangedFiles = {
[ChangeTypeEnum.Added]: [],
[ChangeTypeEnum.Copied]: [],
[ChangeTypeEnum.Deleted]: [],
[ChangeTypeEnum.Modified]: [],
[ChangeTypeEnum.Renamed]: [],
[ChangeTypeEnum.TypeChanged]: [],
[ChangeTypeEnum.Unmerged]: [],
[ChangeTypeEnum.Unknown]: []
}
return mm(files, filePatterns, {
dot: true,
windows: IS_WINDOWS,
noext: true
})
for (const changeType of Object.keys(allDiffFiles)) {
const files = allDiffFiles[changeType as ChangeTypeEnum]
const hasFilePatterns = filePatterns.length > 0
if (hasFilePatterns) {
changedFiles[changeType as ChangeTypeEnum] = mm(files, filePatterns, {
dot: true,
windows: IS_WINDOWS,
noext: true
})
} else {
changedFiles[changeType as ChangeTypeEnum] = files
}
}
return changedFiles
}
export const gitLog = async ({

View file

@ -1 +1 @@
This is a test file with non ascii character in the filename.
This is a test file with non ASCII character in the filename.

1036
yarn.lock

File diff suppressed because it is too large Load diff