mirror of
https://github.com/softprops/action-gh-release
synced 2026-10-03 02:01:31 +00:00
fix: preserve discussion category when publishing releases (#765)
Signed-off-by: Rui Chen <rui@chenrui.dev>
This commit is contained in:
1 parent
26e8ad27a0
commit
569deb874d
3 files changed
+103
-2
No files matched your search
@@ -226,6 +226,64 @@ describe('github', () => {
|
||||
);
|
||||
expect(createRelease.mock.calls[0][0]).not.toHaveProperty('previous_tag_name');
|
||||
});
|
||||
|
||||
it('passes discussion_category_name when finalizing a release', async () => {
|
||||
const updateRelease = vi.fn(async () => ({
|
||||
data: {
|
||||
id: 1,
|
||||
upload_url: 'test',
|
||||
html_url: 'test',
|
||||
tag_name: 'v1.0.0',
|
||||
name: 'v1.0.0',
|
||||
body: 'test',
|
||||
target_commitish: 'main',
|
||||
draft: false,
|
||||
prerelease: false,
|
||||
assets: [],
|
||||
},
|
||||
}));
|
||||
|
||||
const releaser = new GitHubReleaser({
|
||||
rest: {
|
||||
repos: {
|
||||
generateReleaseNotes: vi.fn(),
|
||||
createRelease: vi.fn(),
|
||||
updateRelease,
|
||||
getReleaseByTag: vi.fn(),
|
||||
listReleaseAssets: vi.fn(),
|
||||
deleteReleaseAsset: vi.fn(),
|
||||
deleteRelease: vi.fn(),
|
||||
updateReleaseAsset: vi.fn(),
|
||||
listReleases: {
|
||||
endpoint: {
|
||||
merge: vi.fn(),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
paginate: {
|
||||
iterator: vi.fn(),
|
||||
},
|
||||
request: vi.fn(),
|
||||
} as any);
|
||||
|
||||
await releaser.finalizeRelease({
|
||||
owner: 'owner',
|
||||
repo: 'repo',
|
||||
release_id: 1,
|
||||
make_latest: 'legacy',
|
||||
discussion_category_name: 'Announcements',
|
||||
});
|
||||
|
||||
expect(updateRelease).toHaveBeenCalledWith({
|
||||
owner: 'owner',
|
||||
repo: 'repo',
|
||||
release_id: 1,
|
||||
draft: false,
|
||||
make_latest: 'legacy',
|
||||
discussion_category_name: 'Announcements',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('finalizeRelease input_draft behavior', () => {
|
||||
@@ -309,10 +367,49 @@ describe('github', () => {
|
||||
owner: 'owner',
|
||||
repo: 'repo',
|
||||
release_id: release.id,
|
||||
make_latest: undefined,
|
||||
discussion_category_name: undefined,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it('passes discussion_category_name through when finalizing a draft release', async () => {
|
||||
const finalizeReleaseSpy = vi.fn(async () => ({ data: finalizedRelease }));
|
||||
|
||||
const releaser: Releaser = {
|
||||
getReleaseByTag: () => Promise.reject('Not implemented'),
|
||||
createRelease: () => Promise.reject('Not implemented'),
|
||||
updateRelease: () => Promise.reject('Not implemented'),
|
||||
finalizeRelease: finalizeReleaseSpy,
|
||||
allReleases: async function* () {
|
||||
throw new Error('Not implemented');
|
||||
},
|
||||
listReleaseAssets: () => Promise.reject('Not implemented'),
|
||||
deleteReleaseAsset: () => Promise.reject('Not implemented'),
|
||||
deleteRelease: () => Promise.reject('Not implemented'),
|
||||
updateReleaseAsset: () => Promise.reject('Not implemented'),
|
||||
uploadReleaseAsset: () => Promise.reject('Not implemented'),
|
||||
};
|
||||
|
||||
await finalizeRelease(
|
||||
{
|
||||
...config,
|
||||
input_draft: false,
|
||||
input_discussion_category_name: 'Announcements',
|
||||
},
|
||||
releaser,
|
||||
draftRelease,
|
||||
);
|
||||
|
||||
expect(finalizeReleaseSpy).toHaveBeenCalledWith({
|
||||
owner: 'owner',
|
||||
repo: 'repo',
|
||||
release_id: draftRelease.id,
|
||||
make_latest: undefined,
|
||||
discussion_category_name: 'Announcements',
|
||||
});
|
||||
});
|
||||
|
||||
it('deletes a newly created draft when tag creation is blocked by repository rules', async () => {
|
||||
const finalizeReleaseSpy = vi.fn(async () => {
|
||||
throw {
|
||||
|
||||
Vendored
+2
-2
@@ -49,10 +49,10 @@ ${o}`;break;case"retry":SB(o)&&(s[i]=o);break;case"id":UB(o)&&(s[i]=o);break;cas
|
||||
globstar while`,e,l,t,p,g),this.matchOne(e.slice(l),t.slice(p),s))return this.debug("globstar found match!",l,a,g),!0;if(g==="."||g===".."||!r.dot&&g.charAt(0)==="."){this.debug("dot detected!",e,l,t,p);break}this.debug("globstar swallow a segment, and continue"),l++}return!!(s&&(this.debug(`
|
||||
>>> no match, partial?`,e,l,t,p),l===a))}let h;if(typeof c=="string"?(h=u===c,this.debug("string match",c,u,h)):(h=c.test(u),this.debug("pattern match",c,u,h)),!h)return!1}if(o===a&&n===A)return!0;if(o===a)return s;if(n===A)return o===a-1&&e[o]==="";throw new Error("wtf?")}braceExpand(){return PI(this.pattern,this.options)}parse(e){Ja(e);let t=this.options;if(e==="**")return be;if(e==="")return"";let s,r=null;(s=e.match(RL))?r=t.dot?FL:TL:(s=e.match(BL))?r=(t.nocase?t.dot?bL:wL:t.dot?IL:CL)(s[1]):(s=e.match(SL))?r=(t.nocase?t.dot?NL:UL:t.dot?GL:ML)(s):(s=e.match(yL))?r=t.dot?vL:xL:(s=e.match(kL))&&(r=DL);let i=LI.fromGlob(e,this.options).toMMPattern();return r&&typeof i=="object"&&Reflect.defineProperty(i,"test",{value:r}),i}makeRe(){if(this.regexp||this.regexp===!1)return this.regexp;let e=this.set;if(!e.length)return this.regexp=!1,this.regexp;let t=this.options,s=t.noglobstar?YL:t.dot?OL:JL,r=new Set(t.nocase?["i"]:[]),i=e.map(a=>{let A=a.map(u=>{if(u instanceof RegExp)for(let l of u.flags.split(""))r.add(l);return typeof u=="string"?WL(u):u===be?be:u._src});A.forEach((u,l)=>{let p=A[l+1],g=A[l-1];u!==be||g===be||(g===void 0?p!==void 0&&p!==be?A[l+1]="(?:\\/|"+s+"\\/)?"+p:A[l]=s:p===void 0?A[l-1]=g+"(?:\\/|\\/"+s+")?":p!==be&&(A[l-1]=g+"(?:\\/|\\/"+s+"\\/)"+p,A[l+1]=be))});let c=A.filter(u=>u!==be);if(this.partial&&c.length>=1){let u=[];for(let l=1;l<=c.length;l++)u.push(c.slice(0,l).join("/"));return"(?:"+u.join("|")+")"}return c.join("/")}).join("|"),[o,n]=e.length>1?["(?:",")"]:["",""];i="^"+o+i+n+"$",this.partial&&(i="^(?:\\/|"+o+i.slice(1,-1)+n+")$"),this.negate&&(i="^(?!"+i+").+$");try{this.regexp=new RegExp(i,[...r].join(""))}catch{this.regexp=!1}return this.regexp}slashSplit(e){return this.preserveMultipleSlashes?e.split("/"):this.isWindows&&/^\/\/[^\/]+/.test(e)?["",...e.split(/\/+/)]:e.split(/\/+/)}match(e,t=this.partial){if(this.debug("match",e,this.pattern),this.comment)return!1;if(this.empty)return e==="";if(e==="/"&&t)return!0;let s=this.options;this.isWindows&&(e=e.split("\\").join("/"));let r=this.slashSplit(e);this.debug(this.pattern,"split",r);let i=this.set;this.debug(this.pattern,"set",i);let o=r[r.length-1];if(!o)for(let n=r.length-2;!o&&n>=0;n--)o=r[n];for(let n=0;n<i.length;n++){let a=i[n],A=r;if(s.matchBase&&a.length===1&&(A=[o]),this.matchOne(A,a,t))return s.flipNegate?!0:!this.negate}return s.flipNegate?!1:this.negate}static defaults(e){return ye.defaults(e).Minimatch}};ye.AST=LI;ye.Minimatch=fs;ye.escape=_I;ye.unescape=Xr;var jL=typeof performance=="object"&&performance&&typeof performance.now=="function"?performance:Date,VI=new Set,ep=typeof process=="object"&&process?process:{},qI=(e,t,s,r)=>{typeof ep.emitWarning=="function"?ep.emitWarning(e,t,s,r):console.error(`[${s}] ${t}: ${e}`)},Pa=globalThis.AbortController,EI=globalThis.AbortSignal;if(typeof Pa>"u"){EI=class{onabort;_onabort=[];reason;aborted=!1;addEventListener(s,r){this._onabort.push(r)}},Pa=class{constructor(){t()}signal=new EI;abort(s){if(!this.signal.aborted){this.signal.reason=s,this.signal.aborted=!0;for(let r of this.signal._onabort)r(s);this.signal.onabort?.(s)}}};let e=ep.env?.LRU_CACHE_IGNORE_AC_WARNING!=="1",t=()=>{e&&(e=!1,qI("AbortController is not defined. If using lru-cache in node 14, load an AbortController polyfill from the `node-abort-controller` package. A minimal polyfill is provided for use by LRUCache.fetch(), but it should not be relied upon in other contexts (eg, passing it to other APIs that use AbortController/AbortSignal might have undesirable effects). You may disable this with LRU_CACHE_IGNORE_AC_WARNING=1 in the env.","NO_ABORT_CONTROLLER","ENOTSUP",t))}}var zL=e=>!VI.has(e),ms=e=>e&&e===Math.floor(e)&&e>0&&isFinite(e),WI=e=>ms(e)?e<=Math.pow(2,8)?Uint8Array:e<=Math.pow(2,16)?Uint16Array:e<=Math.pow(2,32)?Uint32Array:e<=Number.MAX_SAFE_INTEGER?Ya:null:null,Ya=class extends Array{constructor(e){super(e),this.fill(0)}},ZL=class po{heap;length;static#e=!1;static create(t){let s=WI(t);if(!s)return[];po.#e=!0;let r=new po(t,s);return po.#e=!1,r}constructor(t,s){if(!po.#e)throw new TypeError("instantiate Stack using Stack.create(n)");this.heap=new s(t),this.length=0}push(t){this.heap[this.length++]=t}pop(){return this.heap[--this.length]}},Va=class jI{#e;#t;#i;#s;#r;#A;#a;#c;get perf(){return this.#c}ttl;ttlResolution;ttlAutopurge;updateAgeOnGet;updateAgeOnHas;allowStale;noDisposeOnSet;noUpdateTTL;maxEntrySize;sizeCalculation;noDeleteOnFetchRejection;noDeleteOnStaleGet;allowStaleOnFetchAbort;allowStaleOnFetchRejection;ignoreFetchAbort;#l;#g;#h;#u;#n;#d;#C;#B;#E;#k;#m;#b;#y;#f;#Q;#I;#x;#o;#U;static unsafeExposeInternals(t){return{starts:t.#y,ttls:t.#f,autopurgeTimers:t.#Q,sizes:t.#b,keyMap:t.#h,keyList:t.#u,valList:t.#n,next:t.#d,prev:t.#C,get head(){return t.#B},get tail(){return t.#E},free:t.#k,isBackgroundFetch:s=>t.#p(s),backgroundFetch:(s,r,i,o)=>t.#J(s,r,i,o),moveToTail:s=>t.#G(s),indexes:s=>t.#R(s),rindexes:s=>t.#T(s),isStale:s=>t.#w(s)}}get max(){return this.#e}get maxSize(){return th
Line truncated
|
||||
|
||||
${i.data.body}`:r.body=i.data.body}return r.body=r.body?this.truncateReleaseNotes(r.body):void 0,r}truncateReleaseNotes(t){return t.substring(0,124999)}async createRelease(t){return this.github.rest.repos.createRelease(await this.prepareReleaseMutation(t))}async updateRelease(t){return this.github.rest.repos.updateRelease(await this.prepareReleaseMutation(t))}async finalizeRelease(t){return await this.github.rest.repos.updateRelease({owner:t.owner,repo:t.repo,release_id:t.release_id,draft:!1,make_latest:t.make_latest})}allReleases(t){let s={per_page:100,...t};return this.github.paginate.iterator(this.github.rest.repos.listReleases.endpoint.merge(s))}async listReleaseAssets(t){return this.github.paginate(this.github.rest.repos.listReleaseAssets,{...t,per_page:100})}async deleteReleaseAsset(t){await this.github.rest.repos.deleteReleaseAsset(t)}async deleteRelease(t){await this.github.rest.repos.deleteRelease(t)}async updateReleaseAsset(t){return await this.github.rest.repos.updateReleaseAsset(t)}async uploadReleaseAsset(t){return this.github.request({method:"POST",url:t.url,headers:{"content-length":`${t.size}`,"content-type":t.mime,authorization:`token ${t.token}`},data:t.data})}},N_=e=>({name:(0,Rw.basename)(e),mime:G_(e),size:(0,vw.statSync)(e).size}),G_=e=>(0,Dw.lookup)(e)||"application/octet-stream",cp=(e,t)=>t.name===e||t.name===yw(e)||t.label===e,M_=e=>{let t=e?.status??e?.response?.status,s=e?.request?.url,r=e?.message,i=typeof s=="string"&&(/\/releases\/assets\//.test(s)||/\/releases\/\d+\/assets(?:\?|$)/.test(s));return t===404&&(i||typeof r=="string"&&r.includes("update-a-release-asset"))},L_=e=>{let t=e?.status??e?.response?.status,s=e?.response?.data?.message??e?.message;return t===422&&/immutable release/i.test(String(s))},__=(e,t)=>t?`Cannot upload asset ${e} to an immutable release. GitHub only allows asset uploads before a release is published, but draft prereleases publish with the release.published event instead of release.prereleased. If you need prereleases with assets on an immutable-release repository, keep the release as a draft with draft: true, then publish it later from that draft and subscribe downstream workflows to release.published.`:`Cannot upload asset ${e} to an immutable release. GitHub only allows asset uploads before a release is published, so upload assets to a draft release before you publish it.`,Tw=async(e,t,s,r,i)=>{let[o,n]=e.github_repository.split("/"),{name:a,mime:A,size:c}=N_(r),u=s.match(/\/releases\/(\d+)\/assets/),l=u?Number(u[1]):void 0,p=i.find(m=>cp(a,m));if(p){if(e.input_overwrite_files===!1)return console.log(`Asset ${a} already exists and overwrite_files is false...`),null;console.log(`\u267B\uFE0F Deleting previously uploaded asset ${a}...`),await t.deleteReleaseAsset({asset_id:p.id||1,owner:o,repo:n})}console.log(`\u2B06\uFE0F Uploading ${a}...`);let g=new URL(s);g.searchParams.append("name",a);let h=async(m,C=3)=>{if(l!==void 0)for(let B=1;B<=C;B++){let S=(await t.listReleaseAssets({owner:o,repo:n,release_id:l})).find(m);if(S)return S;B<C&&await new Promise(G=>setTimeout(G,1e3))}},E=async()=>{let m=await(0,kw.open)(r);try{return await t.uploadReleaseAsset({url:g.toString(),size:c,mime:A,token:e.github_token,data:m.readableWebStream({type:"bytes"})})}finally{await m.close()}},f=async m=>{if(!m.name||m.name===a||!m.id)return m;console.log(`\u270F\uFE0F Restoring asset label to ${a}...`);let C=async B=>{let{data:b}=await t.updateReleaseAsset({owner:o,repo:n,asset_id:B,name:m.name,label:a});return b};try{return await C(m.id)}catch(B){if((B?.status??B?.response?.status)===404&&l!==void 0)try{let S=await h(G=>G.id===m.id||G.name===m.name);if(S)return await C(S.id)}catch(S){console.warn(`error refreshing release assets for ${a}: ${S}`)}return console.warn(`error updating release asset label for ${a}: ${B}`),m}},d=async m=>{let C=m.data;if(m.status!==201)throw new Error(`Failed to upload release asset ${a}. received status code ${m.status}
|
||||
${i.data.body}`:r.body=i.data.body}return r.body=r.body?this.truncateReleaseNotes(r.body):void 0,r}truncateReleaseNotes(t){return t.substring(0,124999)}async createRelease(t){return this.github.rest.repos.createRelease(await this.prepareReleaseMutation(t))}async updateRelease(t){return this.github.rest.repos.updateRelease(await this.prepareReleaseMutation(t))}async finalizeRelease(t){return await this.github.rest.repos.updateRelease({owner:t.owner,repo:t.repo,release_id:t.release_id,draft:!1,make_latest:t.make_latest,discussion_category_name:t.discussion_category_name})}allReleases(t){let s={per_page:100,...t};return this.github.paginate.iterator(this.github.rest.repos.listReleases.endpoint.merge(s))}async listReleaseAssets(t){return this.github.paginate(this.github.rest.repos.listReleaseAssets,{...t,per_page:100})}async deleteReleaseAsset(t){await this.github.rest.repos.deleteReleaseAsset(t)}async deleteRelease(t){await this.github.rest.repos.deleteRelease(t)}async updateReleaseAsset(t){return await this.github.rest.repos.updateReleaseAsset(t)}async uploadReleaseAsset(t){return this.github.request({method:"POST",url:t.url,headers:{"content-length":`${t.size}`,"content-type":t.mime,authorization:`token ${t.token}`},data:t.data})}},N_=e=>({name:(0,Rw.basename)(e),mime:G_(e),size:(0,vw.statSync)(e).size}),G_=e=>(0,Dw.lookup)(e)||"application/octet-stream",cp=(e,t)=>t.name===e||t.name===yw(e)||t.label===e,M_=e=>{let t=e?.status??e?.response?.status,s=e?.request?.url,r=e?.message,i=typeof s=="string"&&(/\/releases\/assets\//.test(s)||/\/releases\/\d+\/assets(?:\?|$)/.test(s));return t===404&&(i||typeof r=="string"&&r.includes("update-a-release-asset"))},L_=e=>{let t=e?.status??e?.response?.status,s=e?.response?.data?.message??e?.message;return t===422&&/immutable release/i.test(String(s))},__=(e,t)=>t?`Cannot upload asset ${e} to an immutable release. GitHub only allows asset uploads before a release is published, but draft prereleases publish with the release.published event instead of release.prereleased. If you need prereleases with assets on an immutable-release repository, keep the release as a draft with draft: true, then publish it later from that draft and subscribe downstream workflows to release.published.`:`Cannot upload asset ${e} to an immutable release. GitHub only allows asset uploads before a release is published, so upload assets to a draft release before you publish it.`,Tw=async(e,t,s,r,i)=>{let[o,n]=e.github_repository.split("/"),{name:a,mime:A,size:c}=N_(r),u=s.match(/\/releases\/(\d+)\/assets/),l=u?Number(u[1]):void 0,p=i.find(m=>cp(a,m));if(p){if(e.input_overwrite_files===!1)return console.log(`Asset ${a} already exists and overwrite_files is false...`),null;console.log(`\u267B\uFE0F Deleting previously uploaded asset ${a}...`),await t.deleteReleaseAsset({asset_id:p.id||1,owner:o,repo:n})}console.log(`\u2B06\uFE0F Uploading ${a}...`);let g=new URL(s);g.searchParams.append("name",a);let h=async(m,C=3)=>{if(l!==void 0)for(let B=1;B<=C;B++){let S=(await t.listReleaseAssets({owner:o,repo:n,release_id:l})).find(m);if(S)return S;B<C&&await new Promise(G=>setTimeout(G,1e3))}},E=async()=>{let m=await(0,kw.open)(r);try{return await t.uploadReleaseAsset({url:g.toString(),size:c,mime:A,token:e.github_token,data:m.readableWebStream({type:"bytes"})})}finally{await m.close()}},f=async m=>{if(!m.name||m.name===a||!m.id)return m;console.log(`\u270F\uFE0F Restoring asset label to ${a}...`);let C=async B=>{let{data:b}=await t.updateReleaseAsset({owner:o,repo:n,asset_id:B,name:m.name,label:a});return b};try{return await C(m.id)}catch(B){if((B?.status??B?.response?.status)===404&&l!==void 0)try{let S=await h(G=>G.id===m.id||G.name===m.name);if(S)return await C(S.id)}catch(S){console.warn(`error refreshing release assets for ${a}: ${S}`)}return console.warn(`error updating release asset label for ${a}: ${B}`),m}},d=async m=>{let C=m.data;if(m.status!==201)throw new Error(`Failed to upload release asset ${a}. received status code ${m.status}
|
||||
${C.message}
|
||||
${JSON.stringify(C.errors)}`);let B=await f(C);return console.log(`\u2705 Uploaded ${a}`),B};try{return await d(await E())}catch(m){let C=m?.status??m?.response?.status,B=m?.response?.data;if(L_(m))throw new Error(__(a,e.input_prerelease));if(l!==void 0&&M_(m))try{let b=await h(S=>cp(a,S));if(b)return console.warn(`error updating release asset metadata for ${a}: ${m}. Matching asset is present after refresh; continuing...`),b}catch(b){console.warn(`error refreshing release assets after metadata update failure: ${b}`)}if(e.input_overwrite_files!==!1&&C===422&&B?.errors?.[0]?.code==="already_exists"&&l!==void 0){console.log(`\u26A0\uFE0F Asset ${a} already exists (race condition), refreshing assets and retrying once...`);let S=(await t.listReleaseAssets({owner:o,repo:n,release_id:l})).find(G=>cp(a,G));if(S)return await t.deleteReleaseAsset({owner:o,repo:n,asset_id:S.id}),await d(await E())}throw m}},lp=async(e,t,s=3)=>{if(s<=0)throw console.log("\u274C Too many retries. Aborting..."),new Error("Too many retries.");let[r,i]=e.github_repository.split("/"),o=Ap(e.input_tag_name)||(fo(e.github_ref)?e.github_ref.replace("refs/tags/",""):""),n=e.input_discussion_category_name,a=e.input_generate_release_notes,A=e.input_previous_tag;a&&A&&console.log(`\u{1F4DD} Generating release notes using previous tag ${A}`);try{let c=await Fw(t,r,i,o);if(c===void 0)return await xw(o,e,t,r,i,n,a,s,A);let u=c;console.log(`Found release ${u.name} (with id=${u.id})`);let l=u.id,p;e.input_target_commitish&&e.input_target_commitish!==u.target_commitish?(console.log(`Updating commit from "${u.target_commitish}" to "${e.input_target_commitish}"`),p=e.input_target_commitish):p=u.target_commitish;let g=o,h=e.input_name||u.name||o,E=ap(e)||"",f=u.body||"",d;e.input_append_body&&E&&f?d=f+`
|
||||
`+E:d=E||f;let m=e.input_prerelease!==void 0?e.input_prerelease:u.prerelease,C=e.input_make_latest;return{release:(await t.updateRelease({owner:r,repo:i,release_id:l,tag_name:g,target_commitish:p,name:h,body:d,draft:u.draft,prerelease:m,discussion_category_name:n,generate_release_notes:a,make_latest:C,previous_tag_name:A})).data,created:!1}}catch(c){if(c.status!==404)throw console.log(`\u26A0\uFE0F Unexpected error fetching GitHub release for tag ${e.github_ref}: ${c}`),c;return await xw(o,e,t,r,i,n,a,s,A)}},up=async(e,t,s,r=!1,i=3)=>{if(e.input_draft===!0||s.draft===!1)return s;if(i<=0)throw console.log("\u274C Too many retries. Aborting..."),new Error("Too many retries.");let[o,n]=e.github_repository.split("/");try{let{data:a}=await t.finalizeRelease({owner:o,repo:n,release_id:s.id,make_latest:e.input_make_latest});return a}catch(a){if(console.warn(`error finalizing release: ${a}`),r&&s.draft&&W_(a)){let A=!1;try{console.log(`\u{1F9F9} Deleting draft release ${s.id} for tag ${s.tag_name} because tag creation is blocked by repository rules...`),await t.deleteRelease({owner:o,repo:n,release_id:s.id}),A=!0}catch(u){console.warn(`error deleting orphan draft release ${s.id}: ${u}`)}let c=A?`Deleted draft release ${s.id} to avoid leaving an orphaned draft release.`:`Failed to delete draft release ${s.id}; manual cleanup may still be required.`;throw new Error(`Tag creation for ${s.tag_name} is blocked by repository rules. ${c}`)}return console.log(`retrying... (${i-1} retries remaining)`),up(e,t,s,r,i-1)}},pp=async(e,t,s,r=3)=>{if(r<=0)throw console.log("\u274C Too many retries. Aborting..."),new Error("Too many retries.");let[i,o]=e.github_repository.split("/");try{return await t.listReleaseAssets({owner:i,repo:o,release_id:s.id})}catch(n){return console.warn(`error listing assets of release: ${n}`),console.log(`retrying... (${r-1} retries remaining)`),pp(e,t,s,r-1)}};async function Fw(e,t,s,r){try{let{data:i}=await e.getReleaseByTag({owner:t,repo:s,tag:r});return i}catch(i){if(i.status===404)return;throw i}}var Y_=1e3,O_=2;async function J_(e){await new Promise(t=>setTimeout(t,e))}async function P_(e,t,s,r){let i=[],o=0;for await(let n of e.allReleases({owner:t,repo:s}))if(i.push(...n.data.filter(a=>a.tag_name===r)),o+=1,o>=O_)break;return i}function H_(e,t){return t&&e.some(s=>s.id===t.id)||e.length===0?t:[...e].sort((s,r)=>s.draft!==r.draft?Number(s.draft)-Number(r.draft):s.id-r.id)[0]}async function V_(e,t,s,r,i,o){let n=Array.from(new Map(o.map(a=>[a.id,a])).values());for(let a of n)if(!(a.id===i||!a.draft||a.assets.length>0))try{console.log(`\u{1F9F9} Removing duplicate draft release ${a.id} for tag ${r}...`),await e.deleteRelease({owner:t,repo:s,release_id:a.id})}catch(A){console.warn(`error deleting duplicate release ${a.id}: ${A}`)}}async function q_(e,t,s,r,i,o){let n=Math.max(o,1);for(let a=1;a<=n;a+=1){let A;try{A=await Fw(e,t,s,r)}catch(l){console.warn(`error reloading release for tag ${r}: ${l}`)}let c=[];try{c=await P_(e,t,s,r)}catch(l){console.warn(`error listing recent releases for tag ${r}: ${l}`)}let u=H_(c,A);if(u)return u.id!==i.id&&console.log(`\u21AA\uFE0F Using release ${u.id} for tag ${r} instead of duplicate draft ${i.id}`),await V_(e,t,s,r,u.id,[i,...c]),u;a<n&&(console.log(`Release ${i.id} is not yet discoverable by tag ${r}, retrying... (${n-a} retries remaining)`),await J_(Y_))}return console.log(`\u26A0\uFE0F Continuing with newly created release ${i.id} because tag ${r} is still not discoverable`),i}async function xw(e,t,s,r,i,o,n,a,A){let c=e,u=t.input_name||e,l=ap(t),p=t.input_prerelease,g=p===!0?t.input_draft===!0:!0,h=t.input_target_commitish,E=t.input_make_latest,f="";h&&(f=` using commit "${h}"`),console.log(`\u{1F469}\u200D\u{1F3ED} Creating new GitHub release for tag ${c}${f}...`);try{let d=await s.createRelease({owner:r,repo:i,tag_name:c,name:u,body:l,draft:g,prerelease:p,target_commitish:h,discussion_category_name:o,generate_release_notes:n,make_latest:E,previous_tag_name:A}),m=await q_(s,r,i,c,d.data,a);return{release:m,created:m.id===d.data.id}}catch(d){switch(console.log(`\u26A0\uFE0F GitHub release failed with status: ${d.status}`),console.log(`${JSON.stringify(d.response.data)}`),d.status){case 403:throw console.log("Skip retry \u2014 your GitHub token/PAT does not have the required permission to create a release"),d;case 404:throw console.log("Skip retry - discussion category mismatch"),d;case 422:if(d.response?.data?.errors?.[0]?.code==="already_exists")console.log("\u26A0\uFE0F Release already exists (race condition detected), retrying to find and update existing release...");else throw console.log("Skip retry - validation failed"),d;break}return console.log(`retrying... (${a-1} retries remaining)`),lp(t,s,a-1)}}function W_(e){let t=e?.response?.data?.errors;return!Array.isArray(t)||e?.status!==422?!1:t.some(({field:s,message:r})=>s==="pre_receive"&&typeof r=="string"&&r.includes("creations being restricted"))}var Sw=require("process");async function j_(){try{
Line truncated
|
||||
`+E:d=E||f;let m=e.input_prerelease!==void 0?e.input_prerelease:u.prerelease,C=e.input_make_latest;return{release:(await t.updateRelease({owner:r,repo:i,release_id:l,tag_name:g,target_commitish:p,name:h,body:d,draft:u.draft,prerelease:m,discussion_category_name:n,generate_release_notes:a,make_latest:C,previous_tag_name:A})).data,created:!1}}catch(c){if(c.status!==404)throw console.log(`\u26A0\uFE0F Unexpected error fetching GitHub release for tag ${e.github_ref}: ${c}`),c;return await xw(o,e,t,r,i,n,a,s,A)}},up=async(e,t,s,r=!1,i=3)=>{if(e.input_draft===!0||s.draft===!1)return s;if(i<=0)throw console.log("\u274C Too many retries. Aborting..."),new Error("Too many retries.");let[o,n]=e.github_repository.split("/");try{let{data:a}=await t.finalizeRelease({owner:o,repo:n,release_id:s.id,make_latest:e.input_make_latest,discussion_category_name:e.input_discussion_category_name});return a}catch(a){if(console.warn(`error finalizing release: ${a}`),r&&s.draft&&W_(a)){let A=!1;try{console.log(`\u{1F9F9} Deleting draft release ${s.id} for tag ${s.tag_name} because tag creation is blocked by repository rules...`),await t.deleteRelease({owner:o,repo:n,release_id:s.id}),A=!0}catch(u){console.warn(`error deleting orphan draft release ${s.id}: ${u}`)}let c=A?`Deleted draft release ${s.id} to avoid leaving an orphaned draft release.`:`Failed to delete draft release ${s.id}; manual cleanup may still be required.`;throw new Error(`Tag creation for ${s.tag_name} is blocked by repository rules. ${c}`)}return console.log(`retrying... (${i-1} retries remaining)`),up(e,t,s,r,i-1)}},pp=async(e,t,s,r=3)=>{if(r<=0)throw console.log("\u274C Too many retries. Aborting..."),new Error("Too many retries.");let[i,o]=e.github_repository.split("/");try{return await t.listReleaseAssets({owner:i,repo:o,release_id:s.id})}catch(n){return console.warn(`error listing assets of release: ${n}`),console.log(`retrying... (${r-1} retries remaining)`),pp(e,t,s,r-1)}};async function Fw(e,t,s,r){try{let{data:i}=await e.getReleaseByTag({owner:t,repo:s,tag:r});return i}catch(i){if(i.status===404)return;throw i}}var Y_=1e3,O_=2;async function J_(e){await new Promise(t=>setTimeout(t,e))}async function P_(e,t,s,r){let i=[],o=0;for await(let n of e.allReleases({owner:t,repo:s}))if(i.push(...n.data.filter(a=>a.tag_name===r)),o+=1,o>=O_)break;return i}function H_(e,t){return t&&e.some(s=>s.id===t.id)||e.length===0?t:[...e].sort((s,r)=>s.draft!==r.draft?Number(s.draft)-Number(r.draft):s.id-r.id)[0]}async function V_(e,t,s,r,i,o){let n=Array.from(new Map(o.map(a=>[a.id,a])).values());for(let a of n)if(!(a.id===i||!a.draft||a.assets.length>0))try{console.log(`\u{1F9F9} Removing duplicate draft release ${a.id} for tag ${r}...`),await e.deleteRelease({owner:t,repo:s,release_id:a.id})}catch(A){console.warn(`error deleting duplicate release ${a.id}: ${A}`)}}async function q_(e,t,s,r,i,o){let n=Math.max(o,1);for(let a=1;a<=n;a+=1){let A;try{A=await Fw(e,t,s,r)}catch(l){console.warn(`error reloading release for tag ${r}: ${l}`)}let c=[];try{c=await P_(e,t,s,r)}catch(l){console.warn(`error listing recent releases for tag ${r}: ${l}`)}let u=H_(c,A);if(u)return u.id!==i.id&&console.log(`\u21AA\uFE0F Using release ${u.id} for tag ${r} instead of duplicate draft ${i.id}`),await V_(e,t,s,r,u.id,[i,...c]),u;a<n&&(console.log(`Release ${i.id} is not yet discoverable by tag ${r}, retrying... (${n-a} retries remaining)`),await J_(Y_))}return console.log(`\u26A0\uFE0F Continuing with newly created release ${i.id} because tag ${r} is still not discoverable`),i}async function xw(e,t,s,r,i,o,n,a,A){let c=e,u=t.input_name||e,l=ap(t),p=t.input_prerelease,g=p===!0?t.input_draft===!0:!0,h=t.input_target_commitish,E=t.input_make_latest,f="";h&&(f=` using commit "${h}"`),console.log(`\u{1F469}\u200D\u{1F3ED} Creating new GitHub release for tag ${c}${f}...`);try{let d=await s.createRelease({owner:r,repo:i,tag_name:c,name:u,body:l,draft:g,prerelease:p,target_commitish:h,discussion_category_name:o,generate_release_notes:n,make_latest:E,previous_tag_name:A}),m=await q_(s,r,i,c,d.data,a);return{release:m,created:m.id===d.data.id}}catch(d){switch(console.log(`\u26A0\uFE0F GitHub release failed with status: ${d.status}`),console.log(`${JSON.stringify(d.response.data)}`),d.status){case 403:throw console.log("Skip retry \u2014 your GitHub token/PAT does not have the required permission to create a release"),d;case 404:throw console.log("Skip retry - discussion category mismatch"),d;case 422:if(d.response?.data?.errors?.[0]?.code==="already_exists")console.log("\u26A0\uFE0F Release already exists (race condition detected), retrying to find and update existing release...");else throw console.log("Skip retry - validation failed"),d;break}return console.log(`retrying... (${a-1} retries remaining)`),lp(t,s,a-1)}}function W_(e){let t=e?.response?.data?.errors;return!Array.isArray(t)||e?.status!==422?!1:t.some(({field:s,message:r})=>s==="pre_receive"&&typeof r=="string"&&r.includes("creations being restri
Line truncated
|
||||
/*! Bundled license information:
|
||||
|
||||
undici/lib/web/fetch/body.js:
|
||||
|
||||
@@ -71,6 +71,7 @@ export interface Releaser {
|
||||
repo: string;
|
||||
release_id: number;
|
||||
make_latest: 'true' | 'false' | 'legacy' | undefined;
|
||||
discussion_category_name: string | undefined;
|
||||
}): Promise<{ data: Release }>;
|
||||
|
||||
allReleases(params: { owner: string; repo: string }): AsyncIterable<{ data: Release[] }>;
|
||||
@@ -181,6 +182,7 @@ export class GitHubReleaser implements Releaser {
|
||||
repo: string;
|
||||
release_id: number;
|
||||
make_latest: 'true' | 'false' | 'legacy' | undefined;
|
||||
discussion_category_name: string | undefined;
|
||||
}) {
|
||||
return await this.github.rest.repos.updateRelease({
|
||||
owner: params.owner,
|
||||
@@ -188,6 +190,7 @@ export class GitHubReleaser implements Releaser {
|
||||
release_id: params.release_id,
|
||||
draft: false,
|
||||
make_latest: params.make_latest,
|
||||
discussion_category_name: params.discussion_category_name,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -641,6 +644,7 @@ export const finalizeRelease = async (
|
||||
repo,
|
||||
release_id: release.id,
|
||||
make_latest: config.input_make_latest,
|
||||
discussion_category_name: config.input_discussion_category_name,
|
||||
});
|
||||
|
||||
return data;
|
||||
|
||||
Reference in new issue
Block a user