From ed2311a594464e30b7189963bdc844e2ab800112 Mon Sep 17 00:00:00 2001 From: Gregory Bonaert Date: Thu, 10 Apr 2025 10:13:16 +0200 Subject: [PATCH] Add `exclude_from_clean` option --- README.md | 6 ++++++ action.yml | 2 ++ dist/index.js | 19 ++++++++++++++----- package-lock.json | 4 ++-- package.json | 2 +- src/git-command-manager.ts | 11 ++++++++--- src/git-directory-helper.ts | 3 ++- src/git-source-provider.ts | 1 + src/git-source-settings.ts | 5 +++++ src/input-helper.ts | 4 ++++ 10 files changed, 45 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 64dc025..4f46f93 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ [![Build and Test](https://github.com/actions/checkout/actions/workflows/test.yml/badge.svg)](https://github.com/actions/checkout/actions/workflows/test.yml) +Changes compared to https://github.com/actions/checkout: +- Can exclude path when cleaning repository (see `exclude_from_clean` argument) + # Checkout V4 This action checks-out your repository under `$GITHUB_WORKSPACE`, so your workflow can access it. @@ -78,6 +81,9 @@ Please refer to the [release page](https://github.com/actions/checkout/releases/ # Default: true clean: '' + # The path to exclude from cleaning + exclude_from_clean: '' + # Partially clone against a given filter. Overrides sparse-checkout if set. # Default: null filter: '' diff --git a/action.yml b/action.yml index 6842eb8..5ec9e61 100644 --- a/action.yml +++ b/action.yml @@ -57,6 +57,8 @@ inputs: clean: description: 'Whether to execute `git clean -ffdx && git reset --hard HEAD` before fetching' default: true + exclude_from_clean: + description: 'The path to exclude from cleaning' filter: description: > Partially clone against a given filter. diff --git a/dist/index.js b/dist/index.js index b0db713..c1ce62e 100644 --- a/dist/index.js +++ b/dist/index.js @@ -819,9 +819,15 @@ class GitCommandManager { return !!output.stdout.trim(); }); } - tryClean() { + tryClean(exclude_from_clean) { return __awaiter(this, void 0, void 0, function* () { - const output = yield this.execGit(['clean', '-ffdx'], true); + let output; + if (exclude_from_clean) { + output = yield this.execGit(['clean', '-ffdx', '-e', exclude_from_clean], true); + } + else { + output = yield this.execGit(['clean', '-ffdx'], true); + } return output.exitCode === 0; }); } @@ -1025,7 +1031,7 @@ const fs = __importStar(__nccwpck_require__(7147)); const fsHelper = __importStar(__nccwpck_require__(7219)); const io = __importStar(__nccwpck_require__(7436)); const path = __importStar(__nccwpck_require__(1017)); -function prepareExistingDirectory(git, repositoryPath, repositoryUrl, clean, ref) { +function prepareExistingDirectory(git, repositoryPath, repositoryUrl, clean, exclude_from_clean, ref) { return __awaiter(this, void 0, void 0, function* () { var _a; assert.ok(repositoryPath, 'Expected repositoryPath to be defined'); @@ -1094,7 +1100,7 @@ function prepareExistingDirectory(git, repositoryPath, repositoryUrl, clean, ref // Clean if (clean) { core.startGroup('Cleaning the repository'); - if (!(yield git.tryClean())) { + if (!(yield git.tryClean(exclude_from_clean))) { core.debug(`The clean command failed. This might be caused by: 1) path too long, 2) permission issue, or 3) file in use. For further investigation, manually run 'git clean -ffdx' on the directory '${repositoryPath}'.`); remove = true; } @@ -1216,7 +1222,7 @@ function getSource(settings) { } // Prepare existing directory, otherwise recreate if (isExisting) { - yield gitDirectoryHelper.prepareExistingDirectory(git, settings.repositoryPath, repositoryUrl, settings.clean, settings.ref); + yield gitDirectoryHelper.prepareExistingDirectory(git, settings.repositoryPath, repositoryUrl, settings.clean, settings.exclude_from_clean, settings.ref); } if (!git) { // Downloading using REST API @@ -1766,6 +1772,9 @@ function getInputs() { // Clean result.clean = (core.getInput('clean') || 'true').toUpperCase() === 'TRUE'; core.debug(`clean = ${result.clean}`); + // Exclude from clean + result.exclude_from_clean = core.getInput('exclude_from_clean'); + core.debug(`exclude_from_clean = ${result.exclude_from_clean}`); // Filter const filter = core.getInput('filter'); if (filter) { diff --git a/package-lock.json b/package-lock.json index 25753a2..084b010 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "checkout", - "version": "4.2.2", + "version": "4.2.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "checkout", - "version": "4.2.2", + "version": "4.2.3", "license": "MIT", "dependencies": { "@actions/core": "^1.10.1", diff --git a/package.json b/package.json index 5661d70..90743a6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "checkout", - "version": "4.2.2", + "version": "4.2.3", "description": "checkout action", "main": "lib/main.js", "scripts": { diff --git a/src/git-command-manager.ts b/src/git-command-manager.ts index 8e42a38..3881735 100644 --- a/src/git-command-manager.ts +++ b/src/git-command-manager.ts @@ -57,7 +57,7 @@ export interface IGitCommandManager { submoduleUpdate(fetchDepth: number, recursive: boolean): Promise submoduleStatus(): Promise tagExists(pattern: string): Promise - tryClean(): Promise + tryClean(exclude_from_clean: string): Promise tryConfigUnset(configKey: string, globalConfig?: boolean): Promise tryDisableAutomaticGarbageCollection(): Promise tryGetFetchUrl(): Promise @@ -434,8 +434,13 @@ class GitCommandManager { return !!output.stdout.trim() } - async tryClean(): Promise { - const output = await this.execGit(['clean', '-ffdx'], true) + async tryClean(exclude_from_clean: string): Promise { + let output + if (exclude_from_clean) { + output = await this.execGit(['clean', '-ffdx', '-e', exclude_from_clean], true) + } else { + output = await this.execGit(['clean', '-ffdx'], true) + } return output.exitCode === 0 } diff --git a/src/git-directory-helper.ts b/src/git-directory-helper.ts index 9a0085f..908efc2 100644 --- a/src/git-directory-helper.ts +++ b/src/git-directory-helper.ts @@ -11,6 +11,7 @@ export async function prepareExistingDirectory( repositoryPath: string, repositoryUrl: string, clean: boolean, + exclude_from_clean: string, ref: string ): Promise { assert.ok(repositoryPath, 'Expected repositoryPath to be defined') @@ -90,7 +91,7 @@ export async function prepareExistingDirectory( // Clean if (clean) { core.startGroup('Cleaning the repository') - if (!(await git.tryClean())) { + if (!(await git.tryClean(exclude_from_clean))) { core.debug( `The clean command failed. This might be caused by: 1) path too long, 2) permission issue, or 3) file in use. For further investigation, manually run 'git clean -ffdx' on the directory '${repositoryPath}'.` ) diff --git a/src/git-source-provider.ts b/src/git-source-provider.ts index 2d35138..4c8f338 100644 --- a/src/git-source-provider.ts +++ b/src/git-source-provider.ts @@ -70,6 +70,7 @@ export async function getSource(settings: IGitSourceSettings): Promise { settings.repositoryPath, repositoryUrl, settings.clean, + settings.exclude_from_clean, settings.ref ) } diff --git a/src/git-source-settings.ts b/src/git-source-settings.ts index 4e41ac3..fc78956 100644 --- a/src/git-source-settings.ts +++ b/src/git-source-settings.ts @@ -29,6 +29,11 @@ export interface IGitSourceSettings { */ clean: boolean + /** + * Indicates path to exclude when cleaning + */ + exclude_from_clean: string + /** * The filter determining which objects to include */ diff --git a/src/input-helper.ts b/src/input-helper.ts index 059232f..ea057e3 100644 --- a/src/input-helper.ts +++ b/src/input-helper.ts @@ -82,6 +82,10 @@ export async function getInputs(): Promise { result.clean = (core.getInput('clean') || 'true').toUpperCase() === 'TRUE' core.debug(`clean = ${result.clean}`) + // Exclude from clean + result.exclude_from_clean = core.getInput('exclude_from_clean') + core.debug(`exclude_from_clean = ${result.exclude_from_clean}`) + // Filter const filter = core.getInput('filter') if (filter) {