fix: bug recovering deleted files for submodules (#1784)

Co-authored-by: GitHub Action <action@github.com>
Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
This commit is contained in:
Tonye Jack 2023-12-10 00:14:44 -07:00 committed by GitHub
parent 7611ff348d
commit 9454999946
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 126 additions and 17 deletions

View File

@ -24,7 +24,7 @@ on:
- auto_merge_enabled
- auto_merge_disabled
branches:
- main
- "**"
jobs:
build:
@ -824,6 +824,36 @@ jobs:
cat "deleted_files/test/test deleted.txt"
fi
- name: Run changed-files with recover_deleted_files for an expected git submodule file
id: changed-files-recover-deleted-files-within-submodule
uses: ./
with:
base_sha: "3be651e99d3d4eae395694f6c6f3b9d18457f6c8"
sha: "d90c240f2ad4ec04d8f0f48e5ac290ad96ebe850"
recover_deleted_files: true
fetch_depth: 60000
- name: Show output
run: |
echo "${{ toJSON(steps.changed-files-recover-deleted-files-within-submodule.outputs) }}"
shell:
bash
- name: Verify deleted files
if: steps.changed-files-recover-deleted-files-within-submodule.outputs.deleted_files != 'test/demo/.github/FUNDING.yml'
run: |
echo "Expected: (test/demo/.github/FUNDING.yml) got ${{ steps.changed-files-recover-deleted-files-within-submodule.outputs.deleted_files }}"
exit 1
- name: Verify that test/demo/.github/FUNDING.yml is restored
run: |
if [ ! -f "test/demo/.github/FUNDING.yml" ]; then
echo "Expected: (test/demo/.github/FUNDING.yml) to exist"
exit 1
else
cat "test/demo/.github/FUNDING.yml"
rm "test/demo/.github/FUNDING.yml"
fi
test-dir-names-deleted-files-include-only-deleted-dirs-single-file:
name: Test dir names deleted files include only deleted dirs single file
runs-on: ubuntu-latest

47
dist/index.js generated vendored
View File

@ -1725,7 +1725,9 @@ const getChangedFilesFromLocalGitHistory = ({ inputs, env, workingDirectory, fil
workingDirectory,
deletedFiles: allDiffFiles[changedFiles_1.ChangeTypeEnum.Deleted],
recoverPatterns,
sha: diffResult.previousSha
diffResult,
hasSubmodule,
submodulePaths
});
}
yield (0, changedFiles_1.processChangedFiles)({
@ -2832,7 +2834,7 @@ const getDeletedFileContents = ({ cwd, filePath, sha }) => __awaiter(void 0, voi
}
return stdout;
});
const recoverDeletedFiles = ({ inputs, workingDirectory, deletedFiles, recoverPatterns, sha }) => __awaiter(void 0, void 0, void 0, function* () {
const recoverDeletedFiles = ({ inputs, workingDirectory, deletedFiles, recoverPatterns, diffResult, hasSubmodule, submodulePaths }) => __awaiter(void 0, void 0, void 0, function* () {
let recoverableDeletedFiles = deletedFiles;
core.debug(`recoverable deleted files: ${recoverableDeletedFiles}`);
if (recoverPatterns.length > 0) {
@ -2848,15 +2850,46 @@ const recoverDeletedFiles = ({ inputs, workingDirectory, deletedFiles, recoverPa
if (inputs.recoverDeletedFilesToDestination) {
target = path.join(workingDirectory, inputs.recoverDeletedFilesToDestination, deletedFile);
}
const deletedFileContents = yield getDeletedFileContents({
cwd: workingDirectory,
filePath: deletedFile,
sha
});
let deletedFileContents;
const submodulePath = submodulePaths.find(p => deletedFile.startsWith(p));
if (hasSubmodule && submodulePath) {
const submoduleShaResult = yield (0, exports.gitSubmoduleDiffSHA)({
cwd: workingDirectory,
parentSha1: diffResult.previousSha,
parentSha2: diffResult.currentSha,
submodulePath,
diff: diffResult.diff
});
if (submoduleShaResult.previousSha) {
core.debug(`recovering deleted file "${deletedFile}" from submodule ${submodulePath} from ${submoduleShaResult.previousSha}`);
deletedFileContents = yield getDeletedFileContents({
cwd: path.join(workingDirectory, submodulePath),
// E.g. submodulePath = test/demo and deletedFile = test/demo/.github/README.md => filePath => .github/README.md
filePath: deletedFile.replace(submodulePath, '').substring(1),
sha: submoduleShaResult.previousSha
});
}
else {
core.warning(`Unable to recover deleted file "${deletedFile}" from submodule ${submodulePath} from ${submoduleShaResult.previousSha}`);
continue;
}
}
else {
core.debug(`recovering deleted file "${deletedFile}" from ${diffResult.previousSha}`);
deletedFileContents = yield getDeletedFileContents({
cwd: workingDirectory,
filePath: deletedFile,
sha: diffResult.previousSha
});
}
core.debug(`recovered deleted file "${deletedFile}"`);
if (!(yield (0, exports.exists)(path.dirname(target)))) {
core.debug(`creating directory "${path.dirname(target)}"`);
yield fs_1.promises.mkdir(path.dirname(target), { recursive: true });
}
core.debug(`writing file "${target}"`);
yield fs_1.promises.writeFile(target, deletedFileContents);
core.debug(`wrote file "${target}"`);
}
});
exports.recoverDeletedFiles = recoverDeletedFiles;

2
dist/index.js.map generated vendored

File diff suppressed because one or more lines are too long

View File

@ -144,7 +144,9 @@ const getChangedFilesFromLocalGitHistory = async ({
workingDirectory,
deletedFiles: allDiffFiles[ChangeTypeEnum.Deleted],
recoverPatterns,
sha: diffResult.previousSha
diffResult,
hasSubmodule,
submodulePaths
})
}

View File

@ -10,6 +10,7 @@ import * as path from 'path'
import {createInterface} from 'readline'
import {parseDocument} from 'yaml'
import {ChangedFiles, ChangeTypeEnum} from './changedFiles'
import {DiffResult} from './commitSha'
import {Inputs} from './inputs'
const MINIMUM_GIT_VERSION = '2.18.0'
@ -1395,13 +1396,17 @@ export const recoverDeletedFiles = async ({
workingDirectory,
deletedFiles,
recoverPatterns,
sha
diffResult,
hasSubmodule,
submodulePaths
}: {
inputs: Inputs
workingDirectory: string
deletedFiles: string[]
recoverPatterns: string[]
sha: string
diffResult: DiffResult
hasSubmodule: boolean
submodulePaths: string[]
}): Promise<void> => {
let recoverableDeletedFiles = deletedFiles
core.debug(`recoverable deleted files: ${recoverableDeletedFiles}`)
@ -1426,16 +1431,55 @@ export const recoverDeletedFiles = async ({
)
}
const deletedFileContents = await getDeletedFileContents({
cwd: workingDirectory,
filePath: deletedFile,
sha
})
let deletedFileContents: string
const submodulePath = submodulePaths.find(p => deletedFile.startsWith(p))
if (hasSubmodule && submodulePath) {
const submoduleShaResult = await gitSubmoduleDiffSHA({
cwd: workingDirectory,
parentSha1: diffResult.previousSha,
parentSha2: diffResult.currentSha,
submodulePath,
diff: diffResult.diff
})
if (submoduleShaResult.previousSha) {
core.debug(
`recovering deleted file "${deletedFile}" from submodule ${submodulePath} from ${submoduleShaResult.previousSha}`
)
deletedFileContents = await getDeletedFileContents({
cwd: path.join(workingDirectory, submodulePath),
// E.g. submodulePath = test/demo and deletedFile = test/demo/.github/README.md => filePath => .github/README.md
filePath: deletedFile.replace(submodulePath, '').substring(1),
sha: submoduleShaResult.previousSha
})
} else {
core.warning(
`Unable to recover deleted file "${deletedFile}" from submodule ${submodulePath} from ${submoduleShaResult.previousSha}`
)
continue
}
} else {
core.debug(
`recovering deleted file "${deletedFile}" from ${diffResult.previousSha}`
)
deletedFileContents = await getDeletedFileContents({
cwd: workingDirectory,
filePath: deletedFile,
sha: diffResult.previousSha
})
}
core.debug(`recovered deleted file "${deletedFile}"`)
if (!(await exists(path.dirname(target)))) {
core.debug(`creating directory "${path.dirname(target)}"`)
await fs.mkdir(path.dirname(target), {recursive: true})
}
core.debug(`writing file "${target}"`)
await fs.writeFile(target, deletedFileContents)
core.debug(`wrote file "${target}"`)
}
}