Skip to content

Commit 5c1bbe6

Browse files
committed
set safe directory when running checkout
1 parent add3486 commit 5c1bbe6

File tree

4 files changed

+236
-165
lines changed

4 files changed

+236
-165
lines changed

__test__/git-auth-helper.test.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -643,10 +643,11 @@ describe('git-auth-helper tests', () => {
643643
expect(gitConfigContent.indexOf('http.')).toBeLessThan(0)
644644
})
645645

646-
const removeGlobalAuth_removesOverride = 'removeGlobalAuth removes override'
647-
it(removeGlobalAuth_removesOverride, async () => {
646+
const removeGlobalConfig_removesOverride =
647+
'removeGlobalConfig removes override'
648+
it(removeGlobalConfig_removesOverride, async () => {
648649
// Arrange
649-
await setup(removeGlobalAuth_removesOverride)
650+
await setup(removeGlobalConfig_removesOverride)
650651
const authHelper = gitAuthHelper.createAuthHelper(git, settings)
651652
await authHelper.configureAuth()
652653
await authHelper.configureGlobalAuth()
@@ -655,7 +656,7 @@ describe('git-auth-helper tests', () => {
655656
await fs.promises.stat(path.join(git.env['HOME'], '.gitconfig'))
656657

657658
// Act
658-
await authHelper.removeGlobalAuth()
659+
await authHelper.removeGlobalConfig()
659660

660661
// Assert
661662
expect(git.env['HOME']).toBeUndefined()

dist/index.js

+99-66
Original file line numberDiff line numberDiff line change
@@ -6572,9 +6572,13 @@ class GitAuthHelper {
65726572
yield this.configureToken();
65736573
});
65746574
}
6575-
configureGlobalAuth() {
6576-
var _a;
6575+
configureTempGlobalConfig(repositoryPath) {
6576+
var _a, _b;
65776577
return __awaiter(this, void 0, void 0, function* () {
6578+
// Already setup global config
6579+
if (((_a = this.temporaryHomePath) === null || _a === void 0 ? void 0 : _a.length) > 0) {
6580+
return path.join(this.temporaryHomePath, '.gitconfig');
6581+
}
65786582
// Create a temp home directory
65796583
const runnerTemp = process.env['RUNNER_TEMP'] || '';
65806584
assert.ok(runnerTemp, 'RUNNER_TEMP is not defined');
@@ -6590,7 +6594,7 @@ class GitAuthHelper {
65906594
configExists = true;
65916595
}
65926596
catch (err) {
6593-
if (((_a = err) === null || _a === void 0 ? void 0 : _a.code) !== 'ENOENT') {
6597+
if (((_b = err) === null || _b === void 0 ? void 0 : _b.code) !== 'ENOENT') {
65946598
throw err;
65956599
}
65966600
}
@@ -6601,10 +6605,25 @@ class GitAuthHelper {
66016605
else {
66026606
yield fs.promises.writeFile(newGitConfigPath, '');
66036607
}
6608+
// Override HOME
6609+
core.info(`Temporarily overriding HOME='${this.temporaryHomePath}' before making global git config changes`);
6610+
this.git.setEnvironmentVariable('HOME', this.temporaryHomePath);
6611+
// Setup the workspace as a safe directory, so if we pass this into a container job with a different user it doesn't fail
6612+
// Otherwise all git commands we run in a container fail
6613+
core.info(`Adding working directory to the temporary git global config as a safe directory`);
6614+
yield this.git
6615+
.config('safe.directory', repositoryPath !== null && repositoryPath !== void 0 ? repositoryPath : this.settings.repositoryPath, true, true)
6616+
.catch(error => {
6617+
core.info(`Failed to initialize safe directory with error: ${error}`);
6618+
});
6619+
return newGitConfigPath;
6620+
});
6621+
}
6622+
configureGlobalAuth() {
6623+
return __awaiter(this, void 0, void 0, function* () {
6624+
// noops if already set, just returns the path
6625+
const newGitConfigPath = yield this.configureTempGlobalConfig();
66046626
try {
6605-
// Override HOME
6606-
core.info(`Temporarily overriding HOME='${this.temporaryHomePath}' before making global git config changes`);
6607-
this.git.setEnvironmentVariable('HOME', this.temporaryHomePath);
66086627
// Configure the token
66096628
yield this.configureToken(newGitConfigPath, true);
66106629
// Configure HTTPS instead of SSH
@@ -6657,11 +6676,14 @@ class GitAuthHelper {
66576676
yield this.removeToken();
66586677
});
66596678
}
6660-
removeGlobalAuth() {
6679+
removeGlobalConfig() {
6680+
var _a;
66616681
return __awaiter(this, void 0, void 0, function* () {
6662-
core.debug(`Unsetting HOME override`);
6663-
this.git.removeEnvironmentVariable('HOME');
6664-
yield io.rmRF(this.temporaryHomePath);
6682+
if (((_a = this.temporaryHomePath) === null || _a === void 0 ? void 0 : _a.length) > 0) {
6683+
core.debug(`Unsetting HOME override`);
6684+
this.git.removeEnvironmentVariable('HOME');
6685+
yield io.rmRF(this.temporaryHomePath);
6686+
}
66656687
});
66666688
}
66676689
configureSsh() {
@@ -7326,40 +7348,48 @@ function getSource(settings) {
73267348
core.startGroup('Getting Git version info');
73277349
const git = yield getGitCommandManager(settings);
73287350
core.endGroup();
7329-
// Prepare existing directory, otherwise recreate
7330-
if (isExisting) {
7331-
yield gitDirectoryHelper.prepareExistingDirectory(git, settings.repositoryPath, repositoryUrl, settings.clean, settings.ref);
7332-
}
7333-
if (!git) {
7334-
// Downloading using REST API
7335-
core.info(`The repository will be downloaded using the GitHub REST API`);
7336-
core.info(`To create a local Git repository instead, add Git ${gitCommandManager.MinimumGitVersion} or higher to the PATH`);
7337-
if (settings.submodules) {
7338-
throw new Error(`Input 'submodules' not supported when falling back to download using the GitHub REST API. To create a local Git repository instead, add Git ${gitCommandManager.MinimumGitVersion} or higher to the PATH.`);
7351+
let authHelper = null;
7352+
try {
7353+
if (git) {
7354+
authHelper = gitAuthHelper.createAuthHelper(git, settings);
7355+
yield authHelper.configureTempGlobalConfig();
73397356
}
7340-
else if (settings.sshKey) {
7341-
throw new Error(`Input 'ssh-key' not supported when falling back to download using the GitHub REST API. To create a local Git repository instead, add Git ${gitCommandManager.MinimumGitVersion} or higher to the PATH.`);
7357+
// Prepare existing directory, otherwise recreate
7358+
if (isExisting) {
7359+
yield gitDirectoryHelper.prepareExistingDirectory(git, settings.repositoryPath, repositoryUrl, settings.clean, settings.ref);
7360+
}
7361+
if (!git) {
7362+
// Downloading using REST API
7363+
core.info(`The repository will be downloaded using the GitHub REST API`);
7364+
core.info(`To create a local Git repository instead, add Git ${gitCommandManager.MinimumGitVersion} or higher to the PATH`);
7365+
if (settings.submodules) {
7366+
throw new Error(`Input 'submodules' not supported when falling back to download using the GitHub REST API. To create a local Git repository instead, add Git ${gitCommandManager.MinimumGitVersion} or higher to the PATH.`);
7367+
}
7368+
else if (settings.sshKey) {
7369+
throw new Error(`Input 'ssh-key' not supported when falling back to download using the GitHub REST API. To create a local Git repository instead, add Git ${gitCommandManager.MinimumGitVersion} or higher to the PATH.`);
7370+
}
7371+
yield githubApiHelper.downloadRepository(settings.authToken, settings.repositoryOwner, settings.repositoryName, settings.ref, settings.commit, settings.repositoryPath);
7372+
return;
7373+
}
7374+
// Save state for POST action
7375+
stateHelper.setRepositoryPath(settings.repositoryPath);
7376+
// Initialize the repository
7377+
if (!fsHelper.directoryExistsSync(path.join(settings.repositoryPath, '.git'))) {
7378+
core.startGroup('Initializing the repository');
7379+
yield git.init();
7380+
yield git.remoteAdd('origin', repositoryUrl);
7381+
core.endGroup();
7382+
}
7383+
// Disable automatic garbage collection
7384+
core.startGroup('Disabling automatic garbage collection');
7385+
if (!(yield git.tryDisableAutomaticGarbageCollection())) {
7386+
core.warning(`Unable to turn off git automatic garbage collection. The git fetch operation may trigger garbage collection and cause a delay.`);
73427387
}
7343-
yield githubApiHelper.downloadRepository(settings.authToken, settings.repositoryOwner, settings.repositoryName, settings.ref, settings.commit, settings.repositoryPath);
7344-
return;
7345-
}
7346-
// Save state for POST action
7347-
stateHelper.setRepositoryPath(settings.repositoryPath);
7348-
// Initialize the repository
7349-
if (!fsHelper.directoryExistsSync(path.join(settings.repositoryPath, '.git'))) {
7350-
core.startGroup('Initializing the repository');
7351-
yield git.init();
7352-
yield git.remoteAdd('origin', repositoryUrl);
73537388
core.endGroup();
7354-
}
7355-
// Disable automatic garbage collection
7356-
core.startGroup('Disabling automatic garbage collection');
7357-
if (!(yield git.tryDisableAutomaticGarbageCollection())) {
7358-
core.warning(`Unable to turn off git automatic garbage collection. The git fetch operation may trigger garbage collection and cause a delay.`);
7359-
}
7360-
core.endGroup();
7361-
const authHelper = gitAuthHelper.createAuthHelper(git, settings);
7362-
try {
7389+
// If we didn't initialize it above, do it now
7390+
if (!authHelper) {
7391+
authHelper = gitAuthHelper.createAuthHelper(git, settings);
7392+
}
73637393
// Configure auth
73647394
core.startGroup('Setting up auth');
73657395
yield authHelper.configureAuth();
@@ -7415,27 +7445,21 @@ function getSource(settings) {
74157445
core.endGroup();
74167446
// Submodules
74177447
if (settings.submodules) {
7418-
try {
7419-
// Temporarily override global config
7420-
core.startGroup('Setting up auth for fetching submodules');
7421-
yield authHelper.configureGlobalAuth();
7422-
core.endGroup();
7423-
// Checkout submodules
7424-
core.startGroup('Fetching submodules');
7425-
yield git.submoduleSync(settings.nestedSubmodules);
7426-
yield git.submoduleUpdate(settings.fetchDepth, settings.nestedSubmodules);
7427-
yield git.submoduleForeach('git config --local gc.auto 0', settings.nestedSubmodules);
7448+
// Temporarily override global config
7449+
core.startGroup('Setting up auth for fetching submodules');
7450+
yield authHelper.configureGlobalAuth();
7451+
core.endGroup();
7452+
// Checkout submodules
7453+
core.startGroup('Fetching submodules');
7454+
yield git.submoduleSync(settings.nestedSubmodules);
7455+
yield git.submoduleUpdate(settings.fetchDepth, settings.nestedSubmodules);
7456+
yield git.submoduleForeach('git config --local gc.auto 0', settings.nestedSubmodules);
7457+
core.endGroup();
7458+
// Persist credentials
7459+
if (settings.persistCredentials) {
7460+
core.startGroup('Persisting credentials for submodules');
7461+
yield authHelper.configureSubmoduleAuth();
74287462
core.endGroup();
7429-
// Persist credentials
7430-
if (settings.persistCredentials) {
7431-
core.startGroup('Persisting credentials for submodules');
7432-
yield authHelper.configureSubmoduleAuth();
7433-
core.endGroup();
7434-
}
7435-
}
7436-
finally {
7437-
// Remove temporary global config override
7438-
yield authHelper.removeGlobalAuth();
74397463
}
74407464
}
74417465
// Get commit information
@@ -7447,10 +7471,13 @@ function getSource(settings) {
74477471
}
74487472
finally {
74497473
// Remove auth
7450-
if (!settings.persistCredentials) {
7451-
core.startGroup('Removing auth');
7452-
yield authHelper.removeAuth();
7453-
core.endGroup();
7474+
if (authHelper) {
7475+
if (!settings.persistCredentials) {
7476+
core.startGroup('Removing auth');
7477+
yield authHelper.removeAuth();
7478+
core.endGroup();
7479+
}
7480+
authHelper.removeGlobalConfig();
74547481
}
74557482
}
74567483
});
@@ -7472,7 +7499,13 @@ function cleanup(repositoryPath) {
74727499
}
74737500
// Remove auth
74747501
const authHelper = gitAuthHelper.createAuthHelper(git);
7475-
yield authHelper.removeAuth();
7502+
try {
7503+
yield authHelper.configureTempGlobalConfig(repositoryPath);
7504+
yield authHelper.removeAuth();
7505+
}
7506+
finally {
7507+
yield authHelper.removeGlobalConfig();
7508+
}
74767509
});
74777510
}
74787511
exports.cleanup = cleanup;

src/git-auth-helper.ts

+39-11
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ export interface IGitAuthHelper {
1919
configureAuth(): Promise<void>
2020
configureGlobalAuth(): Promise<void>
2121
configureSubmoduleAuth(): Promise<void>
22+
configureTempGlobalConfig(repositoryPath?: string): Promise<string>
2223
removeAuth(): Promise<void>
23-
removeGlobalAuth(): Promise<void>
24+
removeGlobalConfig(): Promise<void>
2425
}
2526

2627
export function createAuthHelper(
@@ -80,7 +81,11 @@ class GitAuthHelper {
8081
await this.configureToken()
8182
}
8283

83-
async configureGlobalAuth(): Promise<void> {
84+
async configureTempGlobalConfig(repositoryPath?: string): Promise<string> {
85+
// Already setup global config
86+
if (this.temporaryHomePath?.length > 0) {
87+
return path.join(this.temporaryHomePath, '.gitconfig')
88+
}
8489
// Create a temp home directory
8590
const runnerTemp = process.env['RUNNER_TEMP'] || ''
8691
assert.ok(runnerTemp, 'RUNNER_TEMP is not defined')
@@ -110,13 +115,34 @@ class GitAuthHelper {
110115
await fs.promises.writeFile(newGitConfigPath, '')
111116
}
112117

113-
try {
114-
// Override HOME
115-
core.info(
116-
`Temporarily overriding HOME='${this.temporaryHomePath}' before making global git config changes`
118+
// Override HOME
119+
core.info(
120+
`Temporarily overriding HOME='${this.temporaryHomePath}' before making global git config changes`
121+
)
122+
this.git.setEnvironmentVariable('HOME', this.temporaryHomePath)
123+
124+
// Setup the workspace as a safe directory, so if we pass this into a container job with a different user it doesn't fail
125+
// Otherwise all git commands we run in a container fail
126+
core.info(
127+
`Adding working directory to the temporary git global config as a safe directory`
128+
)
129+
await this.git
130+
.config(
131+
'safe.directory',
132+
repositoryPath ?? this.settings.repositoryPath,
133+
true,
134+
true
117135
)
118-
this.git.setEnvironmentVariable('HOME', this.temporaryHomePath)
136+
.catch(error => {
137+
core.info(`Failed to initialize safe directory with error: ${error}`)
138+
})
139+
return newGitConfigPath
140+
}
119141

142+
async configureGlobalAuth(): Promise<void> {
143+
// noops if already set, just returns the path
144+
const newGitConfigPath = await this.configureTempGlobalConfig()
145+
try {
120146
// Configure the token
121147
await this.configureToken(newGitConfigPath, true)
122148

@@ -181,10 +207,12 @@ class GitAuthHelper {
181207
await this.removeToken()
182208
}
183209

184-
async removeGlobalAuth(): Promise<void> {
185-
core.debug(`Unsetting HOME override`)
186-
this.git.removeEnvironmentVariable('HOME')
187-
await io.rmRF(this.temporaryHomePath)
210+
async removeGlobalConfig(): Promise<void> {
211+
if (this.temporaryHomePath?.length > 0) {
212+
core.debug(`Unsetting HOME override`)
213+
this.git.removeEnvironmentVariable('HOME')
214+
await io.rmRF(this.temporaryHomePath)
215+
}
188216
}
189217

190218
private async configureSsh(): Promise<void> {

0 commit comments

Comments
 (0)