Skip to content

Commit 84ae59a

Browse files
authored
fix: compatibility with actions/checkout@v6 (#4230)
Temporarily hides checkout@v6 credential files to prevent duplicate Authorization headers. Fixes #4228
1 parent b4733b9 commit 84ae59a

File tree

2 files changed

+97
-0
lines changed

2 files changed

+97
-0
lines changed

dist/index.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,6 +1103,7 @@ class GitConfigHelper {
11031103
this.extraheaderConfigPlaceholderValue = 'AUTHORIZATION: basic ***';
11041104
this.extraheaderConfigValueRegex = '^AUTHORIZATION:';
11051105
this.persistedExtraheaderConfigValue = '';
1106+
this.backedUpCredentialFiles = [];
11061107
this.git = git;
11071108
this.workingDirectory = this.git.getWorkingDirectory();
11081109
}
@@ -1182,12 +1183,16 @@ class GitConfigHelper {
11821183
return __awaiter(this, void 0, void 0, function* () {
11831184
const serverUrl = new url_1.URL(`https://${this.getGitRemote().hostname}`);
11841185
this.extraheaderConfigKey = `http.${serverUrl.origin}/.extraheader`;
1186+
// Backup checkout@v6 credential files if they exist
1187+
yield this.hideCredentialFiles();
11851188
// Save and unset persisted extraheader credential in git config if it exists
11861189
this.persistedExtraheaderConfigValue = yield this.getAndUnset();
11871190
});
11881191
}
11891192
restorePersistedAuth() {
11901193
return __awaiter(this, void 0, void 0, function* () {
1194+
// Restore checkout@v6 credential files if they were backed up
1195+
yield this.unhideCredentialFiles();
11911196
if (this.persistedExtraheaderConfigValue) {
11921197
try {
11931198
yield this.setExtraheaderConfig(this.persistedExtraheaderConfigValue);
@@ -1224,6 +1229,48 @@ class GitConfigHelper {
12241229
yield this.gitConfigStringReplace(this.extraheaderConfigPlaceholderValue, extraheaderConfigValue);
12251230
});
12261231
}
1232+
hideCredentialFiles() {
1233+
return __awaiter(this, void 0, void 0, function* () {
1234+
// Temporarily hide checkout@v6 credential files to avoid duplicate auth headers
1235+
const runnerTemp = process.env['RUNNER_TEMP'];
1236+
if (!runnerTemp) {
1237+
return;
1238+
}
1239+
try {
1240+
const files = yield fs.promises.readdir(runnerTemp);
1241+
for (const file of files) {
1242+
if (file.startsWith('git-credentials-') && file.endsWith('.config')) {
1243+
const sourcePath = path.join(runnerTemp, file);
1244+
const backupPath = `${sourcePath}.bak`;
1245+
yield fs.promises.rename(sourcePath, backupPath);
1246+
this.backedUpCredentialFiles.push(backupPath);
1247+
core.info(`Temporarily hiding checkout credential file: ${file} (will be restored after)`);
1248+
}
1249+
}
1250+
}
1251+
catch (e) {
1252+
// If directory doesn't exist or we can't read it, just continue
1253+
core.debug(`Could not backup credential files: ${utils.getErrorMessage(e)}`);
1254+
}
1255+
});
1256+
}
1257+
unhideCredentialFiles() {
1258+
return __awaiter(this, void 0, void 0, function* () {
1259+
// Restore checkout@v6 credential files that were backed up
1260+
for (const backupPath of this.backedUpCredentialFiles) {
1261+
try {
1262+
const originalPath = backupPath.replace(/\.bak$/, '');
1263+
yield fs.promises.rename(backupPath, originalPath);
1264+
const fileName = path.basename(originalPath);
1265+
core.info(`Restored checkout credential file: ${fileName}`);
1266+
}
1267+
catch (e) {
1268+
core.warning(`Failed to restore credential file ${backupPath}: ${utils.getErrorMessage(e)}`);
1269+
}
1270+
}
1271+
this.backedUpCredentialFiles = [];
1272+
});
1273+
}
12271274
getAndUnset() {
12281275
return __awaiter(this, void 0, void 0, function* () {
12291276
let configValue = '';

src/git-config-helper.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export class GitConfigHelper {
2222
private extraheaderConfigPlaceholderValue = 'AUTHORIZATION: basic ***'
2323
private extraheaderConfigValueRegex = '^AUTHORIZATION:'
2424
private persistedExtraheaderConfigValue = ''
25+
private backedUpCredentialFiles: string[] = []
2526

2627
private constructor(git: GitCommandManager) {
2728
this.git = git
@@ -121,11 +122,15 @@ export class GitConfigHelper {
121122
async savePersistedAuth(): Promise<void> {
122123
const serverUrl = new URL(`https://${this.getGitRemote().hostname}`)
123124
this.extraheaderConfigKey = `http.${serverUrl.origin}/.extraheader`
125+
// Backup checkout@v6 credential files if they exist
126+
await this.hideCredentialFiles()
124127
// Save and unset persisted extraheader credential in git config if it exists
125128
this.persistedExtraheaderConfigValue = await this.getAndUnset()
126129
}
127130

128131
async restorePersistedAuth(): Promise<void> {
132+
// Restore checkout@v6 credential files if they were backed up
133+
await this.unhideCredentialFiles()
129134
if (this.persistedExtraheaderConfigValue) {
130135
try {
131136
await this.setExtraheaderConfig(this.persistedExtraheaderConfigValue)
@@ -169,6 +174,51 @@ export class GitConfigHelper {
169174
)
170175
}
171176

177+
private async hideCredentialFiles(): Promise<void> {
178+
// Temporarily hide checkout@v6 credential files to avoid duplicate auth headers
179+
const runnerTemp = process.env['RUNNER_TEMP']
180+
if (!runnerTemp) {
181+
return
182+
}
183+
184+
try {
185+
const files = await fs.promises.readdir(runnerTemp)
186+
for (const file of files) {
187+
if (file.startsWith('git-credentials-') && file.endsWith('.config')) {
188+
const sourcePath = path.join(runnerTemp, file)
189+
const backupPath = `${sourcePath}.bak`
190+
await fs.promises.rename(sourcePath, backupPath)
191+
this.backedUpCredentialFiles.push(backupPath)
192+
core.info(
193+
`Temporarily hiding checkout credential file: ${file} (will be restored after)`
194+
)
195+
}
196+
}
197+
} catch (e) {
198+
// If directory doesn't exist or we can't read it, just continue
199+
core.debug(
200+
`Could not backup credential files: ${utils.getErrorMessage(e)}`
201+
)
202+
}
203+
}
204+
205+
private async unhideCredentialFiles(): Promise<void> {
206+
// Restore checkout@v6 credential files that were backed up
207+
for (const backupPath of this.backedUpCredentialFiles) {
208+
try {
209+
const originalPath = backupPath.replace(/\.bak$/, '')
210+
await fs.promises.rename(backupPath, originalPath)
211+
const fileName = path.basename(originalPath)
212+
core.info(`Restored checkout credential file: ${fileName}`)
213+
} catch (e) {
214+
core.warning(
215+
`Failed to restore credential file ${backupPath}: ${utils.getErrorMessage(e)}`
216+
)
217+
}
218+
}
219+
this.backedUpCredentialFiles = []
220+
}
221+
172222
private async getAndUnset(): Promise<string> {
173223
let configValue = ''
174224
// Save and unset persisted extraheader credential in git config if it exists

0 commit comments

Comments
 (0)