Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add string[] option to submodules #1866

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add string[] option to submodules
Allows checking out only specific submodules instead of all
  • Loading branch information
Maddimax committed Aug 27, 2024
commit b6625bb44a3dc04c6017913a96f748ef400dbc1f
11 changes: 11 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -154,6 +154,17 @@ jobs:
submodules: true
- name: Verify submodules true
run: __test__/verify-submodules-true.sh

# Submodules limited
- name: Checkout submodules limited
uses: ./
with:
ref: test-data/v2/submodule-ssh-url
path: submodules-true
submodules: true
submodule-directories: submodule-level-1
- name: Verify submodules true
run: __test__/verify-submodules-true.sh

# Submodules recursive
- name: Checkout submodules recursive
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -116,6 +116,10 @@ Please refer to the [release page](https://github.com/actions/checkout/releases/
# Default: false
submodules: ''

# A list of submodules to use when `submodules` is `true`.
# Default: null
submodule-directories: ''

# Add repository path as safe.directory for Git global config by running `git
# config --global --add safe.directory <path>`
# Default: true
1 change: 1 addition & 0 deletions __test__/git-auth-helper.test.ts
Original file line number Diff line number Diff line change
@@ -813,6 +813,7 @@ async function setup(testName: string): Promise<void> {
lfs: false,
submodules: false,
nestedSubmodules: false,
submoduleDirectories: null,
persistCredentials: true,
ref: 'refs/heads/main',
repositoryName: 'my-repo',
17 changes: 17 additions & 0 deletions __test__/input-helper.test.ts
Original file line number Diff line number Diff line change
@@ -21,6 +21,13 @@ describe('input-helper tests', () => {
jest.spyOn(core, 'getInput').mockImplementation((name: string) => {
return inputs[name]
})
// Mock getMultilineInput
jest.spyOn(core, 'getMultilineInput').mockImplementation((name: string) => {
const input: string[] = (inputs[name] || '')
.split('\n')
.filter(x => x !== '')
return input.map(inp => inp.trim())
})

// Mock error/warning/info/debug
jest.spyOn(core, 'error').mockImplementation(jest.fn())
@@ -87,6 +94,7 @@ describe('input-helper tests', () => {
expect(settings.showProgress).toBe(true)
expect(settings.lfs).toBe(false)
expect(settings.ref).toBe('refs/heads/some-ref')
expect(settings.submoduleDirectories).toBe(null)
expect(settings.repositoryName).toBe('some-repo')
expect(settings.repositoryOwner).toBe('some-owner')
expect(settings.repositoryPath).toBe(gitHubWorkspace)
@@ -144,4 +152,13 @@ describe('input-helper tests', () => {
const settings: IGitSourceSettings = await inputHelper.getInputs()
expect(settings.workflowOrganizationId).toBe(123456)
})
it('sets submoduleDirectories', async () => {
inputs['submodule-directories'] = 'submodule1\nsubmodule2'
const settings: IGitSourceSettings = await inputHelper.getInputs()
expect(settings.submoduleDirectories).toStrictEqual([
'submodule1',
'submodule2'
])
expect(settings.submodules).toBe(true)
})
})
4 changes: 4 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
@@ -92,6 +92,10 @@ inputs:
When the `ssh-key` input is not provided, SSH URLs beginning with `git@github.com:` are
converted to HTTPS.
default: false
submodule-directories:
description: >
A list of submodules to use when `submodules` is `true`.
default: null
set-safe-directory:
description: Add repository path as safe.directory for Git global config by running `git config --global --add safe.directory <path>`
default: true
44 changes: 35 additions & 9 deletions dist/index.js
Original file line number Diff line number Diff line change
@@ -795,17 +795,32 @@ class GitCommandManager {
yield this.execGit(args);
});
}
submoduleUpdate(fetchDepth, recursive) {
submoduleUpdate(fetchDepth, recursive, submoduleDirectories) {
return __awaiter(this, void 0, void 0, function* () {
const args = ['-c', 'protocol.version=2'];
args.push('submodule', 'update', '--init', '--force');
if (fetchDepth > 0) {
args.push(`--depth=${fetchDepth}`);
if (submoduleDirectories) {
for (const submodule of submoduleDirectories) {
const args = ['-c', 'protocol.version=2'];
args.push('submodule', 'update', '--init', '--force', submodule);
if (fetchDepth > 0) {
args.push(`--depth=${fetchDepth}`);
}
if (recursive) {
args.push('--recursive');
}
yield this.execGit(args);
}
}
if (recursive) {
args.push('--recursive');
else {
const args = ['-c', 'protocol.version=2'];
args.push('submodule', 'update', '--init', '--force');
if (fetchDepth > 0) {
args.push(`--depth=${fetchDepth}`);
}
if (recursive) {
args.push('--recursive');
}
yield this.execGit(args);
}
yield this.execGit(args);
});
}
submoduleStatus() {
@@ -1342,7 +1357,7 @@ function getSource(settings) {
// Checkout submodules
core.startGroup('Fetching submodules');
yield git.submoduleSync(settings.nestedSubmodules);
yield git.submoduleUpdate(settings.fetchDepth, settings.nestedSubmodules);
yield git.submoduleUpdate(settings.fetchDepth, settings.nestedSubmodules, settings.submoduleDirectories);
yield git.submoduleForeach('git config --local gc.auto 0', settings.nestedSubmodules);
core.endGroup();
// Persist credentials
@@ -1805,6 +1820,7 @@ function getInputs() {
// Submodules
result.submodules = false;
result.nestedSubmodules = false;
result.submoduleDirectories = null;
const submodulesString = (core.getInput('submodules') || '').toUpperCase();
if (submodulesString == 'RECURSIVE') {
result.submodules = true;
@@ -1813,8 +1829,18 @@ function getInputs() {
else if (submodulesString == 'TRUE') {
result.submodules = true;
}
const submoduleDirectories = core.getMultilineInput('submodule-directories');
if (submoduleDirectories.length > 0) {
result.submoduleDirectories = submoduleDirectories;
if (!result.submodules)
result.submodules = true;
}
else {
result.submoduleDirectories = null;
}
core.debug(`submodules = ${result.submodules}`);
core.debug(`recursive submodules = ${result.nestedSubmodules}`);
core.debug(`submodule directories = ${result.submoduleDirectories}`);
// Auth token
result.authToken = core.getInput('token', { required: true });
// SSH
46 changes: 35 additions & 11 deletions src/git-command-manager.ts
Original file line number Diff line number Diff line change
@@ -54,7 +54,11 @@ export interface IGitCommandManager {
shaExists(sha: string): Promise<boolean>
submoduleForeach(command: string, recursive: boolean): Promise<string>
submoduleSync(recursive: boolean): Promise<void>
submoduleUpdate(fetchDepth: number, recursive: boolean): Promise<void>
submoduleUpdate(
fetchDepth: number,
recursive: boolean,
submoduleDirectories: string[] | null
): Promise<void>
submoduleStatus(): Promise<boolean>
tagExists(pattern: string): Promise<boolean>
tryClean(): Promise<boolean>
@@ -409,18 +413,38 @@ class GitCommandManager {
await this.execGit(args)
}

async submoduleUpdate(fetchDepth: number, recursive: boolean): Promise<void> {
const args = ['-c', 'protocol.version=2']
args.push('submodule', 'update', '--init', '--force')
if (fetchDepth > 0) {
args.push(`--depth=${fetchDepth}`)
}
async submoduleUpdate(
fetchDepth: number,
recursive: boolean,
submoduleDirectories: string[] | null
): Promise<void> {
if (submoduleDirectories) {
for (const submodule of submoduleDirectories) {
const args = ['-c', 'protocol.version=2']
args.push('submodule', 'update', '--init', '--force', submodule)
if (fetchDepth > 0) {
args.push(`--depth=${fetchDepth}`)
}

if (recursive) {
args.push('--recursive')
}
if (recursive) {
args.push('--recursive')
}

await this.execGit(args)
await this.execGit(args)
}
} else {
const args = ['-c', 'protocol.version=2']
args.push('submodule', 'update', '--init', '--force')
if (fetchDepth > 0) {
args.push(`--depth=${fetchDepth}`)
}

if (recursive) {
args.push('--recursive')
}

await this.execGit(args)
}
}

async submoduleStatus(): Promise<boolean> {
6 changes: 5 additions & 1 deletion src/git-source-provider.ts
Original file line number Diff line number Diff line change
@@ -242,7 +242,11 @@ export async function getSource(settings: IGitSourceSettings): Promise<void> {
// Checkout submodules
core.startGroup('Fetching submodules')
await git.submoduleSync(settings.nestedSubmodules)
await git.submoduleUpdate(settings.fetchDepth, settings.nestedSubmodules)
await git.submoduleUpdate(
settings.fetchDepth,
settings.nestedSubmodules,
settings.submoduleDirectories
)
await git.submoduleForeach(
'git config --local gc.auto 0',
settings.nestedSubmodules
5 changes: 5 additions & 0 deletions src/git-source-settings.ts
Original file line number Diff line number Diff line change
@@ -74,6 +74,11 @@ export interface IGitSourceSettings {
*/
nestedSubmodules: boolean

/**
* Indicates which submodule paths to checkout
*/
submoduleDirectories: string[] | null

/**
* The auth token to use when fetching the repository
*/
12 changes: 11 additions & 1 deletion src/input-helper.ts
Original file line number Diff line number Diff line change
@@ -125,16 +125,26 @@ export async function getInputs(): Promise<IGitSourceSettings> {
// Submodules
result.submodules = false
result.nestedSubmodules = false
result.submoduleDirectories = null
const submodulesString = (core.getInput('submodules') || '').toUpperCase()
if (submodulesString == 'RECURSIVE') {
result.submodules = true
result.nestedSubmodules = true
} else if (submodulesString == 'TRUE') {
result.submodules = true
}

const submoduleDirectories = core.getMultilineInput('submodule-directories')
if (submoduleDirectories.length > 0) {
result.submoduleDirectories = submoduleDirectories
if (!result.submodules) result.submodules = true
} else {
result.submoduleDirectories = null
}

core.debug(`submodules = ${result.submodules}`)
core.debug(`recursive submodules = ${result.nestedSubmodules}`)

core.debug(`submodule directories = ${result.submoduleDirectories}`)
// Auth token
result.authToken = core.getInput('token', {required: true})