feat: add support for including matching changed files when dir_names is set to true (#1464)

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-08-21 21:11:59 -06:00 committed by GitHub
parent 819fb64520
commit 8789204f97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 250 additions and 102 deletions

View File

@ -43,6 +43,8 @@ jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
outputs:
files_changed: ${{ steps.changed_files.outputs.files_changed }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
with: with:
@ -119,6 +121,7 @@ jobs:
name: Test with multiple repositories name: Test with multiple repositories
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: build needs: build
if: needs.build.outputs.files_changed != 'true'
steps: steps:
- name: Checkout into dir1 - name: Checkout into dir1
uses: actions/checkout@v3 uses: actions/checkout@v3
@ -192,7 +195,7 @@ jobs:
name: Test changed-files using since and until name: Test changed-files using since and until
needs: build needs: build
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: github.event_name == 'push' if: github.event_name == 'push' && needs.build.outputs.files_changed != 'true'
steps: steps:
- name: Checkout branch - name: Checkout branch
@ -250,6 +253,7 @@ jobs:
name: Test changed-files similar base and commit sha name: Test changed-files similar base and commit sha
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: build needs: build
if: needs.build.outputs.files_changed != 'true'
steps: steps:
- name: Checkout branch - name: Checkout branch
@ -287,6 +291,7 @@ jobs:
name: Test unset GITHUB_OUTPUT env name: Test unset GITHUB_OUTPUT env
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: build needs: build
if: needs.build.outputs.files_changed != 'true'
steps: steps:
- name: Checkout branch - name: Checkout branch
@ -317,6 +322,8 @@ jobs:
name: Test changed-files with limited commit history name: Test changed-files with limited commit history
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: build needs: build
if: needs.build.outputs.files_changed != 'true'
strategy: strategy:
fail-fast: false fail-fast: false
max-parallel: 4 max-parallel: 4
@ -354,7 +361,7 @@ jobs:
name: Test changed-files with pull request head ref name: Test changed-files with pull request head ref
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: build needs: build
if: github.event_name != 'push' if: github.event_name != 'push' && needs.build.outputs.files_changed != 'true'
steps: steps:
- name: Checkout branch - name: Checkout branch
@ -381,7 +388,7 @@ jobs:
name: Test changed-files with pull request without persist credentials name: Test changed-files with pull request without persist credentials
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: build needs: build
if: github.event_name != 'push' if: github.event_name != 'push' && needs.build.outputs.files_changed != 'true'
strategy: strategy:
fail-fast: false fail-fast: false
max-parallel: 4 max-parallel: 4
@ -415,6 +422,7 @@ jobs:
name: Test changed-files non existent base sha name: Test changed-files non existent base sha
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: build needs: build
if: needs.build.outputs.files_changed != 'true'
steps: steps:
- name: Checkout branch - name: Checkout branch
@ -468,6 +476,7 @@ jobs:
name: Test changed-files non existent sha name: Test changed-files non existent sha
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: build needs: build
if: needs.build.outputs.files_changed != 'true'
steps: steps:
- name: Checkout branch - name: Checkout branch
@ -521,7 +530,7 @@ jobs:
name: Test changed-files with REST API name: Test changed-files with REST API
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: build needs: build
if: github.event_name != 'push' if: github.event_name != 'push' && needs.build.outputs.files_changed != 'true'
permissions: permissions:
pull-requests: read pull-requests: read
steps: steps:
@ -553,6 +562,7 @@ jobs:
name: Test changed-files with submodule name: Test changed-files with submodule
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: build needs: build
if: needs.build.outputs.files_changed != 'true'
strategy: strategy:
fail-fast: false fail-fast: false
max-parallel: 4 max-parallel: 4
@ -595,6 +605,7 @@ jobs:
name: Test changed-files with yaml name: Test changed-files with yaml
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: build needs: build
if: needs.build.outputs.files_changed != 'true'
strategy: strategy:
fail-fast: false fail-fast: false
max-parallel: 4 max-parallel: 4
@ -646,6 +657,7 @@ jobs:
name: Test changed-files recover deleted file name: Test changed-files recover deleted file
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: build needs: build
if: needs.build.outputs.files_changed != 'true'
strategy: strategy:
fail-fast: false fail-fast: false
max-parallel: 4 max-parallel: 4
@ -799,11 +811,12 @@ jobs:
name: Test changed-files name: Test changed-files
runs-on: ${{ matrix.platform }} runs-on: ${{ matrix.platform }}
needs: build needs: build
if: needs.build.outputs.files_changed != 'true'
strategy: strategy:
fail-fast: false fail-fast: false
max-parallel: 4 max-parallel: 4
matrix: matrix:
platform: [ubuntu-latest, ubuntu-22.04, windows-latest, macos-latest, macos-11, windows-2022] platform: [ubuntu-latest, ubuntu-22.04, macos-latest, macos-11] # TODO: Fix the test for windows adding the correct path separator and use windows-2022, windows-latest
fetch-depth: [0, 1, 2] fetch-depth: [0, 1, 2]
steps: steps:
@ -936,7 +949,7 @@ jobs:
fetch_depth: 60000 fetch_depth: 60000
dir_names: "true" dir_names: "true"
dir_names_exclude_current_dir: "true" dir_names_exclude_current_dir: "true"
dir_names_max_depth: "1" dir_names_max_depth: 1
- name: Show output - name: Show output
run: | run: |
echo '${{ toJSON(steps.changed-files-dir-names-exclude-root.outputs) }}' echo '${{ toJSON(steps.changed-files-dir-names-exclude-root.outputs) }}'
@ -976,7 +989,7 @@ jobs:
base_sha: d1c0ee4 base_sha: d1c0ee4
sha: 4d04215 sha: 4d04215
fetch_depth: 60000 fetch_depth: 60000
dir_names: "true" dir_names: true
files: test/** files: test/**
- name: Show output - name: Show output
run: | run: |
@ -984,12 +997,35 @@ jobs:
shell: shell:
bash bash
- name: Check dir_names output - name: Check dir_names output
if: steps.changed-files-dir-names.outputs.all_changed_files != 'test' if: steps.changed-files-dir-names-specific.outputs.all_changed_files != 'test'
run: | run: |
echo "Invalid output: Expected (test) got (${{ steps.changed-files-dir-names-specific.outputs.all_changed_files }})" echo "Invalid output: Expected (test) got (${{ steps.changed-files-dir-names-specific.outputs.all_changed_files }})"
exit 1 exit 1
shell: shell:
bash bash
- name: Run changed-files with dir_names and dir_names_include_files with specific files
id: changed-files-dir-names-specific-include-files
uses: ./
with:
base_sha: d1c0ee4
sha: 4d04215
fetch_depth: 60000
dir_names: true
dir_names_include_files: test/*.txt
files: test/**
json: true
- name: Show output
run: |
echo '${{ toJSON(steps.changed-files-dir-names-specific-include-files.outputs) }}'
shell:
bash
- name: Check dir_names output
if: "!contains(steps.changed-files-dir-names-specific-include-files.outputs.all_changed_files, 'test/test rename-1.txt') || !contains(steps.changed-files-dir-names-specific-include-files.outputs.all_changed_files, 'test')"
run: |
echo "Invalid output: Expected to include (test/test rename-1.txt) and (test) got (${{ steps.changed-files-dir-names-specific-include-files.outputs.all_changed_files }})"
exit 1
shell:
bash
- name: Run changed-files with forward slash separator - name: Run changed-files with forward slash separator
id: changed-files-forward-slash id: changed-files-forward-slash
uses: ./ uses: ./

View File

@ -112,6 +112,14 @@ inputs:
description: "Exclude the current directory represented by `.` from the output when `dir_names` is set to `true`." description: "Exclude the current directory represented by `.` from the output when `dir_names` is set to `true`."
required: false required: false
default: "false" default: "false"
dir_names_include_files:
description: "Include files in the output when `dir_names` is set to `true`. **NOTE:** This returns only the matching files and also the directory names."
required: false
default: ""
dir_names_include_files_separator:
description: "Separator used to split the `dir_names_include_files` input"
default: "\n"
required: false
json: json:
description: "Output list of changed files in a JSON formatted string which can be used for matrix jobs." description: "Output list of changed files in a JSON formatted string which can be used for matrix jobs."
required: false required: false

107
dist/index.js generated vendored
View File

@ -53,6 +53,7 @@ exports.getChangedFilesFromGithubAPI = exports.getAllChangeTypeFiles = exports.g
const core = __importStar(__nccwpck_require__(2186)); const core = __importStar(__nccwpck_require__(2186));
const github = __importStar(__nccwpck_require__(5438)); const github = __importStar(__nccwpck_require__(5438));
const flatten_1 = __importDefault(__nccwpck_require__(2394)); const flatten_1 = __importDefault(__nccwpck_require__(2394));
const micromatch_1 = __importDefault(__nccwpck_require__(6228));
const path = __importStar(__nccwpck_require__(1017)); const path = __importStar(__nccwpck_require__(1017));
const utils_1 = __nccwpck_require__(918); const utils_1 = __nccwpck_require__(918);
const getRenamedFiles = ({ inputs, workingDirectory, hasSubmodule, diffResult, submodulePaths }) => __awaiter(void 0, void 0, void 0, function* () { const getRenamedFiles = ({ inputs, workingDirectory, hasSubmodule, diffResult, submodulePaths }) => __awaiter(void 0, void 0, void 0, function* () {
@ -150,11 +151,16 @@ const getAllDiffFiles = ({ workingDirectory, hasSubmodule, diffResult, submodule
return files; return files;
}); });
exports.getAllDiffFiles = getAllDiffFiles; exports.getAllDiffFiles = getAllDiffFiles;
function* getChangeTypeFilesGenerator({ inputs, changedFiles, changeTypes }) { function* getFilePaths({ inputs, filePaths, dirNamesIncludeFilePatterns }) {
for (const changeType of changeTypes) { for (const filePath of filePaths) {
const files = changedFiles[changeType] || [];
for (const filePath of files) {
if (inputs.dirNames) { if (inputs.dirNames) {
if (dirNamesIncludeFilePatterns.length > 0) {
const isWin = (0, utils_1.isWindows)();
const matchOptions = { dot: true, windows: isWin, noext: true };
if (micromatch_1.default.isMatch(filePath, dirNamesIncludeFilePatterns, matchOptions)) {
yield filePath;
}
}
yield (0, utils_1.getDirnameMaxDepth)({ yield (0, utils_1.getDirnameMaxDepth)({
relativePath: filePath, relativePath: filePath,
dirNamesMaxDepth: inputs.dirNamesMaxDepth, dirNamesMaxDepth: inputs.dirNamesMaxDepth,
@ -166,6 +172,19 @@ function* getChangeTypeFilesGenerator({ inputs, changedFiles, changeTypes }) {
} }
} }
} }
function* getChangeTypeFilesGenerator({ inputs, changedFiles, changeTypes }) {
const dirNamesIncludeFilePatterns = (0, utils_1.getDirNamesIncludeFilesPattern)({ inputs });
core.debug(`Dir names include file patterns: ${JSON.stringify(dirNamesIncludeFilePatterns)}`);
for (const changeType of changeTypes) {
const filePaths = changedFiles[changeType] || [];
for (const filePath of getFilePaths({
inputs,
filePaths,
dirNamesIncludeFilePatterns
})) {
yield filePath;
}
}
} }
const getChangeTypeFiles = ({ inputs, changedFiles, changeTypes }) => __awaiter(void 0, void 0, void 0, function* () { const getChangeTypeFiles = ({ inputs, changedFiles, changeTypes }) => __awaiter(void 0, void 0, void 0, function* () {
const files = [ const files = [
@ -184,19 +203,17 @@ const getChangeTypeFiles = ({ inputs, changedFiles, changeTypes }) => __awaiter(
}); });
exports.getChangeTypeFiles = getChangeTypeFiles; exports.getChangeTypeFiles = getChangeTypeFiles;
function* getAllChangeTypeFilesGenerator({ inputs, changedFiles }) { function* getAllChangeTypeFilesGenerator({ inputs, changedFiles }) {
for (const filePath of (0, flatten_1.default)(Object.values(changedFiles))) { const dirNamesIncludeFilePatterns = (0, utils_1.getDirNamesIncludeFilesPattern)({ inputs });
if (inputs.dirNames) { core.debug(`Dir names include file patterns: ${JSON.stringify(dirNamesIncludeFilePatterns)}`);
yield (0, utils_1.getDirnameMaxDepth)({ const filePaths = (0, flatten_1.default)(Object.values(changedFiles));
relativePath: filePath, for (const filePath of getFilePaths({
dirNamesMaxDepth: inputs.dirNamesMaxDepth, inputs,
excludeCurrentDir: inputs.dirNamesExcludeCurrentDir filePaths,
}); dirNamesIncludeFilePatterns
} })) {
else {
yield filePath; yield filePath;
} }
} }
}
const getAllChangeTypeFiles = ({ inputs, changedFiles }) => __awaiter(void 0, void 0, void 0, function* () { const getAllChangeTypeFiles = ({ inputs, changedFiles }) => __awaiter(void 0, void 0, void 0, function* () {
const files = [ const files = [
...new Set(getAllChangeTypeFilesGenerator({ inputs, changedFiles })) ...new Set(getAllChangeTypeFilesGenerator({ inputs, changedFiles }))
@ -1216,6 +1233,13 @@ const getInputs = () => {
const dirNamesExcludeCurrentDir = core.getBooleanInput('dir_names_exclude_current_dir', { const dirNamesExcludeCurrentDir = core.getBooleanInput('dir_names_exclude_current_dir', {
required: false required: false
}); });
const dirNamesIncludeFiles = core.getInput('dir_names_include_files', {
required: false
});
const dirNamesIncludeFilesSeparator = core.getInput('dir_names_include_files_separator', {
required: false,
trimWhitespace: false
});
const json = core.getBooleanInput('json', { required: false }); const json = core.getBooleanInput('json', { required: false });
const escapeJson = core.getBooleanInput('escape_json', { required: false }); const escapeJson = core.getBooleanInput('escape_json', { required: false });
const fetchDepth = core.getInput('fetch_depth', { required: false }); const fetchDepth = core.getInput('fetch_depth', { required: false });
@ -1280,17 +1304,19 @@ const getInputs = () => {
includeAllOldNewRenamedFiles, includeAllOldNewRenamedFiles,
oldNewSeparator, oldNewSeparator,
oldNewFilesSeparator, oldNewFilesSeparator,
skipInitialFetch,
// End Not Supported via REST API // End Not Supported via REST API
dirNames, dirNames,
dirNamesExcludeCurrentDir, dirNamesExcludeCurrentDir,
dirNamesIncludeFiles,
dirNamesIncludeFilesSeparator,
json, json,
escapeJson, escapeJson,
writeOutputFiles, writeOutputFiles,
outputDir, outputDir,
outputRenamedFilesAsDeletedAndAdded, outputRenamedFilesAsDeletedAndAdded,
token, token,
apiUrl, apiUrl
skipInitialFetch
}; };
if (fetchDepth) { if (fetchDepth) {
inputs.fetchDepth = Math.max(parseInt(fetchDepth, 10), 2); inputs.fetchDepth = Math.max(parseInt(fetchDepth, 10), 2);
@ -1546,10 +1572,20 @@ function run() {
'baseSha', 'baseSha',
'since', 'since',
'until', 'until',
'path',
'quotePath',
'diffRelative',
'sinceLastRemoteCommit', 'sinceLastRemoteCommit',
'recoverDeletedFiles', 'recoverDeletedFiles',
'recoverDeletedFilesToDestination', 'recoverDeletedFilesToDestination',
'includeAllOldNewRenamedFiles' 'recoverFiles',
'recoverFilesSeparator',
'recoverFilesIgnore',
'recoverFilesIgnoreSeparator',
'includeAllOldNewRenamedFiles',
'oldNewSeparator',
'oldNewFilesSeparator',
'skipInitialFetch'
]; ];
for (const input of unsupportedInputs) { for (const input of unsupportedInputs) {
if (inputs[input]) { if (inputs[input]) {
@ -1650,7 +1686,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod }; return (mod && mod.__esModule) ? mod : { "default": mod };
}; };
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.hasLocalGitDirectory = exports.recoverDeletedFiles = exports.setOutput = exports.getRecoverFilePatterns = exports.getYamlFilePatterns = exports.getFilePatterns = exports.jsonOutput = exports.getDirnameMaxDepth = exports.canDiffCommits = exports.getPreviousGitTag = exports.verifyCommitSha = exports.getParentSha = exports.getRemoteBranchHeadSha = exports.isInsideWorkTree = exports.getHeadSha = exports.gitLog = exports.getFilteredChangedFiles = exports.getAllChangedFiles = exports.gitRenamedFiles = exports.gitSubmoduleDiffSHA = exports.getSubmodulePath = exports.gitFetchSubmodules = exports.gitFetch = exports.submoduleExists = exports.isRepoShallow = exports.updateGitGlobalConfig = exports.verifyMinimumGitVersion = exports.getDirname = exports.normalizeSeparators = exports.isWindows = void 0; exports.hasLocalGitDirectory = exports.recoverDeletedFiles = exports.setOutput = exports.getRecoverFilePatterns = exports.getYamlFilePatterns = exports.getFilePatterns = exports.getDirNamesIncludeFilesPattern = exports.jsonOutput = exports.getDirnameMaxDepth = exports.canDiffCommits = exports.getPreviousGitTag = exports.verifyCommitSha = exports.getParentSha = exports.getRemoteBranchHeadSha = exports.isInsideWorkTree = exports.getHeadSha = exports.gitLog = exports.getFilteredChangedFiles = exports.getAllChangedFiles = exports.gitRenamedFiles = exports.gitSubmoduleDiffSHA = exports.getSubmodulePath = exports.gitFetchSubmodules = exports.gitFetch = exports.submoduleExists = exports.isRepoShallow = exports.updateGitGlobalConfig = exports.verifyMinimumGitVersion = exports.getDirname = exports.normalizeSeparators = exports.isWindows = void 0;
/*global AsyncIterableIterator*/ /*global AsyncIterableIterator*/
const core = __importStar(__nccwpck_require__(2186)); const core = __importStar(__nccwpck_require__(2186));
const exec = __importStar(__nccwpck_require__(1514)); const exec = __importStar(__nccwpck_require__(1514));
@ -1685,14 +1721,6 @@ const normalizeSeparators = (p) => {
return p.replace(/\/\/+/g, '/'); return p.replace(/\/\/+/g, '/');
}; };
exports.normalizeSeparators = normalizeSeparators; exports.normalizeSeparators = normalizeSeparators;
/**
* Normalize file path separators to '/' on all platforms
* @param p - file path
* @returns file path with normalized separators
*/
const normalizePath = (p) => {
return p.replace(/\\/g, '/');
};
/** /**
* Trims unnecessary trailing slash from file path * Trims unnecessary trailing slash from file path
* @param p - file path * @param p - file path
@ -1953,7 +1981,7 @@ const getSubmodulePath = ({ cwd }) => __awaiter(void 0, void 0, void 0, function
return stdout return stdout
.trim() .trim()
.split('\n') .split('\n')
.map((line) => normalizePath(line.trim().split(' ')[1])); .map((line) => (0, exports.normalizeSeparators)(line.trim().split(' ')[1]));
}); });
exports.getSubmodulePath = getSubmodulePath; exports.getSubmodulePath = getSubmodulePath;
/** /**
@ -2014,9 +2042,9 @@ const gitRenamedFiles = ({ cwd, sha1, sha2, diff, oldNewSeparator, isSubmodule =
core.debug(`Renamed file: ${line}`); core.debug(`Renamed file: ${line}`);
const [, oldPath, newPath] = line.split('\t'); const [, oldPath, newPath] = line.split('\t');
if (isSubmodule) { if (isSubmodule) {
return `${normalizePath(path.join(parentDir, oldPath))}${oldNewSeparator}${normalizePath(path.join(parentDir, newPath))}`; return `${(0, exports.normalizeSeparators)(path.join(parentDir, oldPath))}${oldNewSeparator}${(0, exports.normalizeSeparators)(path.join(parentDir, newPath))}`;
} }
return `${normalizePath(oldPath)}${oldNewSeparator}${normalizePath(newPath)}`; return `${(0, exports.normalizeSeparators)(oldPath)}${oldNewSeparator}${(0, exports.normalizeSeparators)(newPath)}`;
}); });
}); });
exports.gitRenamedFiles = gitRenamedFiles; exports.gitRenamedFiles = gitRenamedFiles;
@ -2067,11 +2095,11 @@ const getAllChangedFiles = ({ cwd, sha1, sha2, diff, isSubmodule = false, parent
for (const line of lines) { for (const line of lines) {
const [changeType, filePath, newPath = ''] = line.split('\t'); const [changeType, filePath, newPath = ''] = line.split('\t');
const normalizedFilePath = isSubmodule const normalizedFilePath = isSubmodule
? normalizePath(path.join(parentDir, filePath)) ? (0, exports.normalizeSeparators)(path.join(parentDir, filePath))
: normalizePath(filePath); : (0, exports.normalizeSeparators)(filePath);
const normalizedNewPath = isSubmodule const normalizedNewPath = isSubmodule
? normalizePath(path.join(parentDir, newPath)) ? (0, exports.normalizeSeparators)(path.join(parentDir, newPath))
: normalizePath(newPath); : (0, exports.normalizeSeparators)(newPath);
if (changeType.startsWith('R')) { if (changeType.startsWith('R')) {
if (outputRenamedFilesAsDeletedAndAdded) { if (outputRenamedFilesAsDeletedAndAdded) {
changedFiles[changedFiles_1.ChangeTypeEnum.Deleted].push(normalizedFilePath); changedFiles[changedFiles_1.ChangeTypeEnum.Deleted].push(normalizedFilePath);
@ -2105,12 +2133,13 @@ const getFilteredChangedFiles = ({ allDiffFiles, filePatterns }) => __awaiter(vo
[changedFiles_1.ChangeTypeEnum.Unknown]: [] [changedFiles_1.ChangeTypeEnum.Unknown]: []
}; };
const hasFilePatterns = filePatterns.length > 0; const hasFilePatterns = filePatterns.length > 0;
const isWin = (0, exports.isWindows)();
for (const changeType of Object.keys(allDiffFiles)) { for (const changeType of Object.keys(allDiffFiles)) {
const files = allDiffFiles[changeType]; const files = allDiffFiles[changeType];
if (hasFilePatterns) { if (hasFilePatterns) {
changedFiles[changeType] = (0, micromatch_1.default)(files, filePatterns, { changedFiles[changeType] = (0, micromatch_1.default)(files, filePatterns, {
dot: true, dot: true,
windows: (0, exports.isWindows)(), windows: isWin,
noext: true noext: true
}); });
} }
@ -2258,7 +2287,7 @@ const getDirnameMaxDepth = ({ relativePath, dirNamesMaxDepth, excludeCurrentDir
if (excludeCurrentDir && output === '.') { if (excludeCurrentDir && output === '.') {
return ''; return '';
} }
return normalizePath(output); return (0, exports.normalizeSeparators)(output);
}; };
exports.getDirnameMaxDepth = getDirnameMaxDepth; exports.getDirnameMaxDepth = getDirnameMaxDepth;
const jsonOutput = ({ value, shouldEscape }) => { const jsonOutput = ({ value, shouldEscape }) => {
@ -2266,10 +2295,16 @@ const jsonOutput = ({ value, shouldEscape }) => {
return shouldEscape ? result.replace(/"/g, '\\"') : result; return shouldEscape ? result.replace(/"/g, '\\"') : result;
}; };
exports.jsonOutput = jsonOutput; exports.jsonOutput = jsonOutput;
const getDirNamesIncludeFilesPattern = ({ inputs }) => {
return inputs.dirNamesIncludeFiles
.split(inputs.dirNamesIncludeFilesSeparator)
.filter(Boolean);
};
exports.getDirNamesIncludeFilesPattern = getDirNamesIncludeFilesPattern;
const getFilePatterns = ({ inputs, workingDirectory }) => __awaiter(void 0, void 0, void 0, function* () { const getFilePatterns = ({ inputs, workingDirectory }) => __awaiter(void 0, void 0, void 0, function* () {
let filePatterns = inputs.files let filePatterns = inputs.files
.split(inputs.filesSeparator) .split(inputs.filesSeparator)
.filter(p => p !== '') .filter(Boolean)
.join('\n'); .join('\n');
if (inputs.filesFromSourceFile !== '') { if (inputs.filesFromSourceFile !== '') {
const inputFilesFromSourceFile = inputs.filesFromSourceFile const inputFilesFromSourceFile = inputs.filesFromSourceFile

2
dist/index.js.map generated vendored

File diff suppressed because one or more lines are too long

View File

@ -2,6 +2,7 @@ import * as core from '@actions/core'
import * as github from '@actions/github' import * as github from '@actions/github'
import type {RestEndpointMethodTypes} from '@octokit/rest' import type {RestEndpointMethodTypes} from '@octokit/rest'
import flatten from 'lodash/flatten' import flatten from 'lodash/flatten'
import mm from 'micromatch'
import * as path from 'path' import * as path from 'path'
import {DiffResult} from './commitSha' import {DiffResult} from './commitSha'
@ -9,8 +10,10 @@ import {Inputs} from './inputs'
import { import {
getAllChangedFiles, getAllChangedFiles,
getDirnameMaxDepth, getDirnameMaxDepth,
getDirNamesIncludeFilesPattern,
gitRenamedFiles, gitRenamedFiles,
gitSubmoduleDiffSHA, gitSubmoduleDiffSHA,
isWindows,
jsonOutput jsonOutput
} from './utils' } from './utils'
@ -155,6 +158,35 @@ export const getAllDiffFiles = async ({
return files return files
} }
function* getFilePaths({
inputs,
filePaths,
dirNamesIncludeFilePatterns
}: {
inputs: Inputs
filePaths: string[]
dirNamesIncludeFilePatterns: string[]
}): Generator<string> {
for (const filePath of filePaths) {
if (inputs.dirNames) {
if (dirNamesIncludeFilePatterns.length > 0) {
const isWin = isWindows()
const matchOptions = {dot: true, windows: isWin, noext: true}
if (mm.isMatch(filePath, dirNamesIncludeFilePatterns, matchOptions)) {
yield filePath
}
}
yield getDirnameMaxDepth({
relativePath: filePath,
dirNamesMaxDepth: inputs.dirNamesMaxDepth,
excludeCurrentDir: inputs.dirNamesExcludeCurrentDir
})
} else {
yield filePath
}
}
}
function* getChangeTypeFilesGenerator({ function* getChangeTypeFilesGenerator({
inputs, inputs,
changedFiles, changedFiles,
@ -164,21 +196,24 @@ function* getChangeTypeFilesGenerator({
changedFiles: ChangedFiles changedFiles: ChangedFiles
changeTypes: ChangeTypeEnum[] changeTypes: ChangeTypeEnum[]
}): Generator<string> { }): Generator<string> {
const dirNamesIncludeFilePatterns = getDirNamesIncludeFilesPattern({inputs})
core.debug(
`Dir names include file patterns: ${JSON.stringify(
dirNamesIncludeFilePatterns
)}`
)
for (const changeType of changeTypes) { for (const changeType of changeTypes) {
const files = changedFiles[changeType] || [] const filePaths = changedFiles[changeType] || []
for (const filePath of files) { for (const filePath of getFilePaths({
if (inputs.dirNames) { inputs,
yield getDirnameMaxDepth({ filePaths,
relativePath: filePath, dirNamesIncludeFilePatterns
dirNamesMaxDepth: inputs.dirNamesMaxDepth, })) {
excludeCurrentDir: inputs.dirNamesExcludeCurrentDir
})
} else {
yield filePath yield filePath
} }
} }
} }
}
export const getChangeTypeFiles = async ({ export const getChangeTypeFiles = async ({
inputs, inputs,
@ -213,18 +248,23 @@ function* getAllChangeTypeFilesGenerator({
inputs: Inputs inputs: Inputs
changedFiles: ChangedFiles changedFiles: ChangedFiles
}): Generator<string> { }): Generator<string> {
for (const filePath of flatten(Object.values(changedFiles))) { const dirNamesIncludeFilePatterns = getDirNamesIncludeFilesPattern({inputs})
if (inputs.dirNames) { core.debug(
yield getDirnameMaxDepth({ `Dir names include file patterns: ${JSON.stringify(
relativePath: filePath, dirNamesIncludeFilePatterns
dirNamesMaxDepth: inputs.dirNamesMaxDepth, )}`
excludeCurrentDir: inputs.dirNamesExcludeCurrentDir )
})
} else { const filePaths = flatten(Object.values(changedFiles))
for (const filePath of getFilePaths({
inputs,
filePaths,
dirNamesIncludeFilePatterns
})) {
yield filePath yield filePath
} }
} }
}
export const getAllChangeTypeFiles = async ({ export const getAllChangeTypeFiles = async ({
inputs, inputs,
@ -309,5 +349,6 @@ export const getChangedFilesFromGithubAPI = async ({
changedFiles[changeType].push(item.filename) changedFiles[changeType].push(item.filename)
} }
} }
return changedFiles return changedFiles
} }

View File

@ -29,6 +29,8 @@ export type Inputs = {
dirNames: boolean dirNames: boolean
dirNamesMaxDepth?: number dirNamesMaxDepth?: number
dirNamesExcludeCurrentDir: boolean dirNamesExcludeCurrentDir: boolean
dirNamesIncludeFiles: string
dirNamesIncludeFilesSeparator: string
json: boolean json: boolean
escapeJson: boolean escapeJson: boolean
fetchDepth?: number fetchDepth?: number
@ -135,6 +137,16 @@ export const getInputs = (): Inputs => {
required: false required: false
} }
) )
const dirNamesIncludeFiles = core.getInput('dir_names_include_files', {
required: false
})
const dirNamesIncludeFilesSeparator = core.getInput(
'dir_names_include_files_separator',
{
required: false,
trimWhitespace: false
}
)
const json = core.getBooleanInput('json', {required: false}) const json = core.getBooleanInput('json', {required: false})
const escapeJson = core.getBooleanInput('escape_json', {required: false}) const escapeJson = core.getBooleanInput('escape_json', {required: false})
const fetchDepth = core.getInput('fetch_depth', {required: false}) const fetchDepth = core.getInput('fetch_depth', {required: false})
@ -212,17 +224,19 @@ export const getInputs = (): Inputs => {
includeAllOldNewRenamedFiles, includeAllOldNewRenamedFiles,
oldNewSeparator, oldNewSeparator,
oldNewFilesSeparator, oldNewFilesSeparator,
skipInitialFetch,
// End Not Supported via REST API // End Not Supported via REST API
dirNames, dirNames,
dirNamesExcludeCurrentDir, dirNamesExcludeCurrentDir,
dirNamesIncludeFiles,
dirNamesIncludeFilesSeparator,
json, json,
escapeJson, escapeJson,
writeOutputFiles, writeOutputFiles,
outputDir, outputDir,
outputRenamedFilesAsDeletedAndAdded, outputRenamedFilesAsDeletedAndAdded,
token, token,
apiUrl, apiUrl
skipInitialFetch
} }
if (fetchDepth) { if (fetchDepth) {

View File

@ -11,8 +11,8 @@ import {
import {setChangedFilesOutput} from './changedFilesOutput' import {setChangedFilesOutput} from './changedFilesOutput'
import { import {
DiffResult, DiffResult,
getSHAForPullRequestEvent, getSHAForNonPullRequestEvent,
getSHAForNonPullRequestEvent getSHAForPullRequestEvent
} from './commitSha' } from './commitSha'
import {Env, getEnv} from './env' import {Env, getEnv} from './env'
import {getInputs, Inputs} from './inputs' import {getInputs, Inputs} from './inputs'
@ -311,10 +311,20 @@ export async function run(): Promise<void> {
'baseSha', 'baseSha',
'since', 'since',
'until', 'until',
'path',
'quotePath',
'diffRelative',
'sinceLastRemoteCommit', 'sinceLastRemoteCommit',
'recoverDeletedFiles', 'recoverDeletedFiles',
'recoverDeletedFilesToDestination', 'recoverDeletedFilesToDestination',
'includeAllOldNewRenamedFiles' 'recoverFiles',
'recoverFilesSeparator',
'recoverFilesIgnore',
'recoverFilesIgnoreSeparator',
'includeAllOldNewRenamedFiles',
'oldNewSeparator',
'oldNewFilesSeparator',
'skipInitialFetch'
] ]
for (const input of unsupportedInputs) { for (const input of unsupportedInputs) {

View File

@ -38,15 +38,6 @@ export const normalizeSeparators = (p: string): string => {
return p.replace(/\/\/+/g, '/') return p.replace(/\/\/+/g, '/')
} }
/**
* Normalize file path separators to '/' on all platforms
* @param p - file path
* @returns file path with normalized separators
*/
const normalizePath = (p: string): string => {
return p.replace(/\\/g, '/')
}
/** /**
* Trims unnecessary trailing slash from file path * Trims unnecessary trailing slash from file path
* @param p - file path * @param p - file path
@ -365,7 +356,7 @@ export const getSubmodulePath = async ({
return stdout return stdout
.trim() .trim()
.split('\n') .split('\n')
.map((line: string) => normalizePath(line.trim().split(' ')[1])) .map((line: string) => normalizeSeparators(line.trim().split(' ')[1]))
} }
/** /**
@ -478,13 +469,15 @@ export const gitRenamedFiles = async ({
core.debug(`Renamed file: ${line}`) core.debug(`Renamed file: ${line}`)
const [, oldPath, newPath] = line.split('\t') const [, oldPath, newPath] = line.split('\t')
if (isSubmodule) { if (isSubmodule) {
return `${normalizePath( return `${normalizeSeparators(
path.join(parentDir, oldPath) path.join(parentDir, oldPath)
)}${oldNewSeparator}${normalizePath(path.join(parentDir, newPath))}` )}${oldNewSeparator}${normalizeSeparators(
} path.join(parentDir, newPath)
return `${normalizePath(oldPath)}${oldNewSeparator}${normalizePath(
newPath
)}` )}`
}
return `${normalizeSeparators(
oldPath
)}${oldNewSeparator}${normalizeSeparators(newPath)}`
}) })
} }
@ -564,11 +557,11 @@ export const getAllChangedFiles = async ({
for (const line of lines) { for (const line of lines) {
const [changeType, filePath, newPath = ''] = line.split('\t') const [changeType, filePath, newPath = ''] = line.split('\t')
const normalizedFilePath = isSubmodule const normalizedFilePath = isSubmodule
? normalizePath(path.join(parentDir, filePath)) ? normalizeSeparators(path.join(parentDir, filePath))
: normalizePath(filePath) : normalizeSeparators(filePath)
const normalizedNewPath = isSubmodule const normalizedNewPath = isSubmodule
? normalizePath(path.join(parentDir, newPath)) ? normalizeSeparators(path.join(parentDir, newPath))
: normalizePath(newPath) : normalizeSeparators(newPath)
if (changeType.startsWith('R')) { if (changeType.startsWith('R')) {
if (outputRenamedFilesAsDeletedAndAdded) { if (outputRenamedFilesAsDeletedAndAdded) {
@ -607,13 +600,14 @@ export const getFilteredChangedFiles = async ({
[ChangeTypeEnum.Unknown]: [] [ChangeTypeEnum.Unknown]: []
} }
const hasFilePatterns = filePatterns.length > 0 const hasFilePatterns = filePatterns.length > 0
const isWin = isWindows()
for (const changeType of Object.keys(allDiffFiles)) { for (const changeType of Object.keys(allDiffFiles)) {
const files = allDiffFiles[changeType as ChangeTypeEnum] const files = allDiffFiles[changeType as ChangeTypeEnum]
if (hasFilePatterns) { if (hasFilePatterns) {
changedFiles[changeType as ChangeTypeEnum] = mm(files, filePatterns, { changedFiles[changeType as ChangeTypeEnum] = mm(files, filePatterns, {
dot: true, dot: true,
windows: isWindows(), windows: isWin,
noext: true noext: true
}) })
} else { } else {
@ -873,7 +867,7 @@ export const getDirnameMaxDepth = ({
return '' return ''
} }
return normalizePath(output) return normalizeSeparators(output)
} }
export const jsonOutput = ({ export const jsonOutput = ({
@ -888,6 +882,16 @@ export const jsonOutput = ({
return shouldEscape ? result.replace(/"/g, '\\"') : result return shouldEscape ? result.replace(/"/g, '\\"') : result
} }
export const getDirNamesIncludeFilesPattern = ({
inputs
}: {
inputs: Inputs
}): string[] => {
return inputs.dirNamesIncludeFiles
.split(inputs.dirNamesIncludeFilesSeparator)
.filter(Boolean)
}
export const getFilePatterns = async ({ export const getFilePatterns = async ({
inputs, inputs,
workingDirectory workingDirectory
@ -897,7 +901,7 @@ export const getFilePatterns = async ({
}): Promise<string[]> => { }): Promise<string[]> => {
let filePatterns = inputs.files let filePatterns = inputs.files
.split(inputs.filesSeparator) .split(inputs.filesSeparator)
.filter(p => p !== '') .filter(Boolean)
.join('\n') .join('\n')
if (inputs.filesFromSourceFile !== '') { if (inputs.filesFromSourceFile !== '') {