mirror of
https://github.com/actions/checkout.git
synced 2026-09-15 02:07:18 +08:00
Add a quiet input to suppress git output
Adds a `quiet` input (default: false) that passes `--quiet` to the git commands that fetch and check out the repository: `fetch`, `checkout`, `checkout --detach`, and `submodule update`. With `fetch-depth: 0` the refspec covers every branch and tag, so git prints a `From <url>` line plus one `* [new branch]` / `* [new tag]` line per ref. On a ref-heavy repository that summary is the bulk of the checkout log, and `show-progress: false` does not remove it -- that input only ever controlled `--progress`. `--quiet` and `--progress` drive different output and compose rather than conflict: `--progress` forces the transfer/update meter, while `--quiet` drops the ref summary and other informational messages. `checkout` keeps its `--progress` when quiet, so a slow checkout still reports progress. `git lfs fetch` has no `--quiet` flag, so LFS output is unchanged. Fixes #2409
This commit is contained in:
parent
f548e57e54
commit
81a936fd3c
@ -145,6 +145,11 @@ Please refer to the [release page](https://github.com/actions/checkout/releases/
|
||||
# Default: true
|
||||
show-progress: ''
|
||||
|
||||
# Whether to pass `--quiet` to the git commands that fetch and check out the
|
||||
# repository, suppressing their non-error output.
|
||||
# Default: false
|
||||
quiet: ''
|
||||
|
||||
# Whether to download Git-LFS files
|
||||
# Default: false
|
||||
lfs: ''
|
||||
|
||||
@ -1180,6 +1180,7 @@ async function setup(testName: string): Promise<void> {
|
||||
fetchDepth: 1,
|
||||
fetchTags: false,
|
||||
showProgress: true,
|
||||
quiet: false,
|
||||
lfs: false,
|
||||
submodules: false,
|
||||
nestedSubmodules: false,
|
||||
|
||||
@ -572,3 +572,209 @@ describe('git user-agent with orchestration ID', () => {
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Test quiet option', () => {
|
||||
beforeEach(async () => {
|
||||
mockFileExistsSync.mockReset()
|
||||
mockDirectoryExistsSync.mockReset()
|
||||
mockExec.mockImplementation((path: any, args: any, options: any) => {
|
||||
if (args.includes('version')) {
|
||||
options.listeners.stdout(Buffer.from('2.18'))
|
||||
}
|
||||
|
||||
return 0
|
||||
})
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
async function createManager(quiet?: boolean): Promise<IGitCommandManager> {
|
||||
const workingDirectory = 'test'
|
||||
const lfs = false
|
||||
const doSparseCheckout = false
|
||||
return await commandManager.createCommandManager(
|
||||
workingDirectory,
|
||||
lfs,
|
||||
doSparseCheckout,
|
||||
quiet
|
||||
)
|
||||
}
|
||||
|
||||
it('should pass --quiet to fetch when quiet is true', async () => {
|
||||
git = await createManager(true)
|
||||
|
||||
await git.fetch(['refspec1'], {fetchDepth: 0})
|
||||
|
||||
expect(mockExec).toHaveBeenCalledWith(
|
||||
expect.any(String),
|
||||
[
|
||||
'-c',
|
||||
'protocol.version=2',
|
||||
'fetch',
|
||||
'--no-tags',
|
||||
'--prune',
|
||||
'--no-recurse-submodules',
|
||||
'--quiet',
|
||||
'origin',
|
||||
'refspec1'
|
||||
],
|
||||
expect.any(Object)
|
||||
)
|
||||
})
|
||||
|
||||
it('should pass both --quiet and --progress to fetch when both are requested', async () => {
|
||||
// The two flags drive different output and compose: --progress forces the
|
||||
// transfer meter, --quiet drops the per-ref summary.
|
||||
git = await createManager(true)
|
||||
|
||||
await git.fetch(['refspec1'], {fetchDepth: 0, showProgress: true})
|
||||
|
||||
const args = mockExec.mock.calls.at(-1)?.[1] as string[]
|
||||
expect(args).toContain('--quiet')
|
||||
expect(args).toContain('--progress')
|
||||
})
|
||||
|
||||
it('should not pass --quiet to fetch when quiet is false', async () => {
|
||||
git = await createManager(false)
|
||||
|
||||
await git.fetch(['refspec1'], {fetchDepth: 0})
|
||||
|
||||
expect(mockExec).toHaveBeenCalledWith(
|
||||
expect.any(String),
|
||||
[
|
||||
'-c',
|
||||
'protocol.version=2',
|
||||
'fetch',
|
||||
'--no-tags',
|
||||
'--prune',
|
||||
'--no-recurse-submodules',
|
||||
'origin',
|
||||
'refspec1'
|
||||
],
|
||||
expect.any(Object)
|
||||
)
|
||||
})
|
||||
|
||||
it('should default to not quiet when the option is omitted', async () => {
|
||||
git = await createManager()
|
||||
|
||||
await git.fetch(['refspec1'], {fetchDepth: 0, showProgress: true})
|
||||
|
||||
const args = mockExec.mock.calls.at(-1)?.[1] as string[]
|
||||
expect(args).toContain('--progress')
|
||||
expect(args).not.toContain('--quiet')
|
||||
})
|
||||
|
||||
it('should checkout with --quiet alongside --progress when quiet is true', async () => {
|
||||
git = await createManager(true)
|
||||
|
||||
await git.checkout('refs/heads/main', '')
|
||||
|
||||
expect(mockExec).toHaveBeenCalledWith(
|
||||
expect.any(String),
|
||||
['checkout', '--quiet', '--progress', '--force', 'refs/heads/main'],
|
||||
expect.any(Object)
|
||||
)
|
||||
})
|
||||
|
||||
it('should checkout a start point with --quiet when quiet is true', async () => {
|
||||
git = await createManager(true)
|
||||
|
||||
await git.checkout('refs/heads/main', 'refs/remotes/origin/main')
|
||||
|
||||
expect(mockExec).toHaveBeenCalledWith(
|
||||
expect.any(String),
|
||||
[
|
||||
'checkout',
|
||||
'--quiet',
|
||||
'--progress',
|
||||
'--force',
|
||||
'-B',
|
||||
'refs/heads/main',
|
||||
'refs/remotes/origin/main'
|
||||
],
|
||||
expect.any(Object)
|
||||
)
|
||||
})
|
||||
|
||||
it('should checkout with --progress when quiet is false', async () => {
|
||||
git = await createManager(false)
|
||||
|
||||
await git.checkout('refs/heads/main', '')
|
||||
|
||||
expect(mockExec).toHaveBeenCalledWith(
|
||||
expect.any(String),
|
||||
['checkout', '--progress', '--force', 'refs/heads/main'],
|
||||
expect.any(Object)
|
||||
)
|
||||
})
|
||||
|
||||
it('should pass --quiet to checkout --detach when quiet is true', async () => {
|
||||
git = await createManager(true)
|
||||
|
||||
await git.checkoutDetach()
|
||||
|
||||
expect(mockExec).toHaveBeenCalledWith(
|
||||
expect.any(String),
|
||||
['checkout', '--detach', '--quiet'],
|
||||
expect.any(Object)
|
||||
)
|
||||
})
|
||||
|
||||
it('should not pass --quiet to checkout --detach when quiet is false', async () => {
|
||||
git = await createManager(false)
|
||||
|
||||
await git.checkoutDetach()
|
||||
|
||||
expect(mockExec).toHaveBeenCalledWith(
|
||||
expect.any(String),
|
||||
['checkout', '--detach'],
|
||||
expect.any(Object)
|
||||
)
|
||||
})
|
||||
|
||||
it('should pass --quiet to submodule update when quiet is true', async () => {
|
||||
git = await createManager(true)
|
||||
|
||||
await git.submoduleUpdate(1, true)
|
||||
|
||||
expect(mockExec).toHaveBeenCalledWith(
|
||||
expect.any(String),
|
||||
[
|
||||
'-c',
|
||||
'protocol.version=2',
|
||||
'submodule',
|
||||
'update',
|
||||
'--init',
|
||||
'--force',
|
||||
'--quiet',
|
||||
'--depth=1',
|
||||
'--recursive'
|
||||
],
|
||||
expect.any(Object)
|
||||
)
|
||||
})
|
||||
|
||||
it('should not pass --quiet to submodule update when quiet is false', async () => {
|
||||
git = await createManager(false)
|
||||
|
||||
await git.submoduleUpdate(1, true)
|
||||
|
||||
expect(mockExec).toHaveBeenCalledWith(
|
||||
expect.any(String),
|
||||
[
|
||||
'-c',
|
||||
'protocol.version=2',
|
||||
'submodule',
|
||||
'update',
|
||||
'--init',
|
||||
'--force',
|
||||
'--depth=1',
|
||||
'--recursive'
|
||||
],
|
||||
expect.any(Object)
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
@ -119,6 +119,7 @@ describe('input-helper tests', () => {
|
||||
expect(settings.fetchDepth).toBe(1)
|
||||
expect(settings.fetchTags).toBe(false)
|
||||
expect(settings.showProgress).toBe(true)
|
||||
expect(settings.quiet).toBe(false)
|
||||
expect(settings.lfs).toBe(false)
|
||||
expect(settings.ref).toBe('refs/heads/some-ref')
|
||||
expect(settings.repositoryName).toBe('some-repo')
|
||||
@ -128,6 +129,12 @@ describe('input-helper tests', () => {
|
||||
expect(settings.allowUnsafePrCheckout).toBe(false)
|
||||
})
|
||||
|
||||
it('sets quiet', async () => {
|
||||
inputs.quiet = 'true'
|
||||
const settings: IGitSourceSettings = await inputHelper.getInputs()
|
||||
expect(settings.quiet).toBe(true)
|
||||
})
|
||||
|
||||
it('qualifies ref', async () => {
|
||||
let originalRef = mockGithubContext.ref
|
||||
try {
|
||||
|
||||
@ -80,6 +80,11 @@ inputs:
|
||||
show-progress:
|
||||
description: 'Whether to show progress status output when fetching.'
|
||||
default: true
|
||||
quiet:
|
||||
description: >
|
||||
Whether to pass `--quiet` to the git commands that fetch and check out the
|
||||
repository, suppressing their non-error output.
|
||||
default: false
|
||||
lfs:
|
||||
description: 'Whether to download Git-LFS files'
|
||||
default: false
|
||||
|
||||
37
dist/index.js
vendored
37
dist/index.js
vendored
@ -35597,8 +35597,8 @@ class GitVersion {
|
||||
// sparse-checkout not [well-]supported before 2.28 (see https://github.com/actions/checkout/issues/1386)
|
||||
const MinimumGitVersion = new GitVersion('2.18');
|
||||
const MinimumGitSparseCheckoutVersion = new GitVersion('2.28');
|
||||
async function createCommandManager(workingDirectory, lfs, doSparseCheckout) {
|
||||
return await GitCommandManager.createCommandManager(workingDirectory, lfs, doSparseCheckout);
|
||||
async function createCommandManager(workingDirectory, lfs, doSparseCheckout, quiet = false) {
|
||||
return await GitCommandManager.createCommandManager(workingDirectory, lfs, doSparseCheckout, quiet);
|
||||
}
|
||||
class GitCommandManager {
|
||||
gitEnv = {
|
||||
@ -35608,6 +35608,7 @@ class GitCommandManager {
|
||||
gitPath = '';
|
||||
lfs = false;
|
||||
doSparseCheckout = false;
|
||||
quiet = false;
|
||||
workingDirectory = '';
|
||||
gitVersion = new GitVersion();
|
||||
// Private constructor; use createCommandManager()
|
||||
@ -35702,7 +35703,14 @@ class GitCommandManager {
|
||||
await external_fs_namespaceObject.promises.appendFile(sparseCheckoutPath, `\n${sparseCheckout.join('\n')}\n`);
|
||||
}
|
||||
async checkout(ref, startPoint) {
|
||||
const args = ['checkout', '--progress', '--force'];
|
||||
// --quiet and --progress drive different output and compose: --progress
|
||||
// controls the "Updating files" meter, --quiet silences the rest. Keeping
|
||||
// both means a slow checkout still reports progress while going quiet.
|
||||
const args = ['checkout'];
|
||||
if (this.quiet) {
|
||||
args.push('--quiet');
|
||||
}
|
||||
args.push('--progress', '--force');
|
||||
if (startPoint) {
|
||||
args.push('-B', ref, startPoint);
|
||||
}
|
||||
@ -35713,6 +35721,9 @@ class GitCommandManager {
|
||||
}
|
||||
async checkoutDetach() {
|
||||
const args = ['checkout', '--detach'];
|
||||
if (this.quiet) {
|
||||
args.push('--quiet');
|
||||
}
|
||||
await this.execGit(args);
|
||||
}
|
||||
async config(configKey, configValue, globalConfig, add, configFile) {
|
||||
@ -35746,6 +35757,11 @@ class GitCommandManager {
|
||||
// Tags are fetched explicitly via refspec when needed
|
||||
args.push('--no-tags');
|
||||
args.push('--prune', '--no-recurse-submodules');
|
||||
// Independent switches: --quiet drops the ref summary, --progress forces
|
||||
// the transfer meter. Either, both, or neither is meaningful.
|
||||
if (this.quiet) {
|
||||
args.push('--quiet');
|
||||
}
|
||||
if (options.showProgress) {
|
||||
args.push('--progress');
|
||||
}
|
||||
@ -35875,6 +35891,9 @@ class GitCommandManager {
|
||||
async submoduleUpdate(fetchDepth, recursive) {
|
||||
const args = ['-c', 'protocol.version=2'];
|
||||
args.push('submodule', 'update', '--init', '--force');
|
||||
if (this.quiet) {
|
||||
args.push('--quiet');
|
||||
}
|
||||
if (fetchDepth > 0) {
|
||||
args.push(`--depth=${fetchDepth}`);
|
||||
}
|
||||
@ -35975,9 +35994,9 @@ class GitCommandManager {
|
||||
async version() {
|
||||
return this.gitVersion;
|
||||
}
|
||||
static async createCommandManager(workingDirectory, lfs, doSparseCheckout) {
|
||||
static async createCommandManager(workingDirectory, lfs, doSparseCheckout, quiet = false) {
|
||||
const result = new GitCommandManager();
|
||||
await result.initializeCommandManager(workingDirectory, lfs, doSparseCheckout);
|
||||
await result.initializeCommandManager(workingDirectory, lfs, doSparseCheckout, quiet);
|
||||
return result;
|
||||
}
|
||||
async execGit(args, allowAllExitCodes = false, silent = false, customListeners = {}) {
|
||||
@ -36010,8 +36029,9 @@ class GitCommandManager {
|
||||
core_debug(result.stdout);
|
||||
return result;
|
||||
}
|
||||
async initializeCommandManager(workingDirectory, lfs, doSparseCheckout) {
|
||||
async initializeCommandManager(workingDirectory, lfs, doSparseCheckout, quiet) {
|
||||
this.workingDirectory = workingDirectory;
|
||||
this.quiet = quiet;
|
||||
// Git-lfs will try to pull down assets if any of the local/user/system setting exist.
|
||||
// If the user didn't enable `LFS` in their pipeline definition, disable LFS fetch/checkout.
|
||||
this.lfs = lfs;
|
||||
@ -41954,7 +41974,7 @@ async function cleanup(repositoryPath) {
|
||||
async function getGitCommandManager(settings) {
|
||||
info(`Working directory is '${settings.repositoryPath}'`);
|
||||
try {
|
||||
return await createCommandManager(settings.repositoryPath, settings.lfs, settings.sparseCheckout != null);
|
||||
return await createCommandManager(settings.repositoryPath, settings.lfs, settings.sparseCheckout != null, settings.quiet);
|
||||
}
|
||||
catch (err) {
|
||||
// Git is required for LFS
|
||||
@ -42166,6 +42186,9 @@ async function getInputs() {
|
||||
result.showProgress =
|
||||
(getInput('show-progress') || 'true').toUpperCase() === 'TRUE';
|
||||
core_debug(`show progress = ${result.showProgress}`);
|
||||
// Quiet
|
||||
result.quiet = (getInput('quiet') || 'false').toUpperCase() === 'TRUE';
|
||||
core_debug(`quiet = ${result.quiet}`);
|
||||
// LFS
|
||||
result.lfs = (getInput('lfs') || 'false').toUpperCase() === 'TRUE';
|
||||
core_debug(`lfs = ${result.lfs}`);
|
||||
|
||||
@ -85,12 +85,14 @@ export interface IGitCommandManager {
|
||||
export async function createCommandManager(
|
||||
workingDirectory: string,
|
||||
lfs: boolean,
|
||||
doSparseCheckout: boolean
|
||||
doSparseCheckout: boolean,
|
||||
quiet = false
|
||||
): Promise<IGitCommandManager> {
|
||||
return await GitCommandManager.createCommandManager(
|
||||
workingDirectory,
|
||||
lfs,
|
||||
doSparseCheckout
|
||||
doSparseCheckout,
|
||||
quiet
|
||||
)
|
||||
}
|
||||
|
||||
@ -102,6 +104,7 @@ class GitCommandManager {
|
||||
private gitPath = ''
|
||||
private lfs = false
|
||||
private doSparseCheckout = false
|
||||
private quiet = false
|
||||
private workingDirectory = ''
|
||||
private gitVersion: GitVersion = new GitVersion()
|
||||
|
||||
@ -221,7 +224,14 @@ class GitCommandManager {
|
||||
}
|
||||
|
||||
async checkout(ref: string, startPoint: string): Promise<void> {
|
||||
const args = ['checkout', '--progress', '--force']
|
||||
// --quiet and --progress drive different output and compose: --progress
|
||||
// controls the "Updating files" meter, --quiet silences the rest. Keeping
|
||||
// both means a slow checkout still reports progress while going quiet.
|
||||
const args = ['checkout']
|
||||
if (this.quiet) {
|
||||
args.push('--quiet')
|
||||
}
|
||||
args.push('--progress', '--force')
|
||||
if (startPoint) {
|
||||
args.push('-B', ref, startPoint)
|
||||
} else {
|
||||
@ -233,6 +243,10 @@ class GitCommandManager {
|
||||
|
||||
async checkoutDetach(): Promise<void> {
|
||||
const args = ['checkout', '--detach']
|
||||
if (this.quiet) {
|
||||
args.push('--quiet')
|
||||
}
|
||||
|
||||
await this.execGit(args)
|
||||
}
|
||||
|
||||
@ -288,6 +302,12 @@ class GitCommandManager {
|
||||
args.push('--no-tags')
|
||||
|
||||
args.push('--prune', '--no-recurse-submodules')
|
||||
// Independent switches: --quiet drops the ref summary, --progress forces
|
||||
// the transfer meter. Either, both, or neither is meaningful.
|
||||
if (this.quiet) {
|
||||
args.push('--quiet')
|
||||
}
|
||||
|
||||
if (options.showProgress) {
|
||||
args.push('--progress')
|
||||
}
|
||||
@ -455,6 +475,10 @@ class GitCommandManager {
|
||||
async submoduleUpdate(fetchDepth: number, recursive: boolean): Promise<void> {
|
||||
const args = ['-c', 'protocol.version=2']
|
||||
args.push('submodule', 'update', '--init', '--force')
|
||||
if (this.quiet) {
|
||||
args.push('--quiet')
|
||||
}
|
||||
|
||||
if (fetchDepth > 0) {
|
||||
args.push(`--depth=${fetchDepth}`)
|
||||
}
|
||||
@ -604,13 +628,15 @@ class GitCommandManager {
|
||||
static async createCommandManager(
|
||||
workingDirectory: string,
|
||||
lfs: boolean,
|
||||
doSparseCheckout: boolean
|
||||
doSparseCheckout: boolean,
|
||||
quiet = false
|
||||
): Promise<GitCommandManager> {
|
||||
const result = new GitCommandManager()
|
||||
await result.initializeCommandManager(
|
||||
workingDirectory,
|
||||
lfs,
|
||||
doSparseCheckout
|
||||
doSparseCheckout,
|
||||
quiet
|
||||
)
|
||||
return result
|
||||
}
|
||||
@ -662,9 +688,11 @@ class GitCommandManager {
|
||||
private async initializeCommandManager(
|
||||
workingDirectory: string,
|
||||
lfs: boolean,
|
||||
doSparseCheckout: boolean
|
||||
doSparseCheckout: boolean,
|
||||
quiet: boolean
|
||||
): Promise<void> {
|
||||
this.workingDirectory = workingDirectory
|
||||
this.quiet = quiet
|
||||
|
||||
// Git-lfs will try to pull down assets if any of the local/user/system setting exist.
|
||||
// If the user didn't enable `LFS` in their pipeline definition, disable LFS fetch/checkout.
|
||||
|
||||
@ -378,7 +378,8 @@ async function getGitCommandManager(
|
||||
return await gitCommandManager.createCommandManager(
|
||||
settings.repositoryPath,
|
||||
settings.lfs,
|
||||
settings.sparseCheckout != null
|
||||
settings.sparseCheckout != null,
|
||||
settings.quiet
|
||||
)
|
||||
} catch (err) {
|
||||
// Git is required for LFS
|
||||
|
||||
@ -59,6 +59,11 @@ export interface IGitSourceSettings {
|
||||
*/
|
||||
showProgress: boolean
|
||||
|
||||
/**
|
||||
* Indicates whether to use the --quiet option when fetching and checking out
|
||||
*/
|
||||
quiet: boolean
|
||||
|
||||
/**
|
||||
* Indicates whether to fetch LFS objects
|
||||
*/
|
||||
|
||||
@ -136,6 +136,10 @@ export async function getInputs(): Promise<IGitSourceSettings> {
|
||||
(core.getInput('show-progress') || 'true').toUpperCase() === 'TRUE'
|
||||
core.debug(`show progress = ${result.showProgress}`)
|
||||
|
||||
// Quiet
|
||||
result.quiet = (core.getInput('quiet') || 'false').toUpperCase() === 'TRUE'
|
||||
core.debug(`quiet = ${result.quiet}`)
|
||||
|
||||
// LFS
|
||||
result.lfs = (core.getInput('lfs') || 'false').toUpperCase() === 'TRUE'
|
||||
core.debug(`lfs = ${result.lfs}`)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user