64 lines
2.6 KiB
JavaScript
64 lines
2.6 KiB
JavaScript
function mergeEligibility(detail) {
|
|
if (!detail || detail.state !== 'open' || detail.merged) {
|
|
return { allowed: false, reason: 'Pull request is not open' };
|
|
}
|
|
if (detail.draft) return { allowed: false, reason: 'Draft pull requests cannot be merged' };
|
|
if (!detail.mergeable) return { allowed: false, reason: 'Resolve conflicts before merging' };
|
|
if (detail.ci_state !== 'success') {
|
|
return { allowed: false, reason: 'CI must succeed before merging' };
|
|
}
|
|
if (!detail.head_sha) return { allowed: false, reason: 'Current head is unavailable' };
|
|
return { allowed: true, reason: 'Ready to merge' };
|
|
}
|
|
|
|
function createPullSheet({ fetchJson, storage }) {
|
|
let commentRequest = null;
|
|
let mergeRequest = null;
|
|
const pathFor = item => 'api/v1/repos/' + String(item.repository || '').split('/')
|
|
.map(encodeURIComponent).join('/') + '/pulls/' + encodeURIComponent(item.number);
|
|
const draftKey = item => 'stackchain.pull-comment.v1:' + item.repository + '#' + item.number;
|
|
|
|
return {
|
|
load(item) {
|
|
return fetchJson(pathFor(item) + '/detail', { headers: { Accept: 'application/json' } });
|
|
},
|
|
loadDraft(item) {
|
|
try { return storage?.getItem(draftKey(item)) || ''; }
|
|
catch (_error) { return ''; }
|
|
},
|
|
saveDraft(item, body) {
|
|
try { storage?.setItem(draftKey(item), body); }
|
|
catch (_error) { /* The textarea remains the fallback. */ }
|
|
},
|
|
comment(item, body) {
|
|
if (commentRequest) return commentRequest;
|
|
this.saveDraft(item, body);
|
|
commentRequest = fetchJson(pathFor(item) + '/comments', {
|
|
method: 'POST',
|
|
headers: { Accept: 'application/json', 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ body }),
|
|
}).then(result => {
|
|
try { storage?.removeItem(draftKey(item)); }
|
|
catch (_error) { /* The upstream comment is authoritative. */ }
|
|
return result;
|
|
}).finally(() => { commentRequest = null; });
|
|
return commentRequest;
|
|
},
|
|
merge(item, expectedHeadSha) {
|
|
if (mergeRequest) return mergeRequest;
|
|
mergeRequest = fetchJson(pathFor(item) + '/merge', {
|
|
method: 'POST',
|
|
headers: { Accept: 'application/json', 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ expected_head_sha: expectedHeadSha }),
|
|
}).then(result => {
|
|
if (!result?.merged) throw new Error('Pull request merge was not confirmed.');
|
|
return result;
|
|
}).finally(() => { mergeRequest = null; });
|
|
return mergeRequest;
|
|
},
|
|
};
|
|
}
|
|
|
|
createPullSheet.mergeEligibility = mergeEligibility;
|
|
if (typeof module !== 'undefined' && module.exports) module.exports = createPullSheet;
|