豆豆友情提示:这是一个非官方 GitHub 代理镜像,主要用于网络测试或访问加速。请勿在此进行登录、注册或处理任何敏感信息。进行这些操作请务必访问官方网站 github.com。 Raw 内容也通过此代理提供。
Skip to content

Commit 70e6a6d

Browse files
committed
fix(github-actions): serialize file updates to prevent contention
Serializing the file updates in the org-file-sync prevents the createOrUpdate API calls from racing. The race condition of the previous parallelized method caused Github to return API errors related to unexpected base shas.
1 parent f896fed commit 70e6a6d

File tree

1 file changed

+13
-16
lines changed
  • github-actions/org-file-sync/src

1 file changed

+13
-16
lines changed

github-actions/org-file-sync/src/main.ts

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ async function getFilesForRepo(github: Octokit, repo: string): Promise<Files> {
3232
for (const path of filesToSync) {
3333
fileMap.set(path, await getFile(github, repo, path));
3434
}
35-
core.info(`Retrieved ${fileMap.size} file(s)`);
35+
const fileCount = [...fileMap.values()].filter(file => file !== null).length;
36+
core.info(`Retrieved ${fileCount} file(s)`);
3637
core.endGroup();
3738
return fileMap;
3839
}
@@ -65,18 +66,13 @@ async function getFile(github: Octokit, repo: string, path: string): Promise<Fil
6566
* with the same path in the repo.
6667
*/
6768
async function updateRepoWithFiles(github: Octokit, repo: string, goldenFiles: Files) {
68-
/**
69-
* Promises resolved when an update is completed.
70-
* Note: An array is used to allow for awaiting everything via `Promise.all`
71-
*/
72-
let updates: Promise<unknown>[] = [];
7369
/** The current files, or lack of files, for synchronizing in target repo. */
7470
const repoFiles = await getFilesForRepo(github, repo);
7571

76-
goldenFiles.forEach((goldenFile, path) => {
72+
for (let [path, goldenFile] of goldenFiles.entries()) {
7773
// If the golden file does not exist, we have nothing to syncronize.
7874
if (goldenFile === null) {
79-
return;
75+
continue;
8076
}
8177
/** The target repository's File for the path. */
8278
const repoFile = repoFiles.get(path) || null;
@@ -93,23 +89,24 @@ async function updateRepoWithFiles(github: Octokit, repo: string, goldenFiles: F
9389

9490
if (repoFileContent !== goldenFile.content) {
9591
core.info(`Updating "${path}" in "${repo}" repo`);
96-
updates.push(
97-
github.repos.createOrUpdateFileContents({
92+
try {
93+
await github.repos.createOrUpdateFileContents({
9894
content: goldenFile.content,
9995
owner: context.repo.owner,
10096
repo,
10197
path,
10298
message: `build: update \`${path}\` to match the content of \`${context.repo.owner}/${context.repo.repo}\``,
10399
// The SHA of the previous file content change is used if an update is occuring.
104100
sha: repoSha,
105-
}),
106-
);
101+
});
102+
} catch (e) {
103+
core.info(`Failed to update "${path}"`);
104+
console.error(e);
105+
}
107106
} else {
108107
core.info(`"${path}" is already in sync`);
109108
}
110-
});
111-
112-
await Promise.all(updates);
109+
}
113110
}
114111

115112
async function main() {
@@ -127,6 +124,6 @@ async function main() {
127124
}
128125

129126
main().catch((err) => {
130-
core.error(err);
127+
console.error(err);
131128
core.setFailed('Failed with the above error');
132129
});

0 commit comments

Comments
 (0)