feat: mark release as draft until all artifacts are uploaded (#692)

Previously, the releases were created and then artifacts (if any)
were added to them. This broke when GitHub released "immutable"
releases, which disallow changes after the release is published.

Make it so that releases are always marked as "draft" when being
worked on by the action, and unmarked as draft (if desired) once
the action is completed.

Fixes #653
This commit is contained in:
jj authored and GitHub committed 2025-12-01 00:59:24 -05:00
1 parent 87973286a4
commit 7da8983734
4 files changed
+67 -8

No files matched your search

+3 -1
View File
@@ -49,6 +49,7 @@ describe('github', () => {
getReleaseByTag: () => Promise.reject('Not implemented'),
createRelease: () => Promise.reject('Not implemented'),
updateRelease: () => Promise.reject('Not implemented'),
finalizeRelease: () => Promise.reject('Not implemented'),
allReleases: async function* () {
yield { data: [mockRelease] };
},
@@ -254,11 +255,12 @@ describe('github', () => {
name: 'test',
body: 'test',
target_commitish: 'main',
draft: false,
draft: true,
prerelease: false,
assets: [],
},
}),
finalizeRelease: async () => {},
allReleases: async function* () {
yield {
data: [
+1 -1
View File
@@ -13,4 +13,4 @@ e.exports=s(1813)},4096:(e,t,s)=>{"use strict";
* MIT Licensed
*/var i=s(9829);var A=s(6928).extname;var o=s(4062);var r=/^\s*([^;\s]*)(?:;|\s|$)/;var n=/^text\//i;t.charset=charset;t.charsets={lookup:charset};t.contentType=contentType;t.extension=extension;t.extensions=Object.create(null);t.lookup=lookup;t.types=Object.create(null);t._extensionConflicts=[];populateMaps(t.extensions,t.types);function charset(e){if(!e||typeof e!=="string"){return false}var t=r.exec(e);var s=t&&i[t[1].toLowerCase()];if(s&&s.charset){return s.charset}if(t&&n.test(t[1])){return"UTF-8"}return false}function contentType(e){if(!e||typeof e!=="string"){return false}var s=e.indexOf("/")===-1?t.lookup(e):e;if(!s){return false}if(s.indexOf("charset")===-1){var i=t.charset(s);if(i)s+="; charset="+i.toLowerCase()}return s}function extension(e){if(!e||typeof e!=="string"){return false}var s=r.exec(e);var i=s&&t.extensions[s[1].toLowerCase()];if(!i||!i.length){return false}return i[0]}function lookup(e){if(!e||typeof e!=="string"){return false}var s=A("x."+e).toLowerCase().slice(1);if(!s){return false}return t.types[s]||false}function populateMaps(e,s){Object.keys(i).forEach((function forEachMimeType(A){var o=i[A];var r=o.extensions;if(!r||!r.length){return}e[A]=r;for(var n=0;n<r.length;n++){var a=r[n];s[a]=_preferredType(a,s[a],A);const e=_preferredTypeLegacy(a,s[a],A);if(e!==s[a]){t._extensionConflicts.push([a,e,s[a]])}}}))}function _preferredType(e,t,s){var A=t?o(t,i[t].source):0;var r=s?o(s,i[s].source):0;return A>r?t:s}function _preferredTypeLegacy(e,s,A){var o=["nginx","apache",undefined,"iana"];var r=s?o.indexOf(i[s].source):0;var n=A?o.indexOf(i[A].source):0;if(t.types[extension]!=="application/octet-stream"&&(r>n||r===n&&t.types[extension]?.slice(0,12)==="application/")){return s}return r>n?s:A}},4062:e=>{var t={"prs.":100,"x-":200,"x.":300,"vnd.":400,default:900};var s={nginx:10,apache:20,iana:40,default:30};var i={application:1,font:2,default:0};e.exports=function mimeScore(e,A="default"){if(e==="application/octet-stream"){return 0}const[o,r]=e.split("/");const n=r.replace(/(\.|x-).*/,"$1");const a=t[n]||t.default;const c=s[A]||s.default;const l=i[o]||i.default;const u=1-e.length/100;return a+c+l+u}},5560:(e,t,s)=>{var i=s(8264);e.exports=i(once);e.exports.strict=i(onceStrict);once.proto=once((function(){Object.defineProperty(Function.prototype,"once",{value:function(){return once(this)},configurable:true});Object.defineProperty(Function.prototype,"onceStrict",{value:function(){return onceStrict(this)},configurable:true})}));function once(e){var f=function(){if(f.called)return f.value;f.called=true;return f.value=e.apply(this,arguments)};f.called=false;return f}function onceStrict(e){var f=function(){if(f.called)throw new Error(f.onceError);f.called=true;return f.value=e.apply(this,arguments)};var t=e.name||"Function wrapped with `once`";f.onceError=t+" shouldn't be called more than once";f.called=false;return f}},770:(e,t,s)=>{e.exports=s(218)},218:(e,t,s)=>{"use strict";var i=s(9278);var A=s(4756);var o=s(8611);var r=s(5692);var n=s(4434);var a=s(2613);var c=s(9023);t.httpOverHttp=httpOverHttp;t.httpsOverHttp=httpsOverHttp;t.httpOverHttps=httpOverHttps;t.httpsOverHttps=httpsOverHttps;function httpOverHttp(e){var t=new TunnelingAgent(e);t.request=o.request;return t}function httpsOverHttp(e){var t=new TunnelingAgent(e);t.request=o.request;t.createSocket=createSecureSocket;t.defaultPort=443;return t}function httpOverHttps(e){var t=new TunnelingAgent(e);t.request=r.request;return t}function httpsOverHttps(e){var t=new TunnelingAgent(e);t.request=r.request;t.createSocket=createSecureSocket;t.defaultPort=443;return t}function TunnelingAgent(e){var t=this;t.options=e||{};t.proxyOptions=t.options.proxy||{};t.maxSockets=t.options.maxSockets||o.Agent.defaultMaxSockets;t.requests=[];t.sockets=[];t.on("free",(function onFree(e,s,i,A){var o=toOptions(s,i,A);for(var r=0,n=t.requests.length;r<n;++r){var a=t.requests[r];if(a.host===o.host&&a.port===o.port){t.requests.splice(r,1);a.request.onSocket(e);return}}e.destroy();t.removeSocket(e)}))}c.inherits(TunnelingAgent,n.EventEmitter);TunnelingAgent.prototype.addRequest=function addRequest(e,t,s,i){var A=this;var o=mergeOptions({request:e},A.options,toOptions(t,s,i));if(A.sockets.length>=this.maxSockets){A.requests.push(o);return}A.createSocket(o,(function(t){t.on("free",onFree);t.on("close",onCloseOrRemove);t.on("agentRemove",onCloseOrRemove);e.onSocket(t);function onFree(){A.emit("free",t,o)}function onCloseOrRemove(e){A.removeSocket(t);t.removeListener("free",onFree);t.removeListener("close",onCloseOrRemove);t.removeListener("agentRemove",onCloseOrRemove)}}))};TunnelingAgent.prototype.createSocket=function createSocket(e,t){var s=this;var i={};s.sockets.push(i);var A=mergeOptions({},s.proxyOptions,{method:"CONNECT",path:e.host+":"+e.port,agent:false,headers:{host:e.host+":"+e.port}});if(e.localAddress){A.localAddress=e.localAddress}if(A.proxyAuth){A.headers=A.headers||{};A.headers["Proxy-Authorization"]="Basic "+new Buffer(A.proxyAuth).toString("base6Line truncated
/*! formdata-polyfill. MIT License. Jimmy Wärting <https://jimmy.warting.se/opensource> */;const escape=e=>e.replace(/\n/g,"%0A").replace(/\r/g,"%0D").replace(/"/g,"%22");const normalizeLinefeeds=e=>e.replace(/\r?\n|\r/g,"\r\n");const i=[];const A=new Uint8Array([13,10]);u=0;let o=false;for(const[t,r]of e){if(typeof r==="string"){const e=S.encode(s+`; name="${escape(normalizeLinefeeds(t))}"`+`\r\n\r\n${normalizeLinefeeds(r)}\r\n`);i.push(e);u+=e.byteLength}else{const e=S.encode(`${s}; name="${escape(normalizeLinefeeds(t))}"`+(r.name?`; filename="${escape(r.name)}"`:"")+"\r\n"+`Content-Type: ${r.type||"application/octet-stream"}\r\n\r\n`);i.push(e,r,A);if(typeof r.size==="number"){u+=e.byteLength+r.size+A.byteLength}else{o=true}}}const r=S.encode(`--${t}--`);i.push(r);u+=r.byteLength;if(o){u=null}l=e;c=async function*(){for(const e of i){if(e.stream){yield*e.stream()}else{yield e}}};p="multipart/form-data; boundary="+t}else if(r(e)){l=e;u=e.size;if(e.type){p=e.type}}else if(typeof e[Symbol.asyncIterator]==="function"){if(t){throw new TypeError("keepalive")}if(A.isDisturbed(e)||e.locked){throw new TypeError("Response body object should not be disturbed or locked")}i=e instanceof x?e:o(e)}if(typeof l==="string"||A.isBuffer(l)){u=Buffer.byteLength(l)}if(c!=null){let t;i=new x({async start(){t=c(e)[Symbol.asyncIterator]()},async pull(e){const{value:s,done:A}=await t.next();if(A){queueMicrotask((()=>{e.close()}))}else{if(!I(i)){e.enqueue(new Uint8Array(s))}}return e.desiredSize>0},async cancel(e){await t.return()},type:undefined})}const g={stream:i,source:l,length:u};return[g,p]}function safelyExtractBody(e,t=false){if(!x){x=s(3774).ReadableStream}if(e instanceof x){B(!A.isDisturbed(e),"The body has already been consumed.");B(!e.locked,"The stream is locked.")}return extractBody(e,t)}function cloneBody(e){const[t,s]=e.stream.tee();const i=h(s,{transfer:[s]});const[,A]=i.tee();e.stream=t;return{stream:A,length:e.length,source:e.source}}async function*consumeBody(e){if(e){if(b(e)){yield e}else{const t=e.stream;if(A.isDisturbed(t)){throw new TypeError("The body has already been consumed.")}if(t.locked){throw new TypeError("The stream is locked.")}t[C]=true;yield*t}}}function throwIfAborted(e){if(e.aborted){throw new d("The operation was aborted.","AbortError")}}function bodyMixinMethods(e){const t={blob(){return specConsumeBody(this,(e=>{let t=bodyMimeType(this);if(t==="failure"){t=""}else if(t){t=k(t)}return new E([e],{type:t})}),e)},arrayBuffer(){return specConsumeBody(this,(e=>new Uint8Array(e).buffer),e)},text(){return specConsumeBody(this,utf8DecodeBytes,e)},json(){return specConsumeBody(this,parseJSONFromBytes,e)},async formData(){g.brandCheck(this,e);throwIfAborted(this[p]);const t=this.headers.get("Content-Type");if(/multipart\/form-data/.test(t)){const e={};for(const[t,s]of this.headers)e[t.toLowerCase()]=s;const t=new u;let s;try{s=new i({headers:e,preservePath:true})}catch(e){throw new d(`${e}`,"AbortError")}s.on("field",((e,s)=>{t.append(e,s)}));s.on("file",((e,s,i,A,o)=>{const r=[];if(A==="base64"||A.toLowerCase()==="base64"){let A="";s.on("data",(e=>{A+=e.toString().replace(/[\r\n]/gm,"");const t=A.length-A.length%4;r.push(Buffer.from(A.slice(0,t),"base64"));A=A.slice(t)}));s.on("end",(()=>{r.push(Buffer.from(A,"base64"));t.append(e,new D(r,i,{type:o}))}))}else{s.on("data",(e=>{r.push(e)}));s.on("end",(()=>{t.append(e,new D(r,i,{type:o}))}))}}));const A=new Promise(((e,t)=>{s.on("finish",e);s.on("error",(e=>t(new TypeError(e))))}));if(this.body!==null)for await(const e of consumeBody(this[p].body))s.write(e);s.end();await A;return t}else if(/application\/x-www-form-urlencoded/.test(t)){let e;try{let t="";const s=new TextDecoder("utf-8",{ignoreBOM:true});for await(const e of consumeBody(this[p].body)){if(!b(e)){throw new TypeError("Expected Uint8Array chunk")}t+=s.decode(e,{stream:true})}t+=s.decode();e=new URLSearchParams(t)}catch(e){throw Object.assign(new TypeError,{cause:e})}const t=new u;for(const[s,i]of e){t.append(s,i)}return t}else{await Promise.resolve();throwIfAborted(this[p]);throw g.errors.exception({header:`${e.name}.formData`,message:"Could not parse content as FormData."})}}};return t}function mixinBody(e){Object.assign(e.prototype,bodyMixinMethods(e))}async function specConsumeBody(e,t,s){g.brandCheck(e,s);throwIfAborted(e[p]);if(bodyUnusable(e[p].body)){throw new TypeError("Body is unusable")}const i=c();const errorSteps=e=>i.reject(e);const successSteps=e=>{try{i.resolve(t(e))}catch(e){errorSteps(e)}};if(e[p].body==null){successSteps(new Uint8Array);return i.promise}await l(e[p].body,successSteps,errorSteps);return i.promise}function bodyUnusable(e){return e!=null&&(e.stream.locked||A.isDisturbed(e.stream))}function utf8DecodeBytes(e){if(e.length===0){return""}if(e[0]===239&&e[1]===187&&e[2]===191){e=e.subarray(3)}const t=F.decode(e);return t}function parseJSONFromBytes(e){return JSON.parse(utf8DecodeBytes(e))}function bodyMimeType(e){const{headersList:t}=e[p];const s=t.get("content-Line truncated
/*! ws. MIT License. Einar Otto Stangvik <einaros@gmail.com> */o[A-4]=this.maskKey[0];o[A-3]=this.maskKey[1];o[A-2]=this.maskKey[2];o[A-1]=this.maskKey[3];o[1]=s;if(s===126){o.writeUInt16BE(t,2)}else if(s===127){o[2]=o[3]=0;o.writeUIntBE(t,4,6)}o[1]|=128;for(let e=0;e<t;e++){o[A+e]=this.frameData[e]^this.maskKey[e%4]}return o}}e.exports={WebsocketFrameSend:WebsocketFrameSend}},3171:(e,t,s)=>{"use strict";const{Writable:i}=s(2203);const A=s(1637);const{parserStates:o,opcodes:r,states:n,emptyBuffer:a}=s(5913);const{kReadyState:c,kSentClose:l,kResponse:u,kReceivedClose:p}=s(2933);const{isValidStatusCode:g,failWebsocketConnection:d,websocketMessageReceived:h}=s(3574);const{WebsocketFrameSend:E}=s(1237);const Q={};Q.ping=A.channel("undici:websocket:ping");Q.pong=A.channel("undici:websocket:pong");class ByteParser extends i{#r=[];#n=0;#a=o.INFO;#c={};#l=[];constructor(e){super();this.ws=e}_write(e,t,s){this.#r.push(e);this.#n+=e.length;this.run(s)}run(e){while(true){if(this.#a===o.INFO){if(this.#n<2){return e()}const t=this.consume(2);this.#c.fin=(t[0]&128)!==0;this.#c.opcode=t[0]&15;this.#c.originalOpcode??=this.#c.opcode;this.#c.fragmented=!this.#c.fin&&this.#c.opcode!==r.CONTINUATION;if(this.#c.fragmented&&this.#c.opcode!==r.BINARY&&this.#c.opcode!==r.TEXT){d(this.ws,"Invalid frame type was fragmented.");return}const s=t[1]&127;if(s<=125){this.#c.payloadLength=s;this.#a=o.READ_DATA}else if(s===126){this.#a=o.PAYLOADLENGTH_16}else if(s===127){this.#a=o.PAYLOADLENGTH_64}if(this.#c.fragmented&&s>125){d(this.ws,"Fragmented frame exceeded 125 bytes.");return}else if((this.#c.opcode===r.PING||this.#c.opcode===r.PONG||this.#c.opcode===r.CLOSE)&&s>125){d(this.ws,"Payload length for control frame exceeded 125 bytes.");return}else if(this.#c.opcode===r.CLOSE){if(s===1){d(this.ws,"Received close frame with a 1-byte body.");return}const e=this.consume(s);this.#c.closeInfo=this.parseCloseBody(false,e);if(!this.ws[l]){const e=Buffer.allocUnsafe(2);e.writeUInt16BE(this.#c.closeInfo.code,0);const t=new E(e);this.ws[u].socket.write(t.createFrame(r.CLOSE),(e=>{if(!e){this.ws[l]=true}}))}this.ws[c]=n.CLOSING;this.ws[p]=true;this.end();return}else if(this.#c.opcode===r.PING){const t=this.consume(s);if(!this.ws[p]){const e=new E(t);this.ws[u].socket.write(e.createFrame(r.PONG));if(Q.ping.hasSubscribers){Q.ping.publish({payload:t})}}this.#a=o.INFO;if(this.#n>0){continue}else{e();return}}else if(this.#c.opcode===r.PONG){const t=this.consume(s);if(Q.pong.hasSubscribers){Q.pong.publish({payload:t})}if(this.#n>0){continue}else{e();return}}}else if(this.#a===o.PAYLOADLENGTH_16){if(this.#n<2){return e()}const t=this.consume(2);this.#c.payloadLength=t.readUInt16BE(0);this.#a=o.READ_DATA}else if(this.#a===o.PAYLOADLENGTH_64){if(this.#n<8){return e()}const t=this.consume(8);const s=t.readUInt32BE(0);if(s>2**31-1){d(this.ws,"Received payload length > 2^31 bytes.");return}const i=t.readUInt32BE(4);this.#c.payloadLength=(s<<8)+i;this.#a=o.READ_DATA}else if(this.#a===o.READ_DATA){if(this.#n<this.#c.payloadLength){return e()}else if(this.#n>=this.#c.payloadLength){const e=this.consume(this.#c.payloadLength);this.#l.push(e);if(!this.#c.fragmented||this.#c.fin&&this.#c.opcode===r.CONTINUATION){const e=Buffer.concat(this.#l);h(this.ws,this.#c.originalOpcode,e);this.#c={};this.#l.length=0}this.#a=o.INFO}}if(this.#n>0){continue}else{e();break}}}consume(e){if(e>this.#n){return null}else if(e===0){return a}if(this.#r[0].length===e){this.#n-=this.#r[0].length;return this.#r.shift()}const t=Buffer.allocUnsafe(e);let s=0;while(s!==e){const i=this.#r[0];const{length:A}=i;if(A+s===e){t.set(this.#r.shift(),s);break}else if(A+s>e){t.set(i.subarray(0,e-s),s);this.#r[0]=i.subarray(e-s);break}else{t.set(this.#r.shift(),s);s+=i.length}}this.#n-=e;return t}parseCloseBody(e,t){let s;if(t.length>=2){s=t.readUInt16BE(0)}if(e){if(!g(s)){return null}return{code:s}}let i=t.subarray(2);if(i[0]===239&&i[1]===187&&i[2]===191){i=i.subarray(3)}if(s!==undefined&&!g(s)){return null}try{i=new TextDecoder("utf-8",{fatal:true}).decode(i)}catch{return null}return{code:s,reason:i}}get closingInfo(){return this.#c.closeInfo}}e.exports={ByteParser:ByteParser}},2933:e=>{"use strict";e.exports={kWebSocketURL:Symbol("url"),kReadyState:Symbol("ready state"),kController:Symbol("controller"),kResponse:Symbol("response"),kBinaryType:Symbol("binary type"),kSentClose:Symbol("sent close"),kReceivedClose:Symbol("received close"),kByteParser:Symbol("byte parser")}},3574:(e,t,s)=>{"use strict";const{kReadyState:i,kController:A,kResponse:o,kBinaryType:r,kWebSocketURL:n}=s(2933);const{states:a,opcodes:c}=s(5913);const{MessageEvent:l,ErrorEvent:u}=s(6255);function isEstablished(e){return e[i]===a.OPEN}function isClosing(e){return e[i]===a.CLOSING}function isClosed(e){return e[i]===a.CLOSED}function fireEvent(e,t,s=Event,i){const A=new s(e,i);t.dispatchEvent(A)}function websocketMessageReceived(e,t,s){if(e[i]!==a.OPEN){return}let A;if(t===c.TEXT){try{A=new TextDecoder("utf-8",{fatal:true}).decode(s)Line truncated
/*! ws. MIT License. Einar Otto Stangvik <einaros@gmail.com> */o[A-4]=this.maskKey[0];o[A-3]=this.maskKey[1];o[A-2]=this.maskKey[2];o[A-1]=this.maskKey[3];o[1]=s;if(s===126){o.writeUInt16BE(t,2)}else if(s===127){o[2]=o[3]=0;o.writeUIntBE(t,4,6)}o[1]|=128;for(let e=0;e<t;e++){o[A+e]=this.frameData[e]^this.maskKey[e%4]}return o}}e.exports={WebsocketFrameSend:WebsocketFrameSend}},3171:(e,t,s)=>{"use strict";const{Writable:i}=s(2203);const A=s(1637);const{parserStates:o,opcodes:r,states:n,emptyBuffer:a}=s(5913);const{kReadyState:c,kSentClose:l,kResponse:u,kReceivedClose:p}=s(2933);const{isValidStatusCode:g,failWebsocketConnection:d,websocketMessageReceived:h}=s(3574);const{WebsocketFrameSend:E}=s(1237);const Q={};Q.ping=A.channel("undici:websocket:ping");Q.pong=A.channel("undici:websocket:pong");class ByteParser extends i{#r=[];#n=0;#a=o.INFO;#c={};#l=[];constructor(e){super();this.ws=e}_write(e,t,s){this.#r.push(e);this.#n+=e.length;this.run(s)}run(e){while(true){if(this.#a===o.INFO){if(this.#n<2){return e()}const t=this.consume(2);this.#c.fin=(t[0]&128)!==0;this.#c.opcode=t[0]&15;this.#c.originalOpcode??=this.#c.opcode;this.#c.fragmented=!this.#c.fin&&this.#c.opcode!==r.CONTINUATION;if(this.#c.fragmented&&this.#c.opcode!==r.BINARY&&this.#c.opcode!==r.TEXT){d(this.ws,"Invalid frame type was fragmented.");return}const s=t[1]&127;if(s<=125){this.#c.payloadLength=s;this.#a=o.READ_DATA}else if(s===126){this.#a=o.PAYLOADLENGTH_16}else if(s===127){this.#a=o.PAYLOADLENGTH_64}if(this.#c.fragmented&&s>125){d(this.ws,"Fragmented frame exceeded 125 bytes.");return}else if((this.#c.opcode===r.PING||this.#c.opcode===r.PONG||this.#c.opcode===r.CLOSE)&&s>125){d(this.ws,"Payload length for control frame exceeded 125 bytes.");return}else if(this.#c.opcode===r.CLOSE){if(s===1){d(this.ws,"Received close frame with a 1-byte body.");return}const e=this.consume(s);this.#c.closeInfo=this.parseCloseBody(false,e);if(!this.ws[l]){const e=Buffer.allocUnsafe(2);e.writeUInt16BE(this.#c.closeInfo.code,0);const t=new E(e);this.ws[u].socket.write(t.createFrame(r.CLOSE),(e=>{if(!e){this.ws[l]=true}}))}this.ws[c]=n.CLOSING;this.ws[p]=true;this.end();return}else if(this.#c.opcode===r.PING){const t=this.consume(s);if(!this.ws[p]){const e=new E(t);this.ws[u].socket.write(e.createFrame(r.PONG));if(Q.ping.hasSubscribers){Q.ping.publish({payload:t})}}this.#a=o.INFO;if(this.#n>0){continue}else{e();return}}else if(this.#c.opcode===r.PONG){const t=this.consume(s);if(Q.pong.hasSubscribers){Q.pong.publish({payload:t})}if(this.#n>0){continue}else{e();return}}}else if(this.#a===o.PAYLOADLENGTH_16){if(this.#n<2){return e()}const t=this.consume(2);this.#c.payloadLength=t.readUInt16BE(0);this.#a=o.READ_DATA}else if(this.#a===o.PAYLOADLENGTH_64){if(this.#n<8){return e()}const t=this.consume(8);const s=t.readUInt32BE(0);if(s>2**31-1){d(this.ws,"Received payload length > 2^31 bytes.");return}const i=t.readUInt32BE(4);this.#c.payloadLength=(s<<8)+i;this.#a=o.READ_DATA}else if(this.#a===o.READ_DATA){if(this.#n<this.#c.payloadLength){return e()}else if(this.#n>=this.#c.payloadLength){const e=this.consume(this.#c.payloadLength);this.#l.push(e);if(!this.#c.fragmented||this.#c.fin&&this.#c.opcode===r.CONTINUATION){const e=Buffer.concat(this.#l);h(this.ws,this.#c.originalOpcode,e);this.#c={};this.#l.length=0}this.#a=o.INFO}}if(this.#n>0){continue}else{e();break}}}consume(e){if(e>this.#n){return null}else if(e===0){return a}if(this.#r[0].length===e){this.#n-=this.#r[0].length;return this.#r.shift()}const t=Buffer.allocUnsafe(e);let s=0;while(s!==e){const i=this.#r[0];const{length:A}=i;if(A+s===e){t.set(this.#r.shift(),s);break}else if(A+s>e){t.set(i.subarray(0,e-s),s);this.#r[0]=i.subarray(e-s);break}else{t.set(this.#r.shift(),s);s+=i.length}}this.#n-=e;return t}parseCloseBody(e,t){let s;if(t.length>=2){s=t.readUInt16BE(0)}if(e){if(!g(s)){return null}return{code:s}}let i=t.subarray(2);if(i[0]===239&&i[1]===187&&i[2]===191){i=i.subarray(3)}if(s!==undefined&&!g(s)){return null}try{i=new TextDecoder("utf-8",{fatal:true}).decode(i)}catch{return null}return{code:s,reason:i}}get closingInfo(){return this.#c.closeInfo}}e.exports={ByteParser:ByteParser}},2933:e=>{"use strict";e.exports={kWebSocketURL:Symbol("url"),kReadyState:Symbol("ready state"),kController:Symbol("controller"),kResponse:Symbol("response"),kBinaryType:Symbol("binary type"),kSentClose:Symbol("sent close"),kReceivedClose:Symbol("received close"),kByteParser:Symbol("byte parser")}},3574:(e,t,s)=>{"use strict";const{kReadyState:i,kController:A,kResponse:o,kBinaryType:r,kWebSocketURL:n}=s(2933);const{states:a,opcodes:c}=s(5913);const{MessageEvent:l,ErrorEvent:u}=s(6255);function isEstablished(e){return e[i]===a.OPEN}function isClosing(e){return e[i]===a.CLOSING}function isClosed(e){return e[i]===a.CLOSED}function fireEvent(e,t,s=Event,i){const A=new s(e,i);t.dispatchEvent(A)}function websocketMessageReceived(e,t,s){if(e[i]!==a.OPEN){return}let A;if(t===c.TEXT){try{A=new TextDecoder("utf-8",{fatal:true}).decode(s)Line truncated
+56 -4
View File
@@ -58,6 +58,12 @@ export interface Releaser {
make_latest: 'true' | 'false' | 'legacy' | undefined;
}): Promise<{ data: Release }>;
finalizeRelease(params: {
owner: string;
repo: string;
release_id: number;
}): Promise<{ data: Release }>;
allReleases(params: { owner: string; repo: string }): AsyncIterableIterator<{ data: Release[] }>;
}
@@ -160,6 +166,15 @@ export class GitHubReleaser implements Releaser {
return this.github.rest.repos.updateRelease(params);
}
async finalizeRelease(params: { owner: string; repo: string; release_id: number }) {
return await this.github.rest.repos.updateRelease({
owner: params.owner,
repo: params.repo,
release_id: params.release_id,
draft: false,
});
}
allReleases(params: { owner: string; repo: string }): AsyncIterableIterator<{ data: Release[] }> {
const updatedParams = { per_page: 100, ...params };
return this.github.paginate.iterator(
@@ -303,7 +318,6 @@ export const release = async (
body = workflowBody || existingReleaseBody;
}
const draft = config.input_draft !== undefined ? config.input_draft : existingRelease.draft;
const prerelease =
config.input_prerelease !== undefined ? config.input_prerelease : existingRelease.prerelease;
@@ -317,7 +331,7 @@ export const release = async (
target_commitish,
name,
body,
draft,
draft: existingRelease.draft,
prerelease,
discussion_category_name,
generate_release_notes,
@@ -345,6 +359,45 @@ export const release = async (
}
};
/**
* Finalizes a release by unmarking it as "draft" (if relevant)
* after all artifacts have been uploaded.
*
* @param config - Release configuration as specified by user
* @param releaser - The GitHub API wrapper for release operations
* @param release - The existing release to be finalized
* @param maxRetries - The maximum number of attempts to finalize the release
*/
export const finalizeRelease = async (
config: Config,
releaser: Releaser,
release: Release,
maxRetries: number = 3,
): Promise<Release> => {
if (config.input_draft === true) {
return release;
}
if (maxRetries <= 0) {
console.log(`❌ Too many retries. Aborting...`);
throw new Error('Too many retries.');
}
const [owner, repo] = config.github_repository.split('/');
try {
const { data } = await releaser.finalizeRelease({
owner,
repo,
release_id: release.id,
});
return data;
} catch {
console.log(`retrying... (${maxRetries - 1} retries remaining)`);
return finalizeRelease(config, releaser, release, maxRetries - 1);
}
};
/**
* Finds a release by tag name from all a repository's releases.
*
@@ -385,7 +438,6 @@ async function createRelease(
const tag_name = tag;
const name = config.input_name || tag;
const body = releaseBody(config);
const draft = config.input_draft;
const prerelease = config.input_prerelease;
const target_commitish = config.input_target_commitish;
const make_latest = config.input_make_latest;
@@ -401,7 +453,7 @@ async function createRelease(
tag_name,
name,
body,
draft,
draft: true,
prerelease,
target_commitish,
discussion_category_name,
+7 -2
View File
@@ -1,6 +1,6 @@
import { setFailed, setOutput } from '@actions/core';
import { getOctokit } from '@actions/github';
import { GitHubReleaser, release, upload } from './github';
import { GitHubReleaser, release, finalizeRelease, upload } from './github';
import { isTag, parseConfig, paths, unmatchedPatterns, uploadUrl } from './util';
import { env } from 'process';
@@ -48,7 +48,8 @@ async function run() {
},
});
//);
const rel = await release(config, new GitHubReleaser(gh));
const releaser = new GitHubReleaser(gh);
let rel = await release(config, releaser);
if (config.input_files && config.input_files.length > 0) {
const files = paths(config.input_files, config.input_working_directory);
if (files.length == 0) {
@@ -81,6 +82,10 @@ async function run() {
const assets = results.filter(Boolean);
setOutput('assets', assets);
}
console.log('Finalizing release...');
rel = await finalizeRelease(config, releaser, rel);
console.log(`🎉 Release ready at ${rel.html_url}`);
setOutput('url', rel.html_url);
setOutput('id', rel.id.toString());