























@@ -9,7 +9,10 @@ import {
99GITHUB_RESPONSE_BODY_MAX_BYTES,
1010createGitHubApi,
1111createGuardApproverChecks,
12+createIssueMutationHelpers,
13+guardCommentHeadSha,
1214guardTrustedActorCandidates,
15+isCommentNewerThan,
1316readBoundedGitHubErrorText,
1417readBoundedGitHubJson,
1518} from "./guard-shared.mjs";
@@ -195,29 +198,8 @@ export async function findDependencyOverrideCommandAsync(input) {
195198return null;
196199}
197200198-function isCommentNewerThan(comment, newerThan) {
199-if (!newerThan) {
200-return false;
201-}
202-const commentTime = Date.parse(comment.created_at ?? "");
203-const barrierTime = Date.parse(newerThan);
204-return Number.isFinite(commentTime) && Number.isFinite(barrierTime) && commentTime > barrierTime;
205-}
206-207201export function dependencyGuardCommentHeadSha(comment) {
208-const body = comment?.body ?? "";
209-const patterns = [
210-/Approved SHA:\s+`([a-f0-9]{40})`/iu,
211-/current head SHA\s+\(`([a-f0-9]{40})`\)/iu,
212-/Current SHA:\s+`([a-f0-9]{40})`/iu,
213-];
214-for (const pattern of patterns) {
215-const match = body.match(pattern);
216-if (match?.[1]) {
217-return match[1];
218-}
219-}
220-return null;
202+return guardCommentHeadSha(comment);
221203}
222204223205export function dependencyOverrideExpectedSha(existingGuardComment, currentHeadSha) {
@@ -497,17 +479,6 @@ export function githubApi(token, options = {}) {
497479}
498480return result.data;
499481},
500-paginate: async (path) => {
501-const items = [];
502-for (let page = 1; ; page += 1) {
503-const separator = path.includes("?") ? "&" : "?";
504-const pageItems = await api.request(`${path}${separator}per_page=100&page=${page}`);
505-items.push(...pageItems);
506-if (pageItems.length < 100) {
507-return items;
508-}
509-}
510-},
511482};
512483}
513484@@ -716,66 +687,8 @@ async function main() {
716687const existingGuardComment = findDependencyGuardComment(dependencyGraphGuardMarker);
717688const labelNames = new Set(labels.map((label) => label.name));
718689719-const ignoreUnavailableWritePermission = (action) => (error) => {
720-if (error?.status === 403) {
721-console.warn(`Skipping ${action}; token does not have write permission.`);
722-return;
723-}
724-if (error?.status === 404 || error?.status === 422) {
725-console.warn(`${action} is unavailable.`);
726-return;
727-}
728-throw error;
729-};
730-const removeLabelIfPresent = async (label) => {
731-if (!labelNames.has(label)) {
732-return;
733-}
734-await api
735-.request(`${issuePath}/labels/${encodeURIComponent(label)}`, {
736-method: "DELETE",
737-})
738-.catch(ignoreUnavailableWritePermission(`label "${label}" removal`));
739-labelNames.delete(label);
740-};
741-const addLabelIfMissing = async (label) => {
742-if (labelNames.has(label)) {
743-return;
744-}
745-await api
746-.request(`${issuePath}/labels`, {
747-method: "POST",
748-body: JSON.stringify({ labels: [label] }),
749-})
750-.catch(ignoreUnavailableWritePermission(`label "${label}" update`));
751-labelNames.add(label);
752-};
753-const deleteCommentIfPresent = async (comment) => {
754-if (!comment) {
755-return;
756-}
757-await api
758-.request(`/repos/${owner}/${repo}/issues/comments/${comment.id}`, {
759-method: "DELETE",
760-})
761-.catch(ignoreUnavailableWritePermission("comment deletion"));
762-};
763-const upsertComment = async (comment, body) => {
764-if (comment) {
765-return await api
766-.request(`/repos/${owner}/${repo}/issues/comments/${comment.id}`, {
767-method: "PATCH",
768-body: JSON.stringify({ body }),
769-})
770-.catch(ignoreUnavailableWritePermission("comment update"));
771-}
772-return await api
773-.request(`${issuePath}/comments`, {
774-method: "POST",
775-body: JSON.stringify({ body }),
776-})
777-.catch(ignoreUnavailableWritePermission("comment creation"));
778-};
690+const { removeLabelIfPresent, addLabelIfMissing, deleteCommentIfPresent, upsertComment } =
691+createIssueMutationHelpers({ api, issuePath, owner, repo, labelNames });
779692780693if (dependencyGraphFiles.length === 0) {
781694await removeLabelIfPresent(dependencyChangedLabel);
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。