Use git config --show-origin to reliably get submodule config paths

This commit is contained in:
eric sciple
2025-10-14 22:24:46 +00:00
parent 8e4be9ae12
commit a60fb6cabe
2 changed files with 23 additions and 13 deletions

16
dist/index.js vendored
View File

@@ -280,23 +280,27 @@ class GitAuthHelper {
let relativePath = path.relative(githubWorkspace, workingDirectory); let relativePath = path.relative(githubWorkspace, workingDirectory);
relativePath = relativePath.replace(/\\/g, '/'); relativePath = relativePath.replace(/\\/g, '/');
const containerWorkspaceBase = path.posix.join('/github/workspace', relativePath); const containerWorkspaceBase = path.posix.join('/github/workspace', relativePath);
// Get submodule paths. // Get submodule config file paths.
// `git rev-parse --show-toplevel` returns the absolute path of each submodule's working tree. // Use `--show-origin` to get the config file path for each submodule.
const submodulePaths = yield this.git.submoduleForeach(`git rev-parse --show-toplevel`, this.settings.nestedSubmodules); const output = yield this.git.submoduleForeach(`git config --local --show-origin --name-only --get-regexp remote.origin.url`, this.settings.nestedSubmodules);
// Extract config file paths from the output (lines starting with "file:").
const configPaths = output.match(/(?<=(^|\n)file:)[^\t]+(?=\tremote\.origin\.url)/g) || [];
// For each submodule, configure includeIf entries pointing to the shared credentials file. // For each submodule, configure includeIf entries pointing to the shared credentials file.
// Configure both host and container paths to support Docker container actions. // Configure both host and container paths to support Docker container actions.
for (const submodulePath of submodulePaths.split('\n').filter(x => x)) { for (const configPath of configPaths) {
// Get the submodule path from its config file path.
const submodulePath = path.dirname(path.dirname(configPath));
// Configure host path includeIf. // Configure host path includeIf.
// Use forward slashes for git config, even on Windows. // Use forward slashes for git config, even on Windows.
let submoduleGitDir = path.join(submodulePath, '.git'); let submoduleGitDir = path.join(submodulePath, '.git');
submoduleGitDir = submoduleGitDir.replace(/\\/g, '/'); submoduleGitDir = submoduleGitDir.replace(/\\/g, '/');
yield this.git.config(`includeIf.gitdir:${submoduleGitDir}.path`, credentialsConfigPath, false, false, path.join(submodulePath, '.git', 'config')); yield this.git.config(`includeIf.gitdir:${submoduleGitDir}.path`, credentialsConfigPath, false, false, configPath);
// Configure container path includeIf. // Configure container path includeIf.
// Use forward slashes for git config, even on Windows. // Use forward slashes for git config, even on Windows.
let submoduleRelativePath = path.relative(workingDirectory, submodulePath); let submoduleRelativePath = path.relative(workingDirectory, submodulePath);
submoduleRelativePath = submoduleRelativePath.replace(/\\/g, '/'); submoduleRelativePath = submoduleRelativePath.replace(/\\/g, '/');
const containerSubmoduleGitDir = path.posix.join(containerWorkspaceBase, submoduleRelativePath, '.git'); const containerSubmoduleGitDir = path.posix.join(containerWorkspaceBase, submoduleRelativePath, '.git');
yield this.git.config(`includeIf.gitdir:${containerSubmoduleGitDir}.path`, containerCredentialsPath, false, false, path.join(submodulePath, '.git', 'config')); yield this.git.config(`includeIf.gitdir:${containerSubmoduleGitDir}.path`, containerCredentialsPath, false, false, configPath);
} }
if (this.settings.sshKey) { if (this.settings.sshKey) {
// Configure core.sshCommand // Configure core.sshCommand

View File

@@ -190,16 +190,22 @@ class GitAuthHelper {
relativePath relativePath
) )
// Get submodule paths. // Get submodule config file paths.
// `git rev-parse --show-toplevel` returns the absolute path of each submodule's working tree. // Use `--show-origin` to get the config file path for each submodule.
const submodulePaths = await this.git.submoduleForeach( const output = await this.git.submoduleForeach(
`git rev-parse --show-toplevel`, `git config --local --show-origin --name-only --get-regexp remote.origin.url`,
this.settings.nestedSubmodules this.settings.nestedSubmodules
) )
// Extract config file paths from the output (lines starting with "file:").
const configPaths =
output.match(/(?<=(^|\n)file:)[^\t]+(?=\tremote\.origin\.url)/g) || []
// For each submodule, configure includeIf entries pointing to the shared credentials file. // For each submodule, configure includeIf entries pointing to the shared credentials file.
// Configure both host and container paths to support Docker container actions. // Configure both host and container paths to support Docker container actions.
for (const submodulePath of submodulePaths.split('\n').filter(x => x)) { for (const configPath of configPaths) {
// Get the submodule path from its config file path.
const submodulePath = path.dirname(path.dirname(configPath))
// Configure host path includeIf. // Configure host path includeIf.
// Use forward slashes for git config, even on Windows. // Use forward slashes for git config, even on Windows.
let submoduleGitDir = path.join(submodulePath, '.git') let submoduleGitDir = path.join(submodulePath, '.git')
@@ -209,7 +215,7 @@ class GitAuthHelper {
credentialsConfigPath, credentialsConfigPath,
false, false,
false, false,
path.join(submodulePath, '.git', 'config') configPath
) )
// Configure container path includeIf. // Configure container path includeIf.
@@ -229,7 +235,7 @@ class GitAuthHelper {
containerCredentialsPath, containerCredentialsPath,
false, false,
false, false,
path.join(submodulePath, '.git', 'config') configPath
) )
} }