This commit is contained in:
Jellyfrog 2026-10-02 01:46:40 +02:00 committed by GitHub
commit 39b286b437
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 110 additions and 22 deletions

View File

@ -120,7 +120,8 @@ Please refer to the [release page](https://github.com/actions/checkout/releases/
# Default: true # Default: true
clean: '' clean: ''
# Partially clone against a given filter. Overrides sparse-checkout if set. # Partially clone against a given filter. If sparse-checkout is set and filter is
# not, the filter is `blob:none`. Set to `none` to fetch without a filter.
# Default: null # Default: null
filter: '' filter: ''

View File

@ -401,6 +401,41 @@ describe('Test fetchDepth and fetchTags options', () => {
expect.any(Object) expect.any(Object)
) )
}) })
it('should not pass --filter when filter is not set', async () => {
// exec.exec is already mockExec
const workingDirectory = 'test'
const lfs = false
const doSparseCheckout = false
git = await commandManager.createCommandManager(
workingDirectory,
lfs,
doSparseCheckout
)
const refSpec = ['refspec1']
const options = {
fetchDepth: 1
}
await git.fetch(refSpec, options)
expect(mockExec).toHaveBeenCalledWith(
expect.any(String),
[
'-c',
'protocol.version=2',
'fetch',
'--no-tags',
'--prune',
'--no-recurse-submodules',
'--depth=1',
'origin',
'refspec1'
],
expect.any(Object)
)
})
}) })
describe('repository initialization object format', () => { describe('repository initialization object format', () => {

View File

@ -215,6 +215,47 @@ describe('input-helper tests', () => {
expect(settings.commit).toBe('1111111111222222222233333333334444444444') expect(settings.commit).toBe('1111111111222222222233333333334444444444')
}) })
describe('filter', () => {
it('is not set without sparse checkout', async () => {
const settings: IGitSourceSettings = await inputHelper.getInputs()
expect(settings.filter).toBe(undefined)
})
it('defaults to blob:none with sparse checkout', async () => {
inputs['sparse-checkout'] = 'src\ndocs'
const settings: IGitSourceSettings = await inputHelper.getInputs()
expect(settings.sparseCheckout).toEqual(['src', 'docs'])
expect(settings.filter).toBe('blob:none')
})
it('uses the given filter with sparse checkout', async () => {
inputs['sparse-checkout'] = 'src'
inputs.filter = 'tree:0'
const settings: IGitSourceSettings = await inputHelper.getInputs()
expect(settings.filter).toBe('tree:0')
})
it('uses the given filter without sparse checkout', async () => {
inputs.filter = 'blob:limit=1m'
const settings: IGitSourceSettings = await inputHelper.getInputs()
expect(settings.filter).toBe('blob:limit=1m')
})
it('is not set when none with sparse checkout', async () => {
inputs['sparse-checkout'] = 'src'
inputs.filter = 'none'
const settings: IGitSourceSettings = await inputHelper.getInputs()
expect(settings.sparseCheckout).toEqual(['src'])
expect(settings.filter).toBe(undefined)
})
it('is not set when none without sparse checkout', async () => {
inputs.filter = 'None'
const settings: IGitSourceSettings = await inputHelper.getInputs()
expect(settings.filter).toBe(undefined)
})
})
it('sets workflow organization ID', async () => { it('sets workflow organization ID', async () => {
const settings: IGitSourceSettings = await inputHelper.getInputs() const settings: IGitSourceSettings = await inputHelper.getInputs()
expect(settings.workflowOrganizationId).toBe(123456) expect(settings.workflowOrganizationId).toBe(123456)

View File

@ -60,7 +60,8 @@ inputs:
filter: filter:
description: > description: >
Partially clone against a given filter. Partially clone against a given filter.
Overrides sparse-checkout if set. If sparse-checkout is set and filter is not, the filter is `blob:none`.
Set to `none` to fetch without a filter.
default: null default: null
sparse-checkout: sparse-checkout:
description: > description: >

23
dist/index.js vendored
View File

@ -41810,9 +41810,6 @@ async function getSource(settings) {
if (settings.filter) { if (settings.filter) {
fetchOptions.filter = settings.filter; fetchOptions.filter = settings.filter;
} }
else if (settings.sparseCheckout) {
fetchOptions.filter = 'blob:none';
}
if (settings.fetchDepth <= 0) { if (settings.fetchDepth <= 0) {
// Fetch all branches and tags // Fetch all branches and tags
let refSpec = getRefSpecForAllHistory(settings.ref, settings.commit); let refSpec = getRefSpecForAllHistory(settings.ref, settings.commit);
@ -42137,18 +42134,26 @@ async function getInputs() {
// Clean // Clean
result.clean = (getInput('clean') || 'true').toUpperCase() === 'TRUE'; result.clean = (getInput('clean') || 'true').toUpperCase() === 'TRUE';
core_debug(`clean = ${result.clean}`); core_debug(`clean = ${result.clean}`);
// Filter
const filter = getInput('filter');
if (filter) {
result.filter = filter;
}
core_debug(`filter = ${result.filter}`);
// Sparse checkout // Sparse checkout
const sparseCheckout = getMultilineInput('sparse-checkout'); const sparseCheckout = getMultilineInput('sparse-checkout');
if (sparseCheckout.length) { if (sparseCheckout.length) {
result.sparseCheckout = sparseCheckout; result.sparseCheckout = sparseCheckout;
core_debug(`sparse checkout = ${result.sparseCheckout}`); core_debug(`sparse checkout = ${result.sparseCheckout}`);
} }
// Filter
// Sparse checkout implies 'blob:none' unless a filter is given.
// 'none' disables the filter.
const filter = getInput('filter');
if (filter.toUpperCase() === 'NONE') {
result.filter = undefined;
}
else if (filter) {
result.filter = filter;
}
else if (result.sparseCheckout) {
result.filter = 'blob:none';
}
core_debug(`filter = ${result.filter}`);
result.sparseCheckoutConeMode = result.sparseCheckoutConeMode =
(getInput('sparse-checkout-cone-mode') || 'true').toUpperCase() === (getInput('sparse-checkout-cone-mode') || 'true').toUpperCase() ===
'TRUE'; 'TRUE';

View File

@ -181,8 +181,6 @@ export async function getSource(settings: IGitSourceSettings): Promise<void> {
if (settings.filter) { if (settings.filter) {
fetchOptions.filter = settings.filter fetchOptions.filter = settings.filter
} else if (settings.sparseCheckout) {
fetchOptions.filter = 'blob:none'
} }
if (settings.fetchDepth <= 0) { if (settings.fetchDepth <= 0) {

View File

@ -30,7 +30,8 @@ export interface IGitSourceSettings {
clean: boolean clean: boolean
/** /**
* The filter determining which objects to include * The filter determining which objects to include.
* Defaults to 'blob:none' when sparse checkout is set, unless the input is 'none'.
*/ */
filter: string | undefined filter: string | undefined

View File

@ -100,14 +100,6 @@ export async function getInputs(): Promise<IGitSourceSettings> {
result.clean = (core.getInput('clean') || 'true').toUpperCase() === 'TRUE' result.clean = (core.getInput('clean') || 'true').toUpperCase() === 'TRUE'
core.debug(`clean = ${result.clean}`) core.debug(`clean = ${result.clean}`)
// Filter
const filter = core.getInput('filter')
if (filter) {
result.filter = filter
}
core.debug(`filter = ${result.filter}`)
// Sparse checkout // Sparse checkout
const sparseCheckout = core.getMultilineInput('sparse-checkout') const sparseCheckout = core.getMultilineInput('sparse-checkout')
if (sparseCheckout.length) { if (sparseCheckout.length) {
@ -115,6 +107,20 @@ export async function getInputs(): Promise<IGitSourceSettings> {
core.debug(`sparse checkout = ${result.sparseCheckout}`) core.debug(`sparse checkout = ${result.sparseCheckout}`)
} }
// Filter
// Sparse checkout implies 'blob:none' unless a filter is given.
// 'none' disables the filter.
const filter = core.getInput('filter')
if (filter.toUpperCase() === 'NONE') {
result.filter = undefined
} else if (filter) {
result.filter = filter
} else if (result.sparseCheckout) {
result.filter = 'blob:none'
}
core.debug(`filter = ${result.filter}`)
result.sparseCheckoutConeMode = result.sparseCheckoutConeMode =
(core.getInput('sparse-checkout-cone-mode') || 'true').toUpperCase() === (core.getInput('sparse-checkout-cone-mode') || 'true').toUpperCase() ===
'TRUE' 'TRUE'